我你使用的x86 32位機的代碼,如果沒有我的答案是不正確的猜測。
你的機器代碼提供了以下
0000 ADD BYTE PTR DS:[EAX],AL
8B00 MOV EAX,DWORD PTR DS:[EAX]
00XX ADD BYTE PTR ??? ; depends on the next byte
正如你可以看到,如果你試着執行這一點,嘗試任何在eax
是地址來訪問內存。它也不會以ret
或別的東西結束,所以它會直接前進而無需關心接下來的內容。在大多數情況下,這會崩潰。無論如何,您也可能無法執行DATA段中定義的代碼。
如果你想執行的shellcode,你可以嘗試像下面這個簡單的模板。這個想法是在堆棧上創建代碼並在那裏執行代碼。給定的機器代碼函數沒有很好地實現,但至少是正確的,不會導致崩潰。它相當於C代碼
void f(void) { return; };
由調試模式下的VC++編譯。
#include <stdio.h>
int main()
{
const char code[] = "\x55\x8B\xEC\x81\xEC\xC0\x00\x00"
"\x00\x53\x56\x57\x8D\xBD\x40\xFF"
"\xFF\xFF\xB9\x30\x00\x00\x00\xB8"
"\xCC\xCC\xCC\xCC\xF3\xAB\x5F\x5E"
"\x5B\x8B\xE5\x5D\xC3";
printf("Start execution\r\n");
((void (*)())code)();
printf("End execution\r\n");
_getch();
}
如果上述不工作,你可以嘗試。
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
int main()
{
const char code[] = "\x55\x8B\xEC\x81\xEC\xC0\x00\x00"
"\x00\x53\x56\x57\x8D\xBD\x40\xFF"
"\xFF\xFF\xB9\x30\x00\x00\x00\xB8"
"\xCC\xCC\xCC\xCC\xF3\xAB\x5F\x5E"
"\x5B\x8B\xE5\x5D\xC3";
void *exec = VirtualAlloc(0, sizeof(code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, code, sizeof(code));
printf("Start execution\r\n");
((void(*)())exec)();
printf("End execution\r\n");
//_getch();
}
這個想法是使用分配的內存頁與標誌PAGE_EXECUTE_READWRITE
。
其中底層CPU執行的機器代碼?如果x86然後0x00不是'NOP'。 'NOP'具有操作碼'0x90'。 –
@ Fermat2357:有很多有效的操作碼是'NOP',而不僅僅是單字節操作碼'0x90'。 – 0xC0000022L
是的,我的錯,如果你發現所有可能的指令都是「NOP」,你就是對的。 –