کد:
program vmtest;
uses
Windows, sysutils, codesitelogging;
const
// Registers
REGISTER_EAX = 0;
REGISTER_ECX = 1;
REGISTER_EDX = 2;
REGISTER_EBX = 3;
REGISTER_ESP = 4;
REGISTER_EBP = 5;
REGISTER_ESI = 6;
REGISTER_EDI = 7;
REGISTER_NOP = 8;
Type
PVMCONTEXT = ^TVMCONTEXT;
TVMCONTEXT = record
_Eip: DWord;
Reg: array [0..7] of DWord; //EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI
end;
TINST = Record
op: string;
Func: Procedure (c: PVMCONTEXT);
end;
procedure Addcode(c: PVMCONTEXT; n : byte);
begin
inc(c^._eip, n);
end;
Procedure VRetN(c: PVMCONTEXT);
begin
codesite.Send('eax', c^.Reg[REGISTER_EAX]);
end;
Procedure VJmp(c: PVMCONTEXT);
var
imm32 : DWord;
begin
inc(c^._eip);
imm32 := PDword(c^._eip)^;
c^._eip := imm32;
end;
Procedure VPUSHImm(c: PVMCONTEXT);
var
imm32 : DWord;
begin
inc(c^._eip);
imm32 := PDword(c^._eip)^;
Addcode(c,4);
PDword(c^.Reg[REGISTER_ESP])^ := imm32;
inc(c^.Reg[REGISTER_ESP], 4);
end;
Procedure VPUSHReg(c: PVMCONTEXT);
var
regflag: Byte;
imm32 : DWord;
begin
inc(c^._eip);
regflag := pByte(c^._eip)^;
Addcode(c,1);
if( regflag < 8 ) then begin
imm32 := c^.Reg[regflag];
PDword(c^.Reg[REGISTER_ESP])^ := imm32;
inc(c^.Reg[REGISTER_ESP], 4);
end else begin
codesite.senderror('VPUSHReg');
end;
end;
Procedure VPUSHMem(c: PVMCONTEXT);
var
mem32 : DWord;
imm32 : DWord;
begin
inc(c^._eip);
mem32 := PDword(c^._eip)^;
imm32 := PDword(mem32)^;
Addcode(c, 4);
PDword(c^.Reg[REGISTER_ESP])^ := imm32;
inc(c^.Reg[REGISTER_ESP], 4);
end;
Procedure VPOPReg(c: PVMCONTEXT);
var
regflag: Byte;
imm32 : DWord;
begin
inc(c^._eip);
regflag := pByte(c^._eip)^;
Addcode(c,1);
if( regflag < 8 ) then begin
imm32 := PDword(c^.Reg[REGISTER_ESP])^;
dec(c^.Reg[REGISTER_ESP], 4);
c^.Reg[regflag] := imm32;
end;
end;
Procedure VPOPMem(c: PVMCONTEXT);
var
imm32 : DWord;
mem32 : DWord;
begin
imm32 := PDword(c^.Reg[REGISTER_ESP])^;
dec(c^.Reg[REGISTER_ESP], 4);
mem32 := PDword(c^._eip)^;
Addcode(c, 4);
PDword(mem32)^ := imm32;
end;
procedure VMovRegReg(c: PVMCONTEXT);
var
DestReg, SrcReg: Byte;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if( DestReg < 8 ) and ( SrcReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[SrcReg];
end else begin
codesite.senderror('VMovRegReg');
end;
end;
procedure VMovRegImm(c: PVMCONTEXT);
var
DestReg: Byte;
imm32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
imm32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := imm32;
end else begin
codesite.senderror('VMovRegImm');
end;
end;
procedure VMovRegMem(c: PVMCONTEXT);
var
DestReg: Byte;
mem32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
mem32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := PDword(mem32)^;
end else begin
codesite.senderror('VMovRegMem');
end;
end;
procedure VADDRegReg(c: PVMCONTEXT);
var
DestReg, SrcReg: Byte;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if( DestReg < 8 ) and ( SrcReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] + c^.Reg[SrcReg];
end else begin
codesite.senderror('VADDRegReg');
end;
end;
procedure VADDRegImm(c: PVMCONTEXT);
var
DestReg: Byte;
imm32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
imm32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] + imm32;
end else begin
codesite.senderror('VADDRegImm');
end;
end;
procedure VADDRegMem(c: PVMCONTEXT);
var
DestReg: Byte;
mem32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
mem32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] + PDword(mem32)^;
end else begin
codesite.senderror('VADDRegMem');
end;
end;
procedure VSUBRegReg(c: PVMCONTEXT);
var
DestReg, SrcReg: Byte;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if( DestReg < 8 ) and ( SrcReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] - c^.Reg[SrcReg];
end else begin
codesite.senderror('VSUBRegReg');
end;
end;
procedure VSUBRegImm(c: PVMCONTEXT);
var
DestReg: Byte;
imm32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
imm32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] - imm32;
end else begin
codesite.senderror('VSUBRegImm');
end;
end;
procedure VSUBRegMem(c: PVMCONTEXT);
var
DestReg: Byte;
mem32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
mem32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] - PDword(mem32)^;
end else begin
codesite.senderror('VSUBRegMem');
end;
end;
procedure VMulEaxReg(c: PVMCONTEXT);
var
SrcReg: Byte;
begin
inc(c^._eip);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if ( SrcReg < 8 ) then begin
c^.Reg[REGISTER_EAX] := c^.Reg[REGISTER_EAX] - c^.Reg[SrcReg];
end else begin
codesite.senderror('VMulEaxReg');
end;
end;
procedure VDivEaxReg(c: PVMCONTEXT);
var
SrcReg: Byte;
begin
inc(c^._eip);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if ( SrcReg < 8 ) then begin
c^.Reg[REGISTER_EAX] := c^.Reg[REGISTER_EAX] div c^.Reg[SrcReg];
c^.Reg[REGISTER_EDX] := c^.Reg[REGISTER_EAX] mod c^.Reg[SrcReg]
end else begin
codesite.senderror('VDivEaxReg');
end;
end;
procedure VAndRegReg(c: PVMCONTEXT);
var
DestReg, SrcReg: Byte;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if( DestReg < 8 ) and ( SrcReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] and c^.Reg[SrcReg];
end else begin
codesite.senderror('VAndRegReg');
end;
end;
procedure VAndRegImm(c: PVMCONTEXT);
var
DestReg: Byte;
imm32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
imm32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] And imm32;
end else begin
codesite.senderror('VAndRegImm');
end;
end;
procedure VAndRegMem(c: PVMCONTEXT);
var
DestReg: Byte;
mem32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
mem32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] And PDword(mem32)^;
end else begin
codesite.senderror('VAndRegMem');
end;
end;
procedure VORRegReg(c: PVMCONTEXT);
var
DestReg, SrcReg: Byte;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
SrcReg := pByte(c^._eip)^;
Addcode(c,1);
if( DestReg < 8 ) and ( SrcReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] or c^.Reg[SrcReg];
end else begin
codesite.senderror('VORRegReg');
end;
end;
procedure VORRegImm(c: PVMCONTEXT);
var
DestReg: Byte;
imm32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
imm32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] Or imm32;
end else begin
codesite.senderror('VORRegImm');
end;
end;
procedure VORRegMem(c: PVMCONTEXT);
var
DestReg: Byte;
mem32: DWord;
begin
inc(c^._eip);
DestReg := pByte(c^._eip)^;
Addcode(c,1);
mem32 := PDword(c^._eip)^;
Addcode(c,4);
if( DestReg < 8 ) then begin
c^.Reg[DestReg] := c^.Reg[DestReg] or PDword(mem32)^;
end else begin
codesite.senderror('VORRegMem');
end;
end;
const
inst_table1 : array [0..23] of TINST =(
{00}(op: 'Retn'; Func: VRetN),
{01}(op: 'Jump'; Func: VJmp),
{02}(op: 'PUSHIm'; Func: VPUSHImm),
{03}(op: 'PUSHReg'; Func: VPUSHReg),
{04}(op: 'PUSHMem'; Func: VPUSHMem),
{05}(op: 'POPReg'; Func: VPOPReg),
{06}(op: 'POPMem'; Func: VPOPMem),
{07}(op: 'MovRegReg'; Func: VMovRegReg),
{08}(op: 'MovRegImm'; Func: VMovRegImm),
{09}(op: 'MovRegMem'; Func: VMovRegMem),
{10}(op: 'ADDRegReg'; Func: VADDRegReg),
{11}(op: 'ADDRegImm'; Func: VADDRegImm),
{12}(op: 'ADDRegMem'; Func: VADDRegMem),
{13}(op: 'SUBRegReg'; Func: VSUBRegReg),
{14}(op: 'SUBRegImm'; Func: VSUBRegImm),
{15}(op: 'SUBRegMem'; Func: VSUBRegMem),
{16}(op: 'MulEaxReg'; Func: VMulEaxReg),
{17}(op: 'DivEaxReg'; Func: VDivEaxReg),
{18}(op: 'ANDRegReg'; Func: VANDRegReg),
{19}(op: 'ANDRegImm'; Func: VANDRegImm),
{20}(op: 'ANDRegMem'; Func: VANDRegMem),
{21}(op: 'ORRegReg'; Func: VORRegReg),
{22}(op: 'ORRegImm'; Func: VORRegImm),
{23}(op: 'ORRegMem'; Func: VORRegMem)
);
Function ExecuteVM(Code: Pointer; Size: DWord):TVMCONTEXT;
var
Ins: TINST;
Op: Byte;
Stack: Pointer;
begin
with result do begin
{Setup Machine}
for op:= 0 to 7 do Reg[op] := 0;
GetMem(Stack, 1024*1024*2);
Reg[REGISTER_ESP] := DWord(Stack);
_eip := DWord(Code);
{Execute Cycle}
while (_eip <= (DWord(Code)+Size) -1 ) do begin
Op := pByte(_eip)^;
Ins := inst_table1[Op];
codesite.Send('%s / %s', [inttohex(Op, 2), Ins.op]);
Ins.Func(@result);
if (Op = 0) then exit;
end;
FreeMem(Stack, 1024*1024*2);
end;
end;
const
Temp:Array [0..12] of byte =(
$08,$00,$05,$00,$00,$00, //mov eax, 5
$0B,$00,$05,$00,$00,$00, //add eax, 5
$00 //ret
);
begin
ExecuteVM(@temp[0], sizeof(temp));
end.