01-12-2012، 11:44 PM
کد:
/* 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;
}