2012-12-05 21 views
0

前一段時間我發佈了this question關於我嘗試穿過MASM程序時遇到的奇怪行爲。增量鏈接導致意外的MASM程序反彙編

從本質上講,給下面的代碼:

; Tell MASM to use the Intel 80386 instruction set. 
.386 
; Flat memory model, and Win 32 calling convention 
.MODEL FLAT, STDCALL 
; Treat labels as case-sensitive (required for windows.inc) 
OPTION CaseMap:None 

include windows.inc 
include masm32.inc 
include user32.inc 
include kernel32.inc 
include macros.asm 

includelib masm32.lib 
includelib user32.lib 
includelib kernel32.lib 

.DATA 
    BadText  db  "Error...", 0 
    GoodText db  "Excellent!", 0 

.CODE 
main PROC 
     int 3 
     mov eax, 6 
     xor eax, eax 
_label: add eax, ecx 
     dec ecx 
     jnz _label 
     cmp eax, 21 
     jz _good 
_bad: invoke StdOut, addr BadText 
     jmp _quit 
_good: invoke StdOut, addr GoodText 
_quit: invoke ExitProcess, 0 
main ENDP 
END main 

我不能讓int 3指令觸發。很明顯,它爲什麼沒有,檢查拆卸:

00400FFD add   byte ptr [eax],al 
00400FFF add   ah,cl 
--- [User path]\main.asm 
     mov eax, 6 
00401001 mov   eax,6 
     xor eax, eax 
00401006 xor   eax,eax 
_label: add eax, ecx 

int 3指令已被替換爲add al,cl,但我不知道爲什麼。我設法跟蹤問題是否啓用了增量鏈接。上面的反彙編是在增量鏈接禁用(/ INCREMENTAL:NO選項在命令行上)的情況下生成的。重新啓用這將導致類似如下:

.CODE 
main PROC 
     int 3 
00401010 int   3 
     mov eax, 6 
00401011 mov   eax,6 
     xor eax, eax 
00401016 xor   eax,eax 

我應該注意的是,交錯線的引用回到原來的代碼(我猜的Visual Studio的拆卸窗口的功能)。啓用增量鏈接後,反彙編完全對應於我在程序中編寫的內容,這正是我期望它始終如一表現的內容。

那麼,爲什麼要禁用Incremental Linking會導致我的程序的反彙編被改變?在幕後會發生什麼會實際上改變程序執行的方式?

回答

1

「add」指令是一個雙字節指令,其中第二個指令是int3的1字節操作碼。兩個字節添加指令的第一個字節在入口點之前可能是一些垃圾。 add指令的地址可能是int3指令所在位置之前的1個字節。

我迅速組裝,然後拆卸與GNU爲EN objdump的這兩個指令,其結果是:

8: 00 cc     add %cl,%ah 
    a: cc      int3 

在這裏你可以清楚地看到,add指令包含的第二個字節的0xCC,而INT3是0xcc

IOW確保您開始在入口點進行反彙編以避免此問題。

+0

如何確保我開始在入口點進行分解?這並不能解釋非增量鏈接會如何導致這種情況發生。 – kevintodisco

+0

1)我不MS'工具鏈,所以我不能說如何。 2)鏈接的改變可以改變入口點之前的內容,通過對鏈接段進行不同的排序。 –

+1

什麼都沒有發生,它編譯正確,只是反彙編觸發錯誤的地址 - 你看,它是xxxxFF,而顯然你的proc是對齊在xxxxx00,所以它仍然有正常的int3(cc)。在第一篇文章中回答你的最後一個問題,「會發生什麼?」 - 填充,對齊。使用OllyDbg或WinDbg,這些應該以正確,智能的方式處理反彙編。很可能,你的程序有標準基礎 - 400000;因此,請記住PE標頭1000h,401000h必須是入口點。爲什麼在第二種情況下存在10小時的差距 - 請查看對齊參數和前面的部分。 –