Nytro Posted November 15, 2011 Report Posted November 15, 2011 [C++] Simple Code Virtualization (Virtual Machine / Emulator) Original code by: abhe Ported by: steve10120 at ic0de.org Thanks to Edi for help with inst_tableOriginal: ic0de.org/* Original code by: abhe Ported by: steve10120@ic0de.org Thanks to Edi for help with inst_table*/#include <Windows.h>#include <iostream>int const REGISTER_EAX = 0; int const REGISTER_ECX = 1; int const REGISTER_EDX = 2; int const REGISTER_EBX = 3; int const REGISTER_ESP = 4; int const REGISTER_EBP = 5; int const REGISTER_ESI = 6; int const REGISTER_EDI = 7; int const REGISTER_NOP = 8; typedef struct _VMCONTEXT{ DWORD EIP; DWORD Reg[8];} VMCONTEXT, *PVMCONTEXT;typedef void (VM_FUNCTION_CALL)(PVMCONTEXT c);typedef struct _INST{ VM_FUNCTION_CALL* FunctionCall;} INST, *PINST;void AddCode(PVMCONTEXT c, BYTE n){ c->EIP += n;}void VRetn(PVMCONTEXT c){}void VJmp(PVMCONTEXT c){ DWORD imm32; c->EIP++; imm32 = *(PDWORD)c->EIP; c->EIP = imm32;}void VPUSHImm(PVMCONTEXT c){ DWORD imm32; c->EIP++; imm32 = *(PDWORD)c->EIP; AddCode(c, 4); *(PDWORD)c->Reg[REGISTER_ESP] = imm32; c->Reg[REGISTER_ESP] += 4;}void VPUSHReg(PVMCONTEXT c){ BYTE regflag; DWORD imm32; c->EIP++; regflag = *(PBYTE)c->EIP; AddCode(c, 1); if ( regflag < 8 ) { imm32 = c->Reg[regflag]; *(PDWORD)c->Reg[REGISTER_ESP] = imm32; c->Reg[REGISTER_ESP] += 4; }}void VPUSHMem(PVMCONTEXT c){ DWORD mem32; DWORD imm32; c->EIP++; mem32 = *(PDWORD)c->EIP; imm32 = *(PDWORD)mem32; AddCode(c, 4); *(PDWORD)c->Reg[REGISTER_ESP] = imm32; c->Reg[REGISTER_ESP] += 4;}void VPOPReg(PVMCONTEXT c){ BYTE regflag; DWORD imm32; c->EIP++; regflag = *(PBYTE)c->EIP; AddCode(c, 1); if ( regflag < 8 ) { imm32 = *(PDWORD)c->Reg[REGISTER_ESP]; c->Reg[REGISTER_ESP] -= 4; c->Reg[regflag] = imm32; }}void VPOPMem(PVMCONTEXT c){ DWORD imm32; DWORD mem32; imm32 = *(PDWORD)c->Reg[REGISTER_ESP]; c->Reg[REGISTER_ESP] -= 4; mem32 = *(PDWORD)c->EIP; AddCode(c, 4); *(PDWORD)mem32 = imm32;}void VMovRegReg(PVMCONTEXT c){ BYTE DestReg, SrcReg; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( ( DestReg < 8 ) && ( SrcReg < 8 ) ) c->Reg[DestReg] = c->Reg[SrcReg];}void VMovRegImm(PVMCONTEXT c){ BYTE DestReg; DWORD imm32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); imm32 = *(PDWORD)c->EIP; AddCode(c, 4); if ( DestReg < 8 ) c->Reg[DestReg] = imm32;}void VMovRegMem(PVMCONTEXT c){ BYTE DestReg; DWORD mem32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); mem32 = *(PDWORD)c->EIP; AddCode(c, 4); if ( DestReg < 8 ) c->Reg[DestReg] = *(PDWORD)mem32;}void VADDRegReg(PVMCONTEXT c){ BYTE DestReg, SrcReg; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( ( DestReg < 8 ) && ( SrcReg < 8 ) ) c->Reg[DestReg] += c->Reg[SrcReg];}void VADDRegImm(PVMCONTEXT c){ BYTE DestReg; DWORD imm32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); imm32 = *(PDWORD)c->EIP; AddCode(c, 4); if ( DestReg < 8 ) c->Reg[DestReg] += imm32;}void VADDRegMem(PVMCONTEXT c){ BYTE DestReg; DWORD mem32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); mem32 = *(PDWORD)c->EIP; AddCode(c, 4); if ( DestReg < 8 ) c->Reg[DestReg] += *(PDWORD)mem32;}void VSUBRegReg(PVMCONTEXT c){ BYTE DestReg, SrcReg; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( ( DestReg < 8 ) && ( SrcReg < 8 ) ) c->Reg[DestReg] -= c->Reg[SrcReg];}void VSUBRegImm(PVMCONTEXT c){ BYTE DestReg; DWORD imm32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); imm32 = *(PDWORD)c->EIP; AddCode(c, 4); if ( DestReg < 8 ) c->Reg[DestReg] -= imm32;}void VSUBRegMem(PVMCONTEXT c){ BYTE DestReg; DWORD mem32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); mem32 = *(PDWORD)c->EIP; AddCode(c, 4); if ( DestReg < 8 ) c->Reg[DestReg] -= *(PDWORD)mem32;}void VMulEaxReg(PVMCONTEXT c){ BYTE SrcReg; c->EIP++; SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( SrcReg < 8 ) c->Reg[REGISTER_EAX] *= c->Reg[SrcReg];}void VDivEaxReg(PVMCONTEXT c){ BYTE SrcReg; c->EIP++; SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( SrcReg < 8 ) { c->Reg[REGISTER_EAX] /= c->Reg[SrcReg]; c->Reg[REGISTER_EAX] %= c->Reg[SrcReg]; }}void VANDRegReg(PVMCONTEXT c){ BYTE DestReg, SrcReg; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( ( DestReg < 8 ) && ( SrcReg < 8 ) ) c->Reg[DestReg] &= c->Reg[SrcReg];}void VAndRegImm(PVMCONTEXT c){ BYTE DestReg; DWORD imm32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); imm32 = *(PDWORD)c->EIP; AddCode(c, 4); if (DestReg < 8 ) c->Reg[DestReg] &= imm32;}void VAndRegMem(PVMCONTEXT c){ BYTE DestReg; DWORD mem32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); mem32 = *(PDWORD)c->EIP; AddCode(c, 4); if (DestReg < 8 ) c->Reg[DestReg] &= *(PDWORD)mem32;}void VORRegReg(PVMCONTEXT c){ BYTE DestReg, SrcReg; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); SrcReg = *(PBYTE)c->EIP; AddCode(c, 1); if ( ( DestReg < 8 ) & ( SrcReg < 8 ) ) c->Reg[DestReg] |= c->Reg[SrcReg];}void VORRegImm(PVMCONTEXT c){ BYTE DestReg; DWORD imm32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); imm32 = *(PDWORD)c->EIP; AddCode(c, 4); if (DestReg < 8 ) c->Reg[DestReg] |= imm32;}void VORRegMem(PVMCONTEXT c){ BYTE DestReg; DWORD mem32; c->EIP++; DestReg = *(PBYTE)c->EIP; AddCode(c, 1); mem32 = *(PDWORD)c->EIP; AddCode(c, 4); if (DestReg < 8 ) c->Reg[DestReg] |= *(PDWORD)mem32;}const INST inst_table[23] = {{VRetn},{VJmp},{VPUSHImm},{VPUSHReg},{VPUSHMem},{VPOPReg},{VPOPMem},{VMovRegReg},{VMovRegImm},{VMovRegMem},{VADDRegReg},{VADDRegImm},{VADDRegMem},{VSUBRegReg},{VSUBRegImm},{VSUBRegMem},{VMulEaxReg},{VDivEaxReg},{VANDRegReg},{VAndRegImm},{VORRegReg},{VORRegImm},{VORRegMem}};VMCONTEXT ExecuteVM(LPVOID Code, DWORD Size){ INST Ins; BYTE Op; LPVOID Stack; VMCONTEXT Context; for (Op = 0; Op < 7; Op++) Context.Reg[Op] = 0; Stack = GlobalAlloc(GMEM_FIXED, 1024 * 1024 * 2); if (Stack) { Context.Reg[REGISTER_ESP] = (DWORD)Stack; Context.EIP = (DWORD)Code; while (Context.EIP <= ((DWORD)Code + Size - 1)) { Op = *(PBYTE)Context.EIP; Ins = inst_table[Op]; Ins.FunctionCall(&Context); if (Op == 0) break; } GlobalFree(Stack); } return Context;}int main(void){ BYTE Code[13] = {0x08,0x00,0x05,0x00,0x00,0x00, // mov eax, 5 0x0B,0x00,0x05,0x00,0x00,0x00, // add eax, 5 0x00}; // retn VMCONTEXT Context = ExecuteVM(&Code, sizeof(Code)); std::cout << Context.Reg[REGISTER_EAX] << std::endl; return 0;}Sursa: ic0de.org Quote