2012-03-31 75 views
6

我想要一個簡單的C方法能夠在Linux 64位機器上運行十六進制字節碼。下面是我的C程序:如何讓c代碼執行十六進制字節碼?

char code[] = "\x48\x31\xc0"; 
#include <stdio.h> 
int main(int argc, char **argv) 
{ 
     int (*func)(); 
     func = (int (*)()) code; 
     (int)(*func)(); 
     printf("%s\n","DONE"); 
} 

,我試圖運行("\x48\x31\xc0")我通過書面方式這個簡單的彙編程序(它不應該做任何事情)

​​

獲得的代碼然後編譯並objdump-它獲得字節碼。

但是,當我運行我的C程序時,出現了分段錯誤。有任何想法嗎?

+5

即使你的數據段是可執行的,或者你沒有啓用NX,你能指望這樣做?它執行一條指令,然後執行後面的指令(你不控制),然後執行指令,直到它到達的內存不代表觸發段錯誤的合法代碼或代碼。 – 2012-03-31 23:55:16

+1

您需要爲'ret'添加字節碼,因爲您做的間接函數調用應該是一個'call',它將返回地址壓入堆棧。至少,這是我受過最好教育的猜測,我從未見過這樣的事情。 – Chris 2012-03-31 23:56:56

+0

我希望這樣做什麼都不做,但我希望它能夠在不崩潰的情況下運行。 – Nosrettap 2012-03-31 23:58:52

回答

13

這是一個簡單的例子。

的main.c:

#include <sys/mman.h> 
#include <string.h> 

int main() 
{ 
    /*                
     mov rax, 60   ; sys_exit 
     mov rdi, 2 
     syscall             
    */ 
    char code[] = { 
     0x48, 0xb8, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x48, 0xbf, 0x02, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0x0f, 0x05 
    }; 

    void *buf; 

    /* copy code to executable buffer */  
    buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC, 
       MAP_PRIVATE|MAP_ANON,-1,0); 
    memcpy (buf, code, sizeof(code)); 

    /* run code */ 
    ((void (*) (void))buf)(); 

    return 0; 
} 

./main ;echo $? 

我選擇了做一個_exit(2)在大會可以很容易地檢查代碼是否正確運行運行這一點。實際上,您需要在代碼的最後添加一個ret來返回控制權。

+0

是的,'ret'對於返回到調用函數很重要。 – Chris 2012-04-01 19:22:02

+1

感謝您的幫助。我只想補充一點,objdump -d 可以讓你獲得可執行文件的字節碼。 – Jeff 2013-10-24 19:00:36

4

您的機器代碼可能是正確的,但是您的CPU對象。

現代CPUs分段管理內存。在正常操作中,操作系統將一個新程序加載到程序文本段中,並在數據段中設置堆棧。操作系統告訴CPU從不在數據段中運行代碼。您的代碼位於數據段中的code[]。因此段錯誤。

2

這將需要一些努力。

code變量存儲在你的可執行文件的.data部分:

$ readelf -p .data exploit 

String dump of section '.data': 
    [ 10] H1À 

H1À是你的變量的值。

.data可執行:

$ readelf -S exploit 
There are 30 section headers, starting at offset 0x1150: 
Section Headers: 
    [Nr] Name    Type    Address   Offset 
     Size    EntSize   Flags Link Info Align 
[...] 
    [24] .data    PROGBITS   0000000000601010 00001010 
     0000000000000014 0000000000000000 WA  0  0  8 

所有64位處理器,我熟悉支持非可執行網頁本身的pagetables。大多數較新的32位處理器(支持PAE的處理器)在頁表中爲操作系統提供足夠的額外空間來模擬硬件非可執行頁面。您需要運行古老的操作系統或古老的處理器,以獲得標記爲可執行文件的.data部分。

因爲這些只是可執行文件中的標誌,所以您應該能夠通過其他一些機制來設置X標誌,但我不知道該怎麼做。而且你的操作系統甚至可能不會讓你的頁面可寫可執行文件。