1 // VM.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "windows.h" 6 7 /* 下面是虚拟指令 我们只模拟了2条指令 */ 8 9 //push 0x12345678 push一个4字节的数 10 #define vPushData 0x10 11 12 //call 0x12345678 call一个4字节的地址 13 #define vCall 0x12 14 15 //结束符 16 #define vEnd 0xff 17 18 //一个字符串 19 char *str = "Hello World"; 20 21 /* 22 这是我们构造的虚拟指令, 数据还不 在mian里面我们进行了修改 23 push 0 24 push offset str 25 push offset str ;把字符串的地址入栈 26 push 0 27 call MessageBoxA ; 28 */ 29 BYTE bVmData[] = { vPushData, 0x00, 0x00, 0x00,0x00, 30 vPushData, 0x00, 0x00, 0x00,0x00, 31 vPushData, 0x00, 0x00, 0x00, 0x00, 32 vPushData, 0x00, 0x00, 0x00,0x00, 33 vCall, 0x00, 0x00, 0x00, 0x00, 34 vEnd}; 35 36 37 //这就是简单的虚拟引擎了 38 _declspec(naked) void VM(PVOID pvmData) 39 { 40 __asm 41 { 42 //取vCode地址放入ecx 43 mov ecx, dword ptr ss:[esp+4] 44 __vstart: 45 //取第一个字节到al中 46 mov al, byte ptr ds:[ecx] 47 cmp al, vPushData 48 je __vPushData 49 cmp al, vCall 50 je __vCall 51 cmp al, vEnd 52 je __vEnd 53 int 3 54 __vPushData: 55 inc ecx 56 mov edx, dword ptr ds:[ecx] 57 push edx 58 add ecx, 4 59 jmp __vstart 60 __vCall: 61 inc ecx 62 mov edx, dword ptr ds:[ecx] 63 call edx 64 add ecx, 4 65 jmp __vstart 66 __vEnd: 67 ret 68 } 69 } 70 71 72 int main(int argc, char* argv[]) 73 { 74 //修改虚拟指令的数据 75 76 *(DWORD *)(bVmData+5 + 1) = (DWORD)str; 77 *(DWORD *)(bVmData+10 + 1) = (DWORD)str; 78 *(DWORD *)(bVmData+20 + 1) = (DWORD)MessageBoxA; 79 80 //执行虚拟指令 81 VM(bVmData); 82 return 0; 83 }