2011-12-14 54 views
3

可能重複:
Disassembling, modifying and then reassembling a Linux executable試圖組裝的反彙編器的輸出(如objdump的)

我已經告訴組件和dissassembly不是逆。顯然,你不能分解一個程序,把這個輸出直接放到一個彙編程序中,並且期望它能夠正確運行,因爲信息丟失了。

我的問題是,爲什麼信息丟失?另外,什麼信息丟失?

+2

http://stackoverflow.com/questions/4309771/disassembling-modifying-and-then-reassembling-a-linux-executable – n0p 2011-12-14 19:14:11

+0

謝謝,我試着問這個問題之前問,但我一定錯過了那一個 – matzahboy 2011-12-14 19:19:33

回答

7

反彙編程序(或其用戶)通常不會保留的一個重要內容是指令編碼。一些指令可以用多種不同的方式編碼,例如:

mov rdx, -1可以是48,BA,FF,FF,FF,FF,FF,FF,FF,FF(10字節)或48,C7,C2,FF ,FF,FF,FF(7字節)。

如果程序的其餘部分在某種程度上在功能上取決於上述指令的長度正好是10(或7)字節或這些特定的字節值,並且彙編程序選擇彙編mov rdx, -1與原始程序中的不同,然後在反彙編+彙編之後,你會得到一個不同的程序,它將以不同的方式工作。對於帶有模糊編碼的指令,彙編程序不得使用指令助記符(mov rdx, -1),而是在原始程序的反彙編(例如48,BA,FF,FF,FF,FF,FF,FF,FF,FF)中使用其確切編碼。

可能還有其他一些東西,彙編程序或鏈接程序可能會做不同的處理(例如,在輸出文件中以不同方式執行代碼/數據,名稱和順序事件(節/段)的附加對齊),這通常不是問題,但是,如果在原始程序中對這些東西有一些不尋常的依賴關係,那麼重新組合的程序將以不同的方式工作。

3

它不是一個損失,它實際上是一種收益。這聽起來像你還沒有嘗試過,爲什麼不嘗試呢?

.global reset 
reset: 

    mov #0x0280,r1 
    call #notmain 
    jmp hang 

.global hang 
hang: 
    jmp hang 

,你可以組裝看起來像這樣用objdump的:

0000f800 <reset>: 
    f800: 31 40 80 02  mov #640, r1 ;#0x0280 
    f804: b0 12 b2 f8  call #0xf8b2 
    f808: 00 3c   jmp $+2   ;abs 0xf80a 

0000f80a <hang>: 
    f80a: ff 3f   jmp $+0   ;abs 0xf80a 

你可以看到核心代碼仍然存在,如果你有列文本編輯器或其他一些矩形剪切和粘貼你可以將該代碼從中間剪下,並直接或用一點點按摩重新組裝。

沒有理由不能生成可以重新組裝的輸出的反彙編程序,我已經多次完成並多次看過它。事情是用反彙編,用例就是看到額外的信息。可以重新組裝的反彙編程序 的用例就像黑客攻擊某些代碼或類似的東西一樣。如果一個可變的指令長度指令集(x86)可以被編譯,那麼我強烈推薦人們編寫反彙編代碼,這對你的教育既是學習指令集又是如何編碼的,還有很多東西需要學習(我建議不要首先學習其中之一,先用手臂或拇指或類似的東西,或者至少不像x86那樣痛苦,比如msp430)。測試反彙編程序的好方法是輸出可重新組裝的代碼。組裝,拆卸,組裝,如果兩個組件輸出匹配,那麼你的反彙編程序做得很好。