// VM.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> int main(int argc, char* argv[]) { //MessageBox(NULL,"lpText","lpCaption",MB_OK); char *lpCation = "VM"; char *lpText = "Hello world"; __asm { push MB_OK mov eax,lpCation push eax mov eax,lpText push eax push 0 call dword ptr[MessageBoxA] } return 0; }
反汇编:
00401010 >|> \55 push ebp 00401011 |. 8BEC mov ebp, esp 00401013 |. 83EC 48 sub esp, 48 00401016 |. 53 push ebx 00401017 |. 56 push esi 00401018 |. 57 push edi 00401019 |. 8D7D B8 lea edi, dword ptr [ebp-48] 0040101C |. B9 12000000 mov ecx, 12 00401021 |. B8 CCCCCCCC mov eax, CCCCCCCC 00401026 |. F3:AB rep stos dword ptr es:[edi] 00401028 |. C745 FC 2C204>mov dword ptr [ebp-4], 0042202C ; ASCII "VM" 0040102F |. C745 F8 1C204>mov dword ptr [ebp-8], 0042201C ; ASCII "Hello world" 00401036 |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 00401038 |. 8B45 FC mov eax, dword ptr [ebp-4] ; | 0040103B |. 50 push eax ; |Title 0040103C |. 8B45 F8 mov eax, dword ptr [ebp-8] ; | 0040103F |. 50 push eax ; |Text 00401040 |. 6A 00 push 0 ; |hOwner = NULL 00401042 |. FF15 ACA24200 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA 00401048 |. 33C0 xor eax, eax 0040104A |. 5F pop edi 0040104B |. 5E pop esi 0040104C |. 5B pop ebx 0040104D |. 83C4 48 add esp, 48 00401050 |. 3BEC cmp ebp, esp 00401052 |. E8 29000000 call _chkesp 00401057 |. 8BE5 mov esp, ebp 00401059 |. 5D pop ebp 0040105A \. C3 retn
VM编写:
// VM.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #define vPush 0x11 //填充数据,可以为任何值 #define vCall 0x22 #define vEnd 0xff BYTE VMData[] = { vPush,0x00,0x00,0x00,0x00, //push MB_OK 两个字节 vPush,0x00,0x00,0x00,0x00, //push lpCaption 两个字节 vPush,0x00,0x00,0x00,0x00, //push lpText 两个字节 vPush,0x00,0x00,0x00,0x00, //push 0 两个字节 vCall,0x00,0x00,0x00,0x00, //call dword ptr[MessageBoxA] vEnd }; __declspec(naked) void VM(LPVOID VMData) { __asm { mov ecx,dword ptr[esp+4] __VStart: mov al,byte ptr [ecx] //取第一个字节 cmp al,vPush //判断是不是参数部分 je __Vpush //是则跳转到push参数部分 cmp al,vCall //是不是call,是则跳转 je __VCall cmp al,vEnd //是否结束 je __VEnd __Vpush: inc ecx //加一在取四字节 mov edx,dword ptr[ecx] push edx //push MB_OK add ecx,4 jmp __VStart __VCall: inc ecx mov edx,dword ptr [ecx] sub edx,4 call edx add ecx,4 jmp __VStart __VEnd: retn } } int main(int argc, char* argv[]) { //MessageBox(NULL,"lpText","lpCaption",MB_OK); char *lpCation = "VM"; char *lpText = "Hello world"; //push MB_OK 数据本身就是0,所以不用填充 *(DWORD*)(VMData +5 +1) = (DWORD)lpCation; //传递地址,字符串以\0结尾 *(DWORD*)(VMData +10 +1) = (DWORD)lpText; //push hWnd 句柄也默认为0,不用填充 *(DWORD*)(VMData +20 +1) = (DWORD)MessageBoxA+4; //执行虚拟指令 VM(VMData); return 0; }
Debug反汇编,有卡顿现象
00401005 /$ /E9 26C40000 jmp main 0040100A | |E9 01000000 jmp VM 0040100F | |CC int3 00401010 >|> |8B4C24 04 mov ecx, dword ptr [esp+4] 00401014 |? |8A01 mov al, byte ptr [ecx] 00401016 |. |3C 11 cmp al, 11 00401018 |. |74 08 je short 00401022 0040101A |? |3C 22 cmp al, 22 0040101C |. |74 0D je short 0040102B 0040101E |? |3C FF cmp al, 0FF 00401020 |? |74 16 je short 00401038 00401022 |? |41 inc ecx 00401023 |? |8B11 mov edx, dword ptr [ecx] 00401025 |? |52 push edx 00401026 |. |83C1 04 add ecx, 4 00401029 |?^|EB E9 jmp short 00401014 0040102B |? |41 inc ecx 0040102C |? |8B11 mov edx, dword ptr [ecx] 0040102E |? |83EA 04 sub edx, 4 00401031 |? |FFD2 call edx 00401033 |? |83C1 04 add ecx, 4 00401036 |.^|EB DC jmp short 00401014 ; /Style 00401038 |. |C3 retn ; |
Release版,没有卡顿现象
00401030 /$ A1 9C504000 mov eax, dword ptr [<&USER32.MessageBoxA>] 00401035 |. 68 30604000 push 00406030 0040103A |. 83C0 04 add eax, 4 0040103D |. C705 36604000>mov dword ptr [406036], 00406058 ; ASCII "VM" 00401047 |. C705 3B604000>mov dword ptr [40603B], 0040604C ; ASCII "Hello world" 00401051 |. A3 45604000 mov dword ptr [406045], eax 00401056 |. E8 A5FFFFFF call 00401000 0040105B |. 83C4 04 add esp, 4 0040105E |. 33C0 xor eax, eax 00401060 \. C3 retn
。
00401000 /$ 8B4C24 04 mov ecx, dword ptr [esp+4] 00401004 |> 8A01 /mov al, byte ptr [ecx] 00401006 |. 3C 11 |cmp al, 11 ; Switch (cases 22..FF) 00401008 |. 74 08 |je short 00401012 0040100A |. 3C 22 |cmp al, 22 0040100C |. 74 0D |je short 0040101B 0040100E |. 3C FF |cmp al, 0FF 00401010 |. 74 16 |je short 00401028 00401012 |> 41 |inc ecx ; Default case of switch 00401006 00401013 |. 8B11 |mov edx, dword ptr [ecx] 00401015 |. 52 |push edx 00401016 |. 83C1 04 |add ecx, 4 00401019 |.^ EB E9 |jmp short 00401004 0040101B |> 41 |inc ecx ; Case 22 of switch 00401006 0040101C |. 8B11 |mov edx, dword ptr [ecx] 0040101E |. 83EA 04 |sub edx, 4 00401021 |. FFD2 |call edx 00401023 |. 83C1 04 |add ecx, 4 00401026 |.^ EB DC \jmp short 00401004 00401028 \> C3 retn ; Case FF of switch 00401006