📄 vm.pas
字号:
{*******************************************************}
{ }
{ VMachine 1.0 }
{ }
{ 版权所有 (C) 2006 Lifeengines }
{ }
{*******************************************************}
{
vmcode格式定义说明
}
unit vm;
interface
uses disasm,link,windows;
//{$DEFINE SIGN}
{$IFDEF SIGN}
const
VM_SIGN:DWORD = $00434C5A;
{$ENDIF SIGN}
const
VM_NULL = 0;
VM_INIT = 0;
VM_MAX_LCMD = 16;
BIT32_CMDLEN = 4;
//table
//push 类
//last is 1B
//push ebp
VM_T_END = $FFFFFFEE;
VM_T_KEY0 = $10;
VM_T_KEY1 = $11;
VM_T_KEY2 = $12;
VM_T_KEY3 = $13;
//
VM_T_KEY = $13121110;
VM_T_CHAR0 = $0EE+VM_T_KEY0;
VM_T_CHAR1 = $0 + VM_T_KEY1;
VM_T_CHAR2 = $0 + VM_T_KEY2;
VM_T_CHAR3 = $0 + VM_T_KEY3;
VM_T_GROUP_0 = VM_T_CHAR1+0; //---------------------------
VM_T_GROUP_0_0 = VM_T_CHAR2 + 0; //---
VM_T_PUEBP = $010000EE+VM_T_KEY; //push ebx
VM_L_PUEBP = 1;
VM_C_PUEBP = $01+VM_T_CHAR3; //第4位
VM_T_PUEAX = $080000EE+VM_T_KEY;
VM_T_PUECX = $090000EE+VM_T_KEY;
VM_T_PUEBX = $0A0000EE+VM_T_KEY;
VM_T_PUEDX = $0B0000EE+VM_T_KEY;
VM_T_PUESI = $0C0000EE+VM_T_KEY;
VM_T_PUEDI = $0C0000EE+VM_T_KEY;
VM_T_S_PUSH = $100000EE+VM_T_KEY; //push 70h
VM_L_S_PUSH = 2;
VM_C_S_PUSH = $10 + VM_T_CHAR3;
VM_T_L_PUSH = $110000EE+VM_T_KEY;
VM_L_L_PUSH = 5;
VM_C_L_PUSH = $11 + VM_T_CHAR3;
//mov类
VM_T_GROUP_0_1 = 1 + VM_T_CHAR2; //------------------------------
VM_GROUP_ID_1 = $00010000;
//mov ebp,esp
VM_T_MOEBPESP = $020000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_MOEBPESP = 2;
VM_C_MOEBPESP = $02 + VM_T_CHAR3;
VM_T_MOEAXEAX = $0E0000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_T_MOEAXEBX = $0F0000EE+VM_T_KEY + VM_GROUP_ID_1;
//mov eax,400000
VM_T_L_MOVEAX = $040000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_L_MOVEAX = 5;
VM_C_L_MOVEAX = $04 + VM_T_CHAR3;
VM_T_L_MOVEBX = $120000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_L_MOVEBX = 5;
VM_C_L_MOVEBX = $12 + VM_T_CHAR3;
VM_T_L_MOVECX = $130000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_L_MOVECX = 5;
VM_C_L_MOVECX = $13 + VM_T_CHAR3;
VM_T_L_MOVEDX = $140000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_L_MOVEDX = 5;
VM_C_L_MOVEDX = $14 + VM_T_CHAR3;
VM_T_L_MOVEBP = $150000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_T_L_MOVESP = $160000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_T_L_MOVESI = $170000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_T_L_MOVEDI = $180000EE+VM_T_KEY + VM_GROUP_ID_1;
//mov eax,dword ptr [400000]
VM_T_M_MOVEAX = $060000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_M_MOVEAX = 5;
VM_C_M_MOVEAX = $06+ VM_T_CHAR3;
VM_T_M_MOVEBX = $190000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_M_MOVEBX = 6;
VM_C_M_MOVEBX = $19+ VM_T_CHAR3;
VM_T_M_MOVECX = $1A0000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_M_MOVECX = 6;
VM_C_M_MOVECX = $1A+ VM_T_CHAR3;
VM_T_M_MOVEDX = $1B0000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_M_MOVEDX = 6;
VM_C_M_MOVEDX = $1B+ VM_T_CHAR3;
//mov eax,[eax]
VM_T_MOEAX_M_EAX = $070000EE+VM_T_KEY + VM_GROUP_ID_1;
VM_L_MOEAX_M_EAX = 2;
VM_C_MOEAX_M_EAX = $07 + VM_T_CHAR3;
//add类
VM_T_GROUP_0_2 = 2 + VM_T_CHAR2; //------------------
VM_GROUP_ID_2 = $00020000;
// add esp,xx
VM_T_S_ADDESP = $030000EE+VM_T_KEY + VM_GROUP_ID_2;
VM_L_S_ADDESP = 3;
VM_C_S_ADDESP = $03 + VM_T_CHAR3;
//call类
//call xxxxxxxx
VM_T_GROUP_0_3 = 3 + VM_T_CHAR2; //--------------------
VM_GROUP_ID_3 = $00030000;
VM_T_L_CALL = $050000EE+VM_T_KEY + VM_GROUP_ID_3;
VM_L_L_CALL = 5;
VM_C_L_CALL = $05 + VM_T_CHAR3;
type Tvmcodeheader = packed record
{$IFDEF SIGN}
sign:DWORD;
{$ENDIF SIGN}
dw_starteip:dword;
dw_codesize:dword;
end;
type Tx86cmd = packed record
cmd:array[0..VM_MAX_LCMD-1] of char;
end;
type TVMachine = class
private
dw_size:cardinal;
dw_linkmem:cardinal;
dw_eip,
dw_codestart,
dw_postion:cardinal;
public
constructor create(mem_size:cardinal = $1000);
destructor Destroy();
function add(p_codestart,p_eip:cardinal):cardinal;
function GetPcode(cmds:Tx86cmd;dw_lencmd:cardinal;pa_pcode:cardinal;p_code:cardinal):cardinal;
property size:cardinal read dw_size write dw_size;
property memory:cardinal read dw_linkmem;
end;
implementation
constructor TVMachine.create(mem_size:cardinal = $1000);
begin
dw_linkmem := cardinal(VirtualAlloc(nil,mem_size,MEM_COMMIT,
PAGE_READWRITE));
dw_size := 0;
dw_postion := 0;
end;
function TVMachine.add(p_codestart,p_eip:cardinal):cardinal;
var
ch_cmd:Tx86cmd;
dis_result:t_disasm;
ca_lencmd:cardinal;
vm_lencmd:cardinal;
label vm_next;
begin
dw_eip := p_eip;
dw_codestart := p_codestart;
vm_next:
move(pointer(dw_codestart)^,ch_cmd.cmd,VM_MAX_LCMD);
ca_lencmd := DisAssemble(ch_cmd.cmd,VM_MAX_LCMD,dw_eip,@dis_result,DISASM_SIZE);
vm_lencmd := GetPcode(ch_cmd,ca_lencmd,dw_linkmem+dw_postion,dw_codestart);
if vm_lencmd <> 0 then
begin
fillchar(pointer(dw_codestart)^,ca_lencmd,0);
dw_eip := dw_eip+ca_lencmd; //计算下条指令地址
dw_postion := dw_postion+vm_lencmd;
dw_size := dw_size+vm_lencmd;
dw_codestart := dw_codestart+ca_lencmd;
goto vm_next;
end;
end;
destructor TVMachine.Destroy();
begin
virtualfree(pointer(dw_linkmem),0,MEM_RELEASE);
end;
function getvalue(p_src:cardinal):cardinal;stdcall;assembler;
asm
push eax
mov eax,p_src
mov eax,dword ptr [eax]
mov result,eax
pop eax
end;
procedure PushPcode(pa_pcode,v_code:cardinal);stdcall;
asm
pushad
mov eax,pa_pcode
mov ebx,v_code
mov dword ptr [eax],ebx
popad
end;
function TVMachine.GetPcode(cmds:Tx86cmd;dw_lencmd:cardinal;pa_pcode:cardinal;p_code:cardinal):cardinal;
begin
result := 0;
case cmds.cmd[0] of
#$55: //PUSH EBP
BEGIN
PushPcode(pa_pcode,VM_T_PUEBP);
result := sizeof(VM_T_PUEBP);
end;
#$8B:
begin
case cmds.cmd[1] of
#$EC: //mov ebp,esp
begin
PushPcode(pa_pcode,VM_T_MOEBPESP);
result := sizeof(VM_T_MOEBPESP);
end;
#$00://mov eax,[eax]
begin
PushPcode(pa_pcode,VM_T_MOEAX_M_EAX);
result := sizeof(VM_T_MOEAX_M_EAX);
end;
#$1D: //mov ebx,[xxxx]
begin
pushpcode(pa_pcode,VM_T_M_MOVEBX);
pushpcode(pa_pcode+sizeof(VM_T_M_MOVEBX),GetValue(p_code+2));
result := sizeof(VM_T_M_MOVEBX)+sizeof(cardinal);
end;
#$0D: //mov ecx,[xxxxx]
begin
pushpcode(pa_pcode,VM_T_M_MOVECX);
pushpcode(pa_pcode+sizeof(VM_T_M_MOVECX),GetValue(p_code+2));
result := sizeof(VM_T_M_MOVECX)+sizeof(cardinal);
end;
#$15: //mov edx,[xxx]
begin
pushpcode(pa_pcode,VM_T_M_MOVEDX);
pushpcode(pa_pcode+sizeof(VM_T_M_MOVEDX),GetValue(p_code+2));
result := sizeof(VM_T_M_MOVEDX)+sizeof(cardinal);
end;
end;
end;
#$83:
begin
case cmds.cmd[1] of
#$C4: //add esp,xx
begin
pushpcode(pa_pcode,VM_T_S_ADDESP);
pushpcode(pa_pcode+sizeof(VM_T_S_ADDESP),cardinal(cmds.cmd[2]));
result :=sizeof(VM_T_S_ADDESP)+sizeof(cardinal);
end;
end;
end;
#$B8: //mov eax,xxxxxxxx
begin
pushpcode(pa_pcode,VM_T_L_MOVEAX);
pushpcode(pa_pcode+sizeof(VM_T_L_MOVEAX),GetValue(p_code+1));
result := sizeof(VM_T_L_MOVEAX)+sizeof(cardinal);
end;
#$E8://call
begin
pushpcode(pa_pcode,VM_T_L_CALL);
pushpcode(pa_pcode+sizeof(VM_T_L_CALL),GetValue(p_code+1));
result := sizeof(VM_T_L_CALL)+sizeof(cardinal);
end;
#$6A://push x
begin
pushpcode(pa_pcode,VM_T_S_PUSH);
pushpcode(pa_pcode+sizeof(VM_T_S_PUSH),cardinal(cmds.cmd[1]));
result := sizeof(VM_T_S_PUSH)+sizeof(cardinal);
end;
#$68: //push xxxxxxxx
begin
pushpcode(pa_pcode,VM_T_L_PUSH);
pushpcode(pa_pcode+sizeof(VM_T_L_PUSH),GetValue(p_code+1));
result := sizeof(VM_T_L_PUSH)+sizeof(cardinal);
end;
#$A1: //mov eax,dword [xxxxx]
begin
pushpcode(pa_pcode,VM_T_M_MOVEAX);
pushpcode(pa_pcode+sizeof(VM_T_M_MOVEAX),GetValue(p_code+1));
result := sizeof(VM_T_M_MOVEAX)+sizeof(cardinal);
end;
#$B9://mov ecx,xxxxxxxx
begin
pushpcode(pa_pcode,VM_T_L_MOVECX);
pushpcode(pa_pcode+sizeof(VM_T_L_MOVECX),GetValue(p_code+1));
result := sizeof(VM_T_L_MOVECX)+sizeof(cardinal);
end;
#$BA://mov edx,xxxxxxxx
begin
pushpcode(pa_pcode,VM_T_L_MOVEDX);
pushpcode(pa_pcode+sizeof(VM_T_L_MOVEDX),GetValue(p_code+1));
result := sizeof(VM_T_L_MOVEDX)+sizeof(cardinal);
end;
#$BB: //mov ebx,xxxxxxxx
begin
pushpcode(pa_pcode,VM_T_L_MOVEBX);
pushpcode(pa_pcode+sizeof(VM_T_L_MOVEBX),GetValue(p_code+1));
result := sizeof(VM_T_L_MOVEBX)+sizeof(cardinal);
end;
// #$33:
// case cmds.cmd[1] of
// #$DB: //xor ebx,ebx
// begin
// end;
// end;
else
result := 0;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -