2009-04-25 55 views
1

是否有可能使用GNU工具(gcc,binutils等)將所有出現的彙編指令修改爲無操作?具體來說,GCC使用-pg選項生成以下組件(ARM):試圖禁止一條指令

0x0: e1a0c00d mov ip, sp 
    0x4: e92dd800 stmdb sp!, {fp, ip, lr, pc} 
    0x8: e24cb004 sub fp, ip, #4 ; 0x4 
    0xc: ebfffffe bl 0 <mcount> 

我想記錄下這最後一條指令的地址,然後在下面的代碼

0x0: e1a0c00d mov ip, sp 
    0x4: e92dd800 stmdb sp!, {fp, ip, lr, pc} 
    0x8: e24cb004 sub fp, ip, #4 ; 0x4 
    0xc: e1a00000 nop   (mov r0,r0) 
將其更改爲NOP像

Linux內核在運行時可以做類似的事情,但我正在尋找一個構建時間解決方案。

回答

4

這對於RISC-ish固定長度指令格式來說肯定比對比例更容易。 86。

它應該是相對簡單的使用了libelf(很好的教程在這裏:http://people.freebsd.org/~jkoshy/download/libelf/article.html)或libbfd(http://sourceware.org/binutils/docs-2.19/bfd/index.html)打開目標文件,在.text段中修改說明,並使用提供的API再次寫出來。是否值得努力取決於非技術因素(儘管......我有點好奇)。

值得一提的是,如果需要在交叉開發環境中工作,使用libelf或libbfd可能會有一些皺紋。

+0

雖然您的觀點是有效的,但x86上的'nop'是一個單字節指令,因此您可以根據需要通過要刪除的可變長度指令編寫儘可能多的指令。 – 2009-06-01 17:47:01

+1

對於可變長度指令的情況,會變得更加成問題的部分是搜索要變成無操作的指令模式,因爲您不能分辨給定的字節偏移量是否是指令的開始而不解碼抵消之前的指令。如果你認爲巧妙的手工編譯彙編技巧就像分支到有時用來打敗(或者至少阻礙)二進制文件逆向工程的指令中間,那更糟糕。 – 2009-06-01 18:14:58

6

您可以使用gcc -S編譯代碼以輸出彙編程序列表,而不是完全編譯爲目標文件或可執行文件。然後,只需用no-ops替換所需的指令(例如使用sed),然後繼續編譯。

如果您還希望爲沒有原始源代碼的目標文件或庫執行此操作,您將不得不使用諸如objdump(1)之類的工具對其進行反彙編並獲取指令的地址你想替換。然後,解析目標文件頭以在這些指令的文件中查找偏移量,然後直接在目標文件中用no-ops替換機器指令。這有點棘手,但可行。