Logo Search packages:      
Sourcecode: radare2 version File versions  Download package

demsil.c

//   
//    Copyright (c) 2008 Daniel Pistelli.
// 
/*
DisasMSIL
http://www.ntcore.com/utilities.php
Date: 30/04/2008  Author: Daniel Pistelli
DisasMSIL is a free/open disasm engine for the Microsoft Intermediate Language (MSIL). You can use it any context you wish. There are no license restrictions. The only thing I ask you to do is to send me your bug fixes (if any). For more information about this project, read the article.
*/

#include <stdio.h>
#include "demsil.h"
/* typedef */
#ifndef ut64
#define ut64 unsigned long long
#endif
#ifndef ut32
#define ut32 unsigned int
#endif

static ut32 hi_dword(ut64 Q)
{
      ut64 qwBuf = Q >> 32;
      return (ut32) qwBuf;
}

static ut32 lo_dword(ut64 Q)
{
      return (ut32) Q;
}

int GetSingleMSILInstr(const u8 *pMemory, ut32 MemorySize, DISASMSIL_OFFSET CodeBase, ILOPCODE_STRUCT *ilop)
{
      u8 *pCurInstr = (u8 *) pMemory;
      DISASMSIL_OFFSET Base = CodeBase;
      ut32 CurInstr;
      ut32 Token;
      u8 bBuf = 0;
      ut16 wBuf = 0;
      ut32 dwBuf = 0;
      ut64 qwBuf = 0;
      ut32 Prefix;

/* This macro makes a validity check on the requested space */
#define VALIDATE(p, size) \
      if ((MemorySize - (ut32 ) (((unsigned long*) p) - ((unsigned long*) pMemory))) < size) \
            return 0;

      // This little macro makes a validity check
      // on a request from the disassembler
      // when the request can't be satisfied, 
      // the function returns 0
#define demsil_get(p, var, type) { \
      ut32 typesize = sizeof (type);      \
      ut32 remsize = MemorySize - (ut32) (((unsigned long*) p) - ((unsigned long*) pMemory)); \
      if (typesize > remsize) return 0; \
      var = *((type *) p);    \
}

      //
      // This macro adds an instruction to the
      // current mnemonic string
      //
      
#define demsil_addi(i)  \
      if (ilop->Mnemonic[0] == 0)\
            snprintf(ilop->Mnemonic, MAX_DISASMMSIL_MNEMONIC, "%s", i);\
      else snprintf(ilop->Mnemonic, MAX_DISASMMSIL_MNEMONIC, "%s %s", ilop->Mnemonic, i);

      //
      // This macro adds a number to the
      // current mnemonic string
      //
#if 0
      /* XXX original code -stripped to skip warnings */
      case NUMBER_TYPE_BRANCH:                                                        \
            if (((ut32) n) <= 0x7FFFFFFF)                                    \
                  snprintf(szNumber, 100, "0x%08X", (ut32) (Base + 5) + n);\
            else snprintf(szNumber, 100, "0x%08X", (ut32) (Base + 5) - (0 - (int) n));
#endif

#define demsil_add_number(n, nt) {\
            char szNumber[100];\
            switch (nt) {     \
            case NUMBER_TYPE_TOKEN: snprintf(szNumber, 100, "0x%08X", (ut32) n); break;   \
            case NUMBER_TYPE_SMALL_BRANCH:                                                \
                  if (((u8) n) <= 127)                                              \
                        snprintf(szNumber, 100, "0x%08X", (ut32) ((Base + 2) + n)); \
                  else                                                        \
                        snprintf(szNumber, 100, "0x%08X", (ut32) ((Base + 2) - (0 - (char) n)));      \
                  break;                                                      \
            case NUMBER_TYPE_BRANCH:                                          \
                  snprintf(szNumber, 100, "0x%08X", (ut32)( (Base + 5) + n));\
                  break;\
            case NUMBER_TYPE_U8: snprintf(szNumber, 100, "0x%02X", (u8) n); break;  \
            case NUMBER_TYPE_WORD: snprintf(szNumber, 100, "0x%04X", (ut16) n); break;\
            case NUMBER_TYPE_DWORD: snprintf(szNumber, 100, "0x%08X", (ut32) n); break;\
            case NUMBER_TYPE_QWORD: snprintf(szNumber, 100, "0x%08X%08X",           \
                  hi_dword(n), lo_dword(n)); break;                                 \
            case NUMBER_TYPE_CHAR:  snprintf(szNumber, 100, "%d", (int) (u8) n); break;         \
            case NUMBER_TYPE_SHORT: snprintf(szNumber, 100, "%hd", (short) n); break;           \
            case NUMBER_TYPE_INT: snprintf(szNumber, 100, "%d", (int) n); break;                \
            case NUMBER_TYPE_INT64: snprintf(szNumber, 100, "%lld", (ut64) n); break;\
            case NUMBER_TYPE_UCHAR: snprintf(szNumber, 100, "%hu", (unsigned short) n); break;  \
            case NUMBER_TYPE_USHORT:      snprintf(szNumber, 100, "%hu", (short) n); break;     \
            case NUMBER_TYPE_UINT: snprintf(szNumber, 100, "%u", (int) n); break;         \
            case NUMBER_TYPE_FLOAT: snprintf(szNumber, 100, "%f", (float) n); break;            \
            case NUMBER_TYPE_DOUBLE: snprintf(szNumber, 100, "%g", (double) n); break;          \
            }                                                                 \
            if (ilop->Mnemonic[0] == 0)                                             \
                  snprintf(ilop->Mnemonic, MAX_DISASMMSIL_MNEMONIC, "%s", szNumber);            \
            else snprintf(ilop->Mnemonic, MAX_DISASMMSIL_MNEMONIC, "%s %s", ilop->Mnemonic, szNumber); \
      }

      //
      // This macro adds an instruction and a token to the
      // current mnemonic string
      //

#define demsil_addiT(i, t)\
      if (ilop->Mnemonic[0] == 0)\
            snprintf(ilop->Mnemonic, MAX_DISASMMSIL_MNEMONIC, "%s 0x%08X", i, t);   \
      else snprintf(ilop->Mnemonic, MAX_DISASMMSIL_MNEMONIC, "%s %s 0x%08X", ilop->Mnemonic, i, t);

      if (MemorySize == 0) return 0;

      ilop->Offset = Base;
      ilop->Mnemonic[0] = 0;

      //
      // Check if it's a one-byte instr
      // (in that case don't check for prefix)
      //
      demsil_get(pCurInstr, CurInstr, u8);

      if (CurInstr >= 0x00 && CurInstr <= 0xE0)
            goto getinstr;

      //
      // check for prefixes
      //
      demsil_get(pCurInstr, Prefix, ut16);

      switch (Prefix) {
      case ILOPCODE_CONSTRAINED_:
            demsil_get(pCurInstr + 2, Token, ut32);
            pCurInstr += 6;
            demsil_addiT("costrained", Token);
            break;
      case ILOPCODE_UNALIGNED_:
            demsil_get(pCurInstr + 2, bBuf, u8);
            pCurInstr += 3;
            demsil_addi("unaligned");
            demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
            break;
      case ILOPCODE_NO_:
            demsil_get(pCurInstr + 2, bBuf, u8);
            pCurInstr += 3;
            demsil_addi("unaligned");
            demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
            break;
      case ILOPCODE_TAIL_:
            pCurInstr += 2;
            demsil_addi("tail.");
            break;
      case ILOPCODE_VOLATILE_:
            pCurInstr += 2;
            demsil_addi("volatile.");
            break;
      case ILOPCODE_READONLY_:
            pCurInstr += 2;
            demsil_addi("readonly.");
            break;
      }


      //
      // get instruction
      //
getinstr:

      //
      // Check if it's a one-byte instr
      //

      if (CurInstr >= 0x00 && CurInstr <= 0xE0) {
            pCurInstr += 1;

            switch (CurInstr) {
            case ILOPCODE_NOP:
                  demsil_addi("nop");
                  break;
            case ILOPCODE_BREAK:
                  demsil_addi("break");
                  break;
            case ILOPCODE_LDARG_0:
                  demsil_addi("ldarg.0");
                  break;
            case ILOPCODE_LDARG_1:
                  demsil_addi("ldarg.1");
                  break;
            case ILOPCODE_LDARG_2:
                  demsil_addi("ldarg.2");
                  break;
            case ILOPCODE_LDARG_3:
                  demsil_addi("ldarg.3");
                  break;
            case ILOPCODE_LDLOC_0:
                  demsil_addi("ldloc.0");
                  break;
            case ILOPCODE_LDLOC_1:
                  demsil_addi("ldloc.1");
                  break;
            case ILOPCODE_LDLOC_2:
                  demsil_addi("ldloc.2");
                  break;
            case ILOPCODE_LDLOC_3:
                  demsil_addi("ldloc.3");
                  break;
            case ILOPCODE_STLOC_0:
                  demsil_addi("stloc.0");
                  break;
            case ILOPCODE_STLOC_1:
                  demsil_addi("stloc.1");
                  break;
            case ILOPCODE_STLOC_2:
                  demsil_addi("stloc.2");
                  break;
            case ILOPCODE_STLOC_3:
                  demsil_addi("stloc.3");
                  break;
            case ILOPCODE_LDARG_S:
                  demsil_addi("ldarg.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
                  break;
            case ILOPCODE_LDARGA_S:
                  demsil_addi("ldarga.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
                  break;
            case ILOPCODE_STARG_S:
                  demsil_addi("starg.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
                  break;
            case ILOPCODE_LDLOC_S:
                  demsil_addi("ldloc.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
                  break;
            case ILOPCODE_LDLOCA_S:
                  demsil_addi("ldloca.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
                  break;
            case ILOPCODE_STLOC_S:
                  demsil_addi("stloc.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_UCHAR);
                  break;
            case ILOPCODE_LDNULL:
                  demsil_addi("ldnull");
                  break;
            case ILOPCODE_LDC_I4_M1:
                  demsil_addi("ldc.i4.m1");
                  break;
            case ILOPCODE_LDC_I4_0:
                  demsil_addi("ldc.i4.0");
                  break;
            case ILOPCODE_LDC_I4_1:
                  demsil_addi("ldc.i4.1");
                  break;
            case ILOPCODE_LDC_I4_2:
                  demsil_addi("ldc.i4.2");
                  break;
            case ILOPCODE_LDC_I4_3:
                  demsil_addi("ldc.i4.3");
                  break;
            case ILOPCODE_LDC_I4_4:
                  demsil_addi("ldc.i4.4");
                  break;
            case ILOPCODE_LDC_I4_5:
                  demsil_addi("ldc.i4.5");
                  break;
            case ILOPCODE_LDC_I4_6:
                  demsil_addi("ldc.i4.6");
                  break;
            case ILOPCODE_LDC_I4_7:
                  demsil_addi("ldc.i4.7");
                  break;
            case ILOPCODE_LDC_I4_8:
                  demsil_addi("ldc.i4.8");
                  break;
            case ILOPCODE_LDC_I4_S:
                  demsil_addi("ldc.i4.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr++;
                  demsil_add_number(bBuf, NUMBER_TYPE_CHAR);
                  break;
            case ILOPCODE_LDC_I4:
                  {
                        demsil_addi("ldc.i4");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_INT);
                        break;
                  }

            case ILOPCODE_LDC_I8:
                  demsil_addi("ldc.i8");
                  demsil_get(pCurInstr, qwBuf, ut64);
                  pCurInstr += 8;
                  demsil_add_number(qwBuf, NUMBER_TYPE_INT64);
                  break;
            case ILOPCODE_LDC_R4:
                  demsil_addi("ldc.r4");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_FLOAT);
                  break;
            case ILOPCODE_LDC_R8:
                  demsil_addi("ldc.r8");
                  demsil_get(pCurInstr, qwBuf, ut64);
                  pCurInstr += 8;
                  demsil_add_number(qwBuf, NUMBER_TYPE_DOUBLE);
                  break;
            case ILOPCODE_DUP:
                  demsil_addi("dup");
                  break;
            case ILOPCODE_POP:
                  demsil_addi("pop");
                  break;
            case ILOPCODE_JMP:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("jmp", dwBuf);
                  break;
            case ILOPCODE_CALL:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("call", dwBuf);
                  break;
            case ILOPCODE_CALLI:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("calli", dwBuf);
                  break;
            case ILOPCODE_RET:
                  demsil_addi("ret");
                  break;
            case ILOPCODE_BR_S:
                  demsil_addi("br.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
#if 0
            case ILOPCODE_BR0_S:
                  demsil_addi("brfalse.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BR1_S:
                  demsil_addi("brtrue.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
#endif
            case ILOPCODE_BEQ_S:
                  demsil_addi("beq.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BGE_S:
                  demsil_addi("bge.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BGT_S:
                  demsil_addi("bgt.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BLE_S:
                  demsil_addi("ble.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BLT_S:
                  demsil_addi("blt.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BNE_UN_S:
                  demsil_addi("bne.un.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BGE_UN_S:
                  demsil_addi("bge.un.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BGT_UN_S:
                  demsil_addi("bgt.un.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BLE_UN_S:
                  demsil_addi("ble.un.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BLT_UN_S:
                  demsil_addi("blt.un.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_BR:
                  demsil_addi("br");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
#if 0
            case ILOPCODE_BR0:
                  demsil_addi("brfalse");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
            case ILOPCODE_BR1:
                  demsil_addi("brtrue");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
#endif
            case ILOPCODE_BEQ:
                  demsil_addi("beq");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
            case ILOPCODE_BGE:
                  demsil_addi("bge");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
            case ILOPCODE_BGT:
                  demsil_addi("bgt");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
            case ILOPCODE_BLE:
                  demsil_addi("ble");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
            case ILOPCODE_BLT:
                  {
                        demsil_addi("blt");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                        break;
                  }
            case ILOPCODE_BNE_UN:
                  {
                        demsil_addi("bne.un");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                        break;
                  }
            case ILOPCODE_BGE_UN:
                  {
                        demsil_addi("bge.un");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                        break;
                  }
            case ILOPCODE_BGT_UN:
                  {
                        demsil_addi("bgt.un");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                        break;
                  }
            case ILOPCODE_BLE_UN:
                  {
                        demsil_addi("ble.un");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                        break;
                  }
            case ILOPCODE_BLT_UN:
                  {
                        demsil_addi("blt.un");
                        demsil_get(pCurInstr, dwBuf, ut32);
                        pCurInstr += 4;
                        demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                        break;
                  }
            case ILOPCODE_SWITCH:
                  {
                        //
                        // The switch is followed by a dword and an array
                        // of dwords, the first dword tells how many dwords will follow
                        // every dword in the array represents an int32 offset
                        //

                        demsil_get(pCurInstr, dwBuf, ut32);
                        VALIDATE(pCurInstr, (dwBuf + 1) * sizeof (ut32));
                        demsil_addi("switch");
                        pCurInstr += ((dwBuf + 1) * sizeof (ut32));
                        break;
                  }
            case ILOPCODE_LDIND_I1:
                  demsil_addi("ldind.i1");
                  break;
            case ILOPCODE_LDIND_U1:
                  demsil_addi("ldind.u1");
                  break;
            case ILOPCODE_LDIND_I2:
                  demsil_addi("ldind.i2");
                  break;
            case ILOPCODE_LDIND_U2:
                  demsil_addi("ldind.u2");
                  break;
            case ILOPCODE_LDIND_I4:
                  demsil_addi("ldind.i4");
                  break;
            case ILOPCODE_LDIND_U4:
                  demsil_addi("ldind.u4");
                  break;
            case ILOPCODE_LDIND_I8:
                  demsil_addi("ldind.i8");
                  break;
            case ILOPCODE_LDIND_I:
                  demsil_addi("ldind.i");
                  break;
            case ILOPCODE_LDIND_R4:
                  demsil_addi("ldind.r4");
                  break;
            case ILOPCODE_LDIND_R8:
                  demsil_addi("ldind.r8");
                  break;
            case ILOPCODE_LDIND_REF:
                  demsil_addi("ldind.ref");
                  break;
            case ILOPCODE_STIND_REF:
                  demsil_addi("stind.ref");
                  break;
            case ILOPCODE_STIND_I1:
                  demsil_addi("stind.i1");
                  break;
            case ILOPCODE_STIND_I2:
                  demsil_addi("stind.i2");
                  break;
            case ILOPCODE_STIND_I4:
                  demsil_addi("stind.i4");
                  break;
            case ILOPCODE_STIND_I8:
                  demsil_addi("stind.i8");
                  break;
            case ILOPCODE_STIND_R4:
                  demsil_addi("stind.r4");
                  break;
            case ILOPCODE_STIND_R8:
                  demsil_addi("stind.r8");
                  break;
            case ILOPCODE_ADD:
                  demsil_addi("add");
                  break;
            case ILOPCODE_SUB:
                  demsil_addi("sub");
                  break;
            case ILOPCODE_MUL:
                  demsil_addi("mul");
                  break;
            case ILOPCODE_DIV:
                  demsil_addi("div");
                  break;
            case ILOPCODE_DIV_UN:
                  demsil_addi("div.un");
                  break;
            case ILOPCODE_REM:
                  demsil_addi("rem");
                  break;
            case ILOPCODE_REM_UN:
                  demsil_addi("rem.un");
                  break;
            case ILOPCODE_AND:
                  demsil_addi("and");
                  break;
            case ILOPCODE_OR:
                  demsil_addi("or");
                  break;
            case ILOPCODE_XOR:
                  demsil_addi("xor");
                  break;
            case ILOPCODE_SHL:
                  demsil_addi("shl");
                  break;
            case ILOPCODE_SHR:
                  demsil_addi("shr");
                  break;
            case ILOPCODE_SHR_UN:
                  demsil_addi("shr.un");
                  break;
            case ILOPCODE_NEG:
                  demsil_addi("neg");
                  break;
            case ILOPCODE_NOT:
                  demsil_addi("not");
                  break;
            case ILOPCODE_CONV_I1:
                  demsil_addi("conv.i1");
                  break;
            case ILOPCODE_CONV_I2:
                  demsil_addi("conv.i2");
                  break;
            case ILOPCODE_CONV_I4:
                  demsil_addi("conv.i4");
                  break;
            case ILOPCODE_CONV_I8:
                  demsil_addi("conv.i8");
                  break;
            case ILOPCODE_CONV_R4:
                  demsil_addi("conv.r4");
                  break;
            case ILOPCODE_CONV_R8:
                  demsil_addi("conv.r8");
                  break;
            case ILOPCODE_CONV_U4:
                  demsil_addi("conv.u4");
                  break;
            case ILOPCODE_CONV_U8:
                  demsil_addi("conv.u8");
                  break;
            case ILOPCODE_CALLVIRT:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("callvirt", dwBuf);
                  break;
            case ILOPCODE_CPOBJ:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("cpobj", dwBuf);
                  break;
            case ILOPCODE_LDOBJ:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldobj", dwBuf);
                  break;
            case ILOPCODE_LDSTR:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldstr", dwBuf);
                  break;
            case ILOPCODE_NEWOBJ:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("newobj", dwBuf);
                  break;
            case ILOPCODE_CASTCLASS:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("castclass", dwBuf);
                  break;
            case ILOPCODE_ISINST:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("isinst", dwBuf);
                  break;
            case ILOPCODE_CONV_R_UN:
                  demsil_addi("conv.r.un");
                  break;
            case ILOPCODE_UNBOX:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("unbox", dwBuf);
                  break;
            case ILOPCODE_THROW:
                  demsil_addi("throw");
                  break;
            case ILOPCODE_LDFLD:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldfld", dwBuf);
                  break;
            case ILOPCODE_LDFLDA:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldflda", dwBuf);
                  break;
            case ILOPCODE_STFLD:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("stfld", dwBuf);
                  break;
            case ILOPCODE_LDSFLD:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldsfld", dwBuf);
                  break;
            case ILOPCODE_LDSFLDA:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldsflda", dwBuf);
                  break;
            case ILOPCODE_STSFLD:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("stsfld", dwBuf);
                  break;
            case ILOPCODE_STOBJ:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("stobj", dwBuf);
                  break;
            case ILOPCODE_CONV_OVF_I1_UN:
                  demsil_addi("conv.ovf.i1.un");
                  break;
            case ILOPCODE_CONV_OVF_I2_UN:
                  demsil_addi("conv.ovf.i2.un");
                  break;
            case ILOPCODE_CONV_OVF_I4_UN:
                  demsil_addi("conv.ovf.i4.un");
                  break;
            case ILOPCODE_CONV_OVF_I8_UN:
                  demsil_addi("conv.ovf.i8.un");
                  break;
            case ILOPCODE_CONV_OVF_U1_UN:
                  demsil_addi("conv.ovf.u1.un");
                  break;
            case ILOPCODE_CONV_OVF_U2_UN:
                  demsil_addi("conv.ovf.u2.un");
                  break;
            case ILOPCODE_CONV_OVF_U4_UN:
                  demsil_addi("conv.ovf.u4.un");
                  break;
            case ILOPCODE_CONV_OVF_U8_UN:
                  demsil_addi("conv.ovf.u8.un");
                  break;
            case ILOPCODE_CONV_OVF_I_UN:
                  demsil_addi("conv.ovf.i.un");
                  break;
            case ILOPCODE_CONV_OVF_U_UN:
                  demsil_addi("conv.ovf.u.un");
                  break;
            case ILOPCODE_BOX:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("box", dwBuf);
                  break;
            case ILOPCODE_NEWARR:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("newarr", dwBuf);
                  break;
            case ILOPCODE_LDLEN:
                  demsil_addi("ldlen");
                  break;
            case ILOPCODE_LDELEMA:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldelema", dwBuf);
                  break;
            case ILOPCODE_LDELEM_I1:
                  demsil_addi("ldelem.i1");
                  break;
            case ILOPCODE_LDELEM_U1:
                  demsil_addi("ldelem.u1");
                  break;
            case ILOPCODE_LDELEM_I2:
                  demsil_addi("ldelem.i2");
                  break;
            case ILOPCODE_LDELEM_U2:
                  demsil_addi("ldelem.u2");
                  break;
            case ILOPCODE_LDELEM_I4:
                  demsil_addi("ldelem.i4");
                  break;
            case ILOPCODE_LDELEM_U4:
                  demsil_addi("ldelem.u4");
                  break;
            case ILOPCODE_LDELEM_I8:
                  demsil_addi("ldelem.i1");
                  break;
            case ILOPCODE_LDELEM_I:
                  demsil_addi("ldelem.i");
                  break;
            case ILOPCODE_LDELEM_R4:
                  demsil_addi("ldelem.r4");
                  break;
            case ILOPCODE_LDELEM_R8:
                  demsil_addi("ldelem.r8");
                  break;
            case ILOPCODE_LDELEM_REF:
                  demsil_addi("ldelem.ref");
                  break;
            case ILOPCODE_STELEM_I:
                  demsil_addi("stelem.i");
                  break;
            case ILOPCODE_STELEM_I1:
                  demsil_addi("stelem.i1");
                  break;
            case ILOPCODE_STELEM_I2:
                  demsil_addi("stelem.i2");
                  break;
            case ILOPCODE_STELEM_I4:
                  demsil_addi("stelem.i4");
                  break;
            case ILOPCODE_STELEM_I8:
                  demsil_addi("stelem.i8");
                  break;
            case ILOPCODE_STELEM_R4:
                  demsil_addi("stelem.r4");
                  break;
            case ILOPCODE_STELEM_R8:
                  demsil_addi("stelem.r8");
                  break;
            case ILOPCODE_STELEM_REF:
                  demsil_addi("stelem.ref");
                  break;
            case ILOPCODE_LDELEM:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldelem", dwBuf);
                  break;
            case ILOPCODE_STELEM:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("stelem", dwBuf);
                  break;
            case ILOPCODE_UNBOX_ANY:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("unbox.any", dwBuf);
                  break;
            case ILOPCODE_CONV_OVF_I1:
                  demsil_addi("conv.ovf.i1");
                  break;
            case ILOPCODE_CONV_OVF_U1:
                  demsil_addi("conv.ovf.u1");
                  break;
            case ILOPCODE_CONV_OVF_I2:
                  demsil_addi("conv.ovf.i2");
                  break;
            case ILOPCODE_CONV_OVF_U2:
                  demsil_addi("conv.ovf.u2");
                  break;
            case ILOPCODE_CONV_OVF_I4:
                  demsil_addi("conv.ovf.i4");
                  break;
            case ILOPCODE_CONV_OVF_U4:
                  demsil_addi("conv.ovf.u4");
                  break;
            case ILOPCODE_CONV_OVF_I8:
                  demsil_addi("conv.ovf.i8");
                  break;
            case ILOPCODE_CONV_OVF_U8:
                  demsil_addi("conv.ovf.u8");
                  break;
            case ILOPCODE_REFANYVAL:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("refanyval", dwBuf);
                  break;
            case ILOPCODE_CKFINITE:
                  demsil_addi("ckfinite");
                  break;
            case ILOPCODE_MKREFANY:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("mkrefany", dwBuf);
                  break;
            case ILOPCODE_LDTOKEN:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldtoken", dwBuf);
                  break;
            case ILOPCODE_CONV_U2:
                  demsil_addi("conv.u2");
                  break;
            case ILOPCODE_CONV_U1:
                  demsil_addi("conv.u1");
                  break;
            case ILOPCODE_CONV_I:
                  demsil_addi("conv.i");
                  break;
            case ILOPCODE_CONV_OVF_I:
                  demsil_addi("conv.ovf.i");
                  break;
            case ILOPCODE_CONV_OVF_U:
                  demsil_addi("conv.ovf.u");
                  break;
            case ILOPCODE_ADD_OVF:
                  demsil_addi("add.ovf");
                  break;
            case ILOPCODE_ADD_OVF_UN:
                  demsil_addi("add.ovf.un");
                  break;
            case ILOPCODE_MUL_OVF:
                  demsil_addi("mul.ovf");
                  break;
            case ILOPCODE_MUL_OVF_UN:
                  demsil_addi("mul.ovf.un");
                  break;
            case ILOPCODE_SUB_OVF:
                  demsil_addi("sub.ovf");
                  break;
            case ILOPCODE_SUB_OVF_UN:
                  demsil_addi("sub.ovf.un");
                  break;
            case ILOPCODE_ENDFINALLY:
                  demsil_addi("endfinally");
                  break;
            case ILOPCODE_LEAVE:
                  demsil_addi("leave");
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_add_number(dwBuf, NUMBER_TYPE_BRANCH);
                  break;
            case ILOPCODE_LEAVE_S:
                  demsil_addi("leave.s");
                  demsil_get(pCurInstr, bBuf, u8);
                  pCurInstr += 1;
                  demsil_add_number(bBuf, NUMBER_TYPE_SMALL_BRANCH);
                  break;
            case ILOPCODE_STIND_I:
                  demsil_addi("stind.i");
                  break;
            case ILOPCODE_CONV_U:
                  demsil_addi("conv.u");
                  break;
            default:
                  return 0;
            } // end switch
      } else {
      //
      // Two bytes instruction
      //
            demsil_get(pCurInstr, CurInstr, ut16);

            pCurInstr += 2;

            switch (CurInstr) {
            case ILOPCODE_ARGLIST:
                  demsil_addi("arglist");
                  break;
            case ILOPCODE_CEQ:
                  demsil_addi("ceq");
                  break;
            case ILOPCODE_CGT:
                  demsil_addi("cgt");
                  break;
            case ILOPCODE_CGT_UN:
                  demsil_addi("cgt.un");
                  break;
            case ILOPCODE_CLT:
                  demsil_addi("clt");
                  break;
            case ILOPCODE_CLT_UN:
                  demsil_addi("clt.un");
                  break;
            case ILOPCODE_LDFTN:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldftn", dwBuf);
                  break;
            case ILOPCODE_LDVIRTFTN:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("ldvirtftn", dwBuf);
                  break;
            case ILOPCODE_LDARG:
                  demsil_addi("ldarg");
                  demsil_get(pCurInstr, wBuf, ut16);
                  pCurInstr += 2;
                  demsil_add_number(wBuf, NUMBER_TYPE_USHORT);
                  break;
            case ILOPCODE_LDARGA:
                  demsil_addi("ldarga");
                  demsil_get(pCurInstr, wBuf, ut16);
                  pCurInstr += 2;
                  demsil_add_number(wBuf, NUMBER_TYPE_USHORT);
                  break;
            case ILOPCODE_STARG:
                  demsil_addi("starg");
                  demsil_get(pCurInstr, wBuf, ut16);
                  pCurInstr += 2;
                  demsil_add_number(wBuf, NUMBER_TYPE_USHORT);
                  break;
            case ILOPCODE_LDLOC:
                  demsil_addi("ldloc");
                  demsil_get(pCurInstr, wBuf, ut16);
                  pCurInstr += 2;
                  demsil_add_number(wBuf, NUMBER_TYPE_USHORT);
                  break;
            case ILOPCODE_LDLOCA:
                  demsil_addi("ldloca");
                  demsil_get(pCurInstr, wBuf, ut16);
                  pCurInstr += 2;
                  demsil_add_number(wBuf, NUMBER_TYPE_USHORT);
                  break;
            case ILOPCODE_STLOC:
                  demsil_addi("stloc");
                  demsil_get(pCurInstr, wBuf, ut16);
                  pCurInstr += 2;
                  demsil_add_number(wBuf, NUMBER_TYPE_USHORT);
                  break;
            case ILOPCODE_LOCALLOC:
                  demsil_addi("localloc");
                  break;
            case ILOPCODE_ENDFILTER:
                  demsil_addi("endfilter");
                  break;
            case ILOPCODE_INITOBJ:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("initobj", dwBuf);
                  break;
            case ILOPCODE_CPBLK:
                  demsil_addi("cpblk");
                  break;
            case ILOPCODE_INITBLK:
                  demsil_addi("initblk");
                  break;
            case ILOPCODE_RETHROW:
                  demsil_addi("rethrow");
                  break;
            case ILOPCODE_SIZEOF:
                  demsil_get(pCurInstr, dwBuf, ut32);
                  pCurInstr += 4;
                  demsil_addiT("sizeof", dwBuf);
                  break;
            case ILOPCODE_REFANYTYPE_V2:
                  demsil_addi("refanytype.v2");
                  break;
            default:
                  return 0;
            }
      }

      ilop->Size = (ut32) (((unsigned long*) pCurInstr) - ((unsigned long*) pMemory));
      
      return 1;
}

int DisasMSIL(const u8 *pMemory, ut32 MemorySize, DISASMSIL_OFFSET CodeBase, ILOPCODE_STRUCT *iloparray, ut32 nOpcodeStructs, ut32 *nDisassembledInstr)
{
      const u8 *pCurMem = pMemory;
      ut32 x, RemSize = MemorySize;
      DISASMSIL_OFFSET CurBase = CodeBase;

      if (MemorySize == 0 || nOpcodeStructs == 0 || iloparray == NULL) 
            return 0;
      if (nDisassembledInstr) *nDisassembledInstr = 0;

      for (x = 0; x < nOpcodeStructs; x++) {
            if (!GetSingleMSILInstr(pCurMem, RemSize, CurBase, &iloparray[x])) {
                  if (x == 0) return 0;
                  break;
            }

            pCurMem += iloparray[x].Size;
            CurBase += iloparray[x].Size;
            RemSize -= iloparray[x].Size;

            if (nDisassembledInstr)
                  *nDisassembledInstr = x + 1;
      }

      return 1;
}


Generated by  Doxygen 1.6.0   Back to index