Пример #1
0
void DecodeIL(IMetaDataImport *pImport, BYTE *buffer, ULONG bufSize)
{
    // First decode the header
    COR_ILMETHOD *pHeader = (COR_ILMETHOD *) buffer;    
    COR_ILMETHOD_DECODER header(pHeader);    

    // Set globals
    position = 0;	
    pBuffer = (BYTE *) header.Code;

    UINT indentCount = 0;
    ULONG endCodePosition = header.GetCodeSize();
    while(position < endCodePosition)
    {	
        for (unsigned e=0;e<header.EHCount();e++)
        {
            IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
            const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
            
            ehInfo = header.EH->EHClause(e,&ehBuff);
            if (ehInfo->TryOffset == position)
            {
                printf ("%*s.try\n%*s{\n", indentCount, "", indentCount, "");
                indentCount+=2;
            }
            else if ((ehInfo->TryOffset + ehInfo->TryLength) == position)
            {
                indentCount-=2;
                printf("%*s} // end .try\n", indentCount, "");
            }

            if (ehInfo->HandlerOffset == position)
            {
                if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
                    printf("%*s.finally\n%*s{\n", indentCount, "", indentCount, "");
                else
                    printf("%*s.catch\n%*s{\n", indentCount, "", indentCount, "");

                indentCount+=2;
            }
            else if ((ehInfo->HandlerOffset + ehInfo->HandlerLength) == position)
            {
                indentCount-=2;
                
                if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
                    printf("%*s} // end .finally\n", indentCount, "");
                else
                    printf("%*s} // end .catch\n", indentCount, "");
            }
        }        
        
        printf("%*sIL_%04x: ", indentCount, "", position);
        unsigned int c = readOpcode();
        OpCode opcode = opcodes[c];
        printf("%s ", opcode.name);

        switch(opcode.args)
        {
        case InlineNone: break;
        
        case ShortInlineVar:
            printf("VAR OR ARG %d",readData<BYTE>()); break;
        case InlineVar:
            printf("VAR OR ARG %d",readData<unsigned short>()); break;
        case InlineI:
            printf("%d",readData<long>()); 
            break;
        case InlineR:
            printf("%f",readData<double>());
            break;
        case InlineBrTarget:
            printf("IL_%04x",readData<long>() + position); break;
        case ShortInlineBrTarget:
            printf("IL_%04x",readData<BYTE>()  + position); break;
        case InlineI8:
            printf("%ld", readData<__int64>()); break;
            
        case InlineMethod:
        case InlineField:
        case InlineType:
        case InlineTok:
        case InlineSig:        
        {
            long l = readData<long>();
            if (pImport != NULL)
            {
                DisassembleToken(pImport, l);
            }
            else
            {
                printf("TOKEN %x", l); 
            }
            break;
        }
            
        case InlineString:
        {
            long l = readData<long>();

            ULONG numChars;
            WCHAR str[84];

            if ((pImport != NULL) && (pImport->GetUserString((mdString) l, str, 80, &numChars) == S_OK))
            {
                if (numChars < 80)
                    str[numChars] = 0;
                wcscpy_s(&str[79], 4, L"...");
                WCHAR* ptr = str;
                while(*ptr != 0) {
                    if (*ptr < 0x20 || * ptr >= 0x80) {
                        *ptr = '.';
                    }
                    ptr++;
                }

                printf("\"%S\"", str);
            }
            else
            {
                printf("STRING %x", l); 
            }
            break;
        }
            
        case InlineSwitch:
        {
            long cases = readData<long>();
            long *pArray = new long[cases];            
            long i=0;
            for(i=0;i<cases;i++)
            {
                pArray[i] = readData<long>();
            }
            printf("(");
            for(i=0;i<cases;i++)
            {
                if (i != 0)
                    printf(", ");
                printf("IL_%04x",pArray[i] + position);
            }
            printf(")");
            delete [] pArray;
            break;
        }
        case ShortInlineI:
            printf("%d", readData<char>()); break;
        case ShortInlineR:		
            printf("%f", readData<float>()); break;
        default: printf("Error, unexpected opcode type\n"); break;
        }

        printf("\n");
    }
}
Пример #2
0
// Similar to the function above. TODO: factor them together before checkin.
void DecodeDynamicIL(BYTE *data, ULONG Size, DacpObjectData& tokenArray)
{
    // There is no header for this dynamic guy.
    // Set globals
    position = 0;	
    pBuffer = data;

    // At this time no exception information will be displayed (fix soon)
    UINT indentCount = 0;
    ULONG endCodePosition = Size;
    while(position < endCodePosition)
    {	        
        printf("%*sIL_%04x: ", indentCount, "", position);
        unsigned int c = readOpcode();
        OpCode opcode = opcodes[c];
        printf("%s ", opcode.name);

        switch(opcode.args)
        {
        case InlineNone: break;
        
        case ShortInlineVar:
            printf("VAR OR ARG %d",readData<BYTE>()); break;
        case InlineVar:
            printf("VAR OR ARG %d",readData<unsigned short>()); break;
        case InlineI:
            printf("%d",readData<long>()); 
            break;
        case InlineR:
            printf("%f",readData<double>());
            break;
        case InlineBrTarget:
            printf("IL_%04x",readData<long>() + position); break;
        case ShortInlineBrTarget:
            printf("IL_%04x",readData<BYTE>()  + position); break;
        case InlineI8:
            printf("%ld", readData<__int64>()); break;
            
        case InlineMethod:
        case InlineField:
        case InlineType:
        case InlineTok:
        case InlineSig:        
        case InlineString:            
        {
            long l = readData<long>();  
            DisassembleToken(tokenArray, l);            
            break;
        }
                        
        case InlineSwitch:
        {
            long cases = readData<long>();
            long *pArray = new long[cases];            
            long i=0;
            for(i=0;i<cases;i++)
            {
                pArray[i] = readData<long>();
            }
            printf("(");
            for(i=0;i<cases;i++)
            {
                if (i != 0)
                    printf(", ");
                printf("IL_%04x",pArray[i] + position);
            }
            printf(")");
            delete [] pArray;
            break;
        }
        case ShortInlineI:
            printf("%d", readData<char>()); break;
        case ShortInlineR:		
            printf("%f", readData<float>()); break;
        default: printf("Error, unexpected opcode type\n"); break;
        }

        printf("\n");
    }
}
Пример #3
0
/*static*/ SIZE_T DebuggerFunction::Disassemble(BOOL native,
                                                SIZE_T offset,
                                                BYTE *codeStart,
                                                BYTE *codeEnd,
                                                WCHAR *buffer,
                                                BOOL noAddress,
                                                DebuggerModule *module,
                                                BYTE *ilCode)
{
    SIZE_T ret;

    if (!native)
    {
        //
        // Write the address
        //
        swprintf(buffer, L"[IL:%.4x] ", offset);
        buffer += wcslen(buffer);

        //
        // Read next opcode
        //
        BYTE *ip = codeStart + offset;
        DWORD opcode;
        BYTE *prevIP = ip;
        ip = (BYTE *) ReadNextOpcode(ip, &opcode);

        //
        // Get the end of the instruction
        //
        BYTE *nextIP = (BYTE *) SkipIP(ip, opcode);

        BYTE *bytes = prevIP;

        //
        // Dump the raw value of the stream
        //
        while (bytes < ip)
        {
            swprintf(buffer, L"%.2x", *bytes++);
            buffer += wcslen(buffer);
        }
        *buffer++ = ':';
        while (bytes < nextIP)
        {
            swprintf(buffer, L"%.2x", *bytes++);
            buffer += wcslen(buffer);
        }

        while (bytes++ - prevIP < 8)
        {
            *buffer++ = L' ';
            *buffer++ = L' ';
        }

        //
        // Print the opcode
        //
        swprintf(buffer, L"%s\t", opcodeName[opcode]);
        buffer += wcslen(buffer);

        int tokenType = operandDescription[opcode];

        if (tokenType == InlineSwitch)
        {
            *buffer++ = L'\n';

            DWORD caseCount = GET_UNALIGNED_VAL32(ip);
            ip += 4;

            DWORD index = 0;
            while (index < caseCount)
            {
                swprintf(buffer, L"\t\t\t%.5d:[%.4x]\n", index,
                        GET_UNALIGNED_VAL16(ip));
                buffer += wcslen(buffer);
                index++;
                ip += 4;
            }
        }
        else if (tokenType == InlinePhi)
        {
            *buffer++ = L'\n';

            DWORD caseCount = *(unsigned char*)ip;
            ip += 1;

            DWORD index = 0;
            while (index < caseCount)
            {
                swprintf(buffer, L"\t\t\t%.5d: [%.4x]\n", index, GET_UNALIGNED_VAL16(ip));
                buffer += wcslen(buffer);
                index++;
                ip += 2;
            }
        }
        else if (tokenType == InlineTok || tokenType == InlineType || 
			     tokenType == InlineField ||  tokenType == InlineMethod)
        {
            DisassembleToken(module->GetMetaData(), GET_UNALIGNED_VAL32(ip), buffer);
            buffer += wcslen(buffer);
        }
        else
        {
            DisassembleArgument(ip, ip - ilCode, tokenType, buffer);
            buffer += wcslen(buffer);
        }

        ret = nextIP - ilCode;
    }
    else
    {
        // Write the address
        if (!noAddress)
        {
            swprintf(buffer, L"[%.4x] ", offset);
            buffer += wcslen(buffer);
        }

        ret = 0xffff;
    }

    *buffer++ = L'\n';
    *buffer = L'\0';

    return (ret);
}