/*
VM初探
作者:blueapplez
QQ:124272113
Email:blueapple1987@163.com
http://bbs.pediy.com/
*/
#include "windows.h"
/* 下面是虚拟指令 我们只模拟了2条指令 */
//push 0x12345678 push一个4字节的数
#define vPushData 0x10
//call 0x12345678 call一个4字节的地址
#define vCall 0x12
//结束符
#define vEnd 0xff
//一个字符串
char *str = "Hello World";
/*
这是我们构造的虚拟指令, 数据还不 在mian里面我们进行了修改
push 0
push 0
push offset str ;把字符串的地址入栈
push 0
call MessageBoxA ;
*/
BYTE bVmData[] = {
vPushData, 0x00, 0x00, 0x00, 0x00,
vPushData, 0x00, 0x00, 0x00, 0x00,
vPushData, 0x00, 0x00, 0x00, 0x00,
vPushData, 0x00, 0x00, 0x00, 0x00,
vCall, 0x00, 0x00, 0x00, 0x00,
vEnd};
//这就是简单的虚拟引擎了
_declspec(naked) void VM(PVOID pvmData)
{
__asm
{
//取vCode地址放入ecx
mov ecx, dword ptr ss:[esp+4]
__vstart:
//取第一个字节到al中
mov al, byte ptr ds:[ecx]
cmp al, vPushData
je __vPushData
cmp al, vCall
je __vCall
cmp al, vEnd
je __vEnd
int 3
__vPushData:
inc ecx
mov edx, dword ptr ds:[ecx]
push edx
add ecx, 4
jmp __vstart
__vCall:
inc ecx
mov edx, dword ptr ds:[ecx]
call edx
add ecx, 4
jmp __vstart
__vEnd:
ret
}
}
int main(int argc, char* argv[])
{
//修改虚拟指令的数据
*(DWORD *)(bVmData+10 + 1) = (DWORD)str;
*(DWORD *)(bVmData+20 + 1) = (DWORD)MessageBoxA;
//执行虚拟指令
VM(bVmData);
return 0;
}