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 }