3

剛剛閱讀了有關不同的算法反彙編程序用於識別二進制文件作爲彙編指令。在不同的反彙編程序中打開一個程序,其中一些將程序的特定部分顯示爲代碼,另一些顯示與數據相同的部分。所以我的問題是反彙編在操作碼是指令還是數據之間會產生混淆,處理器如何知道該操作碼到底該怎麼做?反彙編程序顯示不同的指令

我希望我的問題是明確的.. 在此先感謝..

回答

3

處理器不知道它要求執行的是代碼還是數據。它可以是一個或兩個在同一時間。 CPU會嘗試執行它給出的任何內容。

如果執行失敗,可能會產生諸如「遇到無效指令」或「指令引用的內存不可訪問」或「除零」或「權限不足」等事件(希望)處理。如果它知道如何(虛擬內存通常基於此機制)或讓應用程序處理此事件或終止應用程序,它將修復問題。

有不同的反彙編。有些是「愚蠢」的反彙編程序,因爲它們不會試圖對可執行文件格式有很多或任何意義,它們只會試圖反彙編它們提供的任何內容。其他人將反彙編標記爲代碼的文件部分,並且他們將從入口點位置開始反彙編(每個可執行文件都有一個應由OS/CPU啓動的位置),並使用各種啓發式方法進行明智的反彙編。

但是,拆卸幾乎無法完美完成。正確拆卸的主要問題是反彙編不知道代碼將執行什麼以及不執行什麼。

例如,可以編寫代碼,以便計算要跳轉或呼叫的地址。反彙編程序將無法計算出這樣的地址,因爲它不會執行,模擬或解釋代碼。所以反彙編可能無法找出下一個可以反彙編的位置。

也有CPU具有可變長度指令。這使得代碼跳轉到指令中間成爲可能。反彙編應該如何反彙編這種代碼?

另一個加重的做法是使用代碼進行操縱。代碼可以在執行時隨時更改。代碼也可以生成更多的代碼。代碼也可以作爲數據存儲。你如何分解所有這些?

因此,毫不奇怪的是,許多反彙編仍然非常愚蠢。他們無法與編寫各種各樣程序的程序員的智力競爭。

EDIT

另外,由於同樣的可變長度指令的問題,disassemblying開始在稍微不同的位置可以產生不同的指令相同的代碼。

實施例:

考慮32位模式爲x86處理器此字節序列:66H,0B8h,90H,90H,90H,90H。

如果你開始的第一個字節disassemblying它,你將得到:

mov ax,9090h 
nop 
nop 

如果你開始下一個字節disassemblying您將獲得:

mov eax,90909090h 

如果跳過另一個字節你會得到:

nop 
nop 
nop 
nop 
+0

niice謝謝:) – user1466594 2012-07-05 09:59:37

3

只是讀有關不同交易算法反編譯器使用來識別二進制的彙編指令。

因此,我假設你的意思是線性掃描與遞歸遍歷 - 有一個有趣的頁面在那here

所以我的問題是如果反彙編之間的指令或數據操作碼之間混淆,處理器如何知道如何處理該操作碼?

所以,這個問題的肉 - 他們不,也不關心。 CPU不知道關於數據和指令的任何信息。這就是爲什麼您可以通過替換包含操作碼的字符串從緩衝區溢出來執行堆棧上的輸入。如果指令指針(EIP/RIP)結束,那麼處理器只會引發一個錯誤(基本上在操作系統上發出呻吟聲),這是因爲標記頁面不執行而導致的。

反彙編的挑戰在於,你正在試圖找出實際運行它的代碼的結構。解決這個問題的唯一方法是生成一個x86模擬器並使用它。

這被稱爲halting problem

+0

非常感謝..btw看着你的答案我假設ura安全的人:) – user1466594 2012-07-05 09:57:08

+0

@ user1466594我寫了很多C,並且它不得不充滿安全漏洞;) – 2012-07-05 11:15:44

+0

這是一個非常出色的答案,我從安全人員的心臟聲稱「拆卸是不可判定的」,但他們都不能給充分解釋「爲什麼它是不可判定的」。謝謝安東尼,現在我想我知道爲什麼它是不可判定的... – computereasy 2014-03-15 06:06:12