2013-02-17 80 views
1

我正在使用GDB調試Mac OSX 64位應用程序。我發現跳過大量代碼可以解決我所有的問題。ASM:向x86-64二進制文件寫入跳轉命令

但是:

如何修補可執行文件以實現跳轉?我希望應用程序自動跳轉到代碼中的定義點,而無需調試器。

這就是我想做的事:

地址0x1000027a9(調試器給出)跳到解決0x100003b6e。 我很努力地通過HexEdit來做到這一點,但沒有成功。我閱讀關於jmp到絕對地址操作碼的任何地方(FF似乎是正確的操作碼,但它是一個調用,而不是跳轉...),但沒有任何工作。訪問不良,sigfault。

我該怎麼做?

謝謝。

+0

這樣做的常見方法是:1)修復代碼和重建,2)嚮應用程序供應商報告錯誤。你爲什麼試圖自己修補它? – Mat 2013-02-17 13:49:55

+0

當你有一個非常舊的應用程序,沒有一家公司的支持時,你需要這樣的東西。當然,填寫錯誤報告可以解決我的問題。 – Mc128k 2015-06-08 07:21:43

回答

3

你想要的不是call,而是jmp,而你想直接jmp。直接跳轉通常使用相對於下一條指令的地址rip(請參閱my answer to SO question: How encode a relative short jmp in x86)。

所以,你在0x1000027a9,並想跳轉到0x100003b6e

0x100003b6e - 0x1000027a9 = 0x000013C5 =​​,所以明確不適合在很短的跳躍(rel8英特爾文檔中),但你需要jmp rel32。它也適用於rel16,但x86-64不支持(64位模式)。

所以,你想要一個jmp rel32。這是編碼相對於jmp之後的下一條指令,並且由於指令的長度是5個字節(E9 xx xx xx xx),所以rel32將是0x000013C0。由於x86是一種小端架構,因此編碼爲E9 C0 13 00 00

爲了證實這一點,我召集了一個小的測試可執行文件NASM與ndisasm拆卸它(注意我先走0x10000000個字節,但是作爲跳轉是相對的,它不會改變在編碼的任何東西):

000027A8 90    nop 
000027A9 E9C0130000  jmp dword 0x3b6e ; this is the instruction you need. 
000027AE 90    nop 
+0

作品!非常感謝!我在哪裏可以瞭解更多關於x86彙編的知識我在網上找到了一些資料,但它不完整或很舊。 – Mc128k 2013-02-17 15:06:31

+0

我發現介紹64位英特爾彙編語言編程的Linux相當有用。由於OS/X和Linux使用相同的System V ABI和函數調用,我認爲它幾乎可以完全適用於OS/X。對於32位代碼有更多的材料,但是因爲你有一個64位系統,所以我真的建議直接學習x86-64,它更方便(更多更大的寄存器使你作爲程序員的生活更加舒適)。雖然我不喜歡AT&T的語法,但是[編程基礎書籍](http://savannah.nongnu.org/projects/pgubook/)也可能有用。 – nrz 2013-02-17 15:22:09

+0

太棒了!對於32位代碼完成相同的工作,它的工作就像一個魅力。看起來我最初忘記了架構是小端... – Mc128k 2013-02-17 16:30:46