// 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