2011-03-30 122 views

回答

5

之前GCC 5 (1),我不知道一種方式來運行任意機器碼,除非你真的輸入機器碼到內存,然後運行它。

如果你想在內存中運行的代碼是已經,你可以將指令指針設置爲開始,結束時斷點,然後去。然後,在斷點之後,將指令指針更改回其原始值。

但我實際上看不到這個用例。這並不意味着不是之一,只要你可以通過運行代碼來做任何事情,你也可以通過直接修改寄存器,標誌,內存等來實現。

例如,命令:

info registers 

將轉儲寄存器的當前值,同時:

set $eax = 42 

eax寄存器更改爲42

您也可以通過這種方式改變內存:

set *((char*)0xb7ffeca0) = 4 

此寫入內存位置0xb7ffeca0一個字節,你也可以使用同樣的方法來存儲更廣泛的數據類型。


(1) GCC 5允許編譯和與compile code命令執行任意代碼,如記錄here

+0

如何修改寄存器,如果'mov'等不能直接運行? – gdb 2011-03-30 01:59:02

+0

@gdb:例如,您可以使用'set $ eax = 42'。查看更新。 – paxdiablo 2011-03-30 02:13:11

+0

你也可以演示如何用'set'來改變內存嗎? – gdb 2011-03-30 02:22:53

0

編譯代碼命令,近GDB引入,允許代碼編譯和注射,文檔:https://sourceware.org/gdb/onlinedocs/gdb/Compiling-and-Injecting-Code.html

實施例:

int main() { 
    int i = 0; 
    printf("%d\n", i); 
    return 0; 
} 

然後在GDB:

start 
next 
compile code int j = 1; i = j; asm("nop"); 
continue 

程序輸出:

1 

爲此,您需要最近的GDB和GCC 5.x.測試上GDB 7.9.1,GCC 5.1,具有:

export LD_LIBRARY_PATH="/path/to/gcc/install/lib64:$LD_LIBRARY_PATH" 

使得libcc1.so將是可見的:這是一個最近GCC組分暴露一個C API到cc1編譯器。

還有如我所料一樣return,沒有工作的幾個結構,所以我問爲什麼在:In the GDB compile code command, what language constructs behave exactly as if they were present in the original source?

+0

這似乎並沒有像'asm volatile (「mov $ abc,%eax」)',當語言是C.在'compile'命令返回後,'$ rax'仍然有它的原始值。當源語言爲asm時,GDB 7.10不支持'compile'命令,所以即使在調試用asm編寫的函數時也不起作用。 – 2016-02-17 04:42:09

+0

@PeterCordes謝謝,我沒有嘗試過。 'compile'確實非常有限。但有潛力。 – 2016-02-17 10:22:30

+0

對於C/C++來說,它看起來非常方便,但不適合僅僅試驗不同輸入的指令。我想你可以使用一個C變量作爲輸出操作數,但是你需要一條指令來使用它。在這一點上,將指令放在文件中,彙編/鏈接它,以及單步操作可能會更容易。感謝您指出,儘管這不是* this *問題的好答案。 >< – 2016-02-17 10:28:20