1. 程式人生 > >使用VS反彙編除錯

使用VS反彙編除錯

查找出錯誤的函式

查詢函式內某個出錯引數

2.  適用情況

比較適合於使用第三方庫或者其他dll檔案時,無法進入使用函式內部的情況。

3.  注意點:

call函式:函式的返回值能夠反映函式呼叫情況,如果出錯,則一般為函式返回值異常,函式返回值存放於EAX中。

出錯程式碼:VS中函式執行完成後會返回出錯程式碼,出錯程式碼可能為巨集定義值,此時可以結合原始碼(如果有的話),IDA反彙編出dll,具體一一對應。

彙編檢視跳轉:如果判定條件為≥,那麼在彙編中的跳轉指令可能是<。

4.  基礎知識:

1)   指令

ret跳轉會呼叫函式的地方。對應於call,返回到對應的call呼叫的下一條指令,若有返回值,則放入eax中;

xor異或指令,這本身是一個邏輯運算指令,但在彙編指令中通常會見到它被用來實現清零功能。用xor eax,eax這種操作來實現mov eax,0,可以使速度更快,佔用位元組數更少。

lea取得第二個引數地址後放入到前面的暫存器(第一個引數)中。lea也同樣可以實現mov的操作,例如: lea edi,[ebx-0ch],方括號表示儲存單元,也就是提取方括號中的資料所指向的內容,然而lea提取內容的地址,這樣就實現了把(ebx-0ch)放入到了edi中,但是mov指令是不支援第二個運算元是一個暫存器減去一個數值的。

stos序列儲存指令,它實現把eax中的資料放入到edi所指的地址中,同時edi後移4個位元組,這裡的stos實際上對應的是stosd,其他的還有stosb,stosw分別對應1,2個位元組。

jmp無條件跳轉指令,對應於大量的條件跳轉指令。

jg條件跳轉,大於時成立,進行跳轉,通常條件跳轉之前會有一條比較指令(用於設定標誌位)。

jl小於時跳轉。

jge大於等於時跳轉。

cmp比較大小指令,結果用來設定標誌位。

彙編跳轉指令記憶

比較數目大小的

J    == jump
E   == Equal
Z   == Zero
A   == Above
B == Below
G == Greater
L   == Less
N == Not

比較標誌位的

C   == Carry(進位)
O   
== Overflow(溢位)
P   
==   Parity(奇偶性)
S   

==   Sign(符號位)

表 測試標誌位的JCC指令

指 令

描 述

條 件

別 名

相 反 指 令

JC

如果進位位被置位則跳轉

進位標誌=1

JB,JNAE

JNC

JNC

如果進位位沒有置位則跳轉

進位標誌=0

JNB,JAE

JC

JZ

如果0標誌被置位則跳轉

0標誌=1

JE

JNZ

JNZ

如果0標誌沒有置位則跳轉

0標誌=0

JNE

JZ

JS

如果符號位被置位則跳轉

符號標誌=1

JNS

JNS

如果符號位沒有被置位則跳轉

符號標誌=0

JS

JO

如果溢位標誌置位則跳轉

溢位標誌=1

JNO

JNO

如果溢位標誌沒有置位則跳轉

溢位標誌=0

JO

JP

如果奇偶校驗位被置位則跳轉

奇偶校驗標誌=1

JPE

JNP

JPE

如果奇偶校驗位為偶校驗則跳轉

奇偶校驗標誌=1

JP

JPO

JNP

如果奇偶校驗位沒有被置位則跳轉

奇偶校驗標誌=0

JPO

JP

JPO

如果奇偶校驗位為奇校驗則跳轉

奇偶校驗標誌=0

JNP

JPE

表 使用無符號數比較的JCC指令

指 令

描 述

條 件

別 名

相反指令

JA

如果超過(>)則跳轉

進位標誌=0,0標誌=0

JNBE

JNA

JNBE

如果不低於或等於(不 <=)則跳轉

進位標誌=0,0標誌=0

JA

JBE

JAE

如果超過或等於(>=)則跳轉

進位標誌=0

JNC,JNB

JNAE

JNB

如果不低於則跳轉(不 <)

進位標誌=0

JNC,JAE

JB

JB

如果低於(<)則跳轉

進位標誌=1

JC,JNAE

JNB

JNAE

如果不超過或等於(不>=)則跳轉

進位標誌=1

JC,JB

JAE

JBE

如果低於或等於(<=)則跳轉

進位標誌=1或0標誌=1

JNA

JNBE

JNA

如果不超過(不>)則跳轉

進位標誌=1或0標誌=1

JBE

JA

JE

如果相等(=)則跳轉

0標誌=1

JZ

JNE

JNE

如果不相等(<>)則跳轉

0標誌=0

JNZ

JE

表 使用有符號數比較的JCC指令

指 令

描 述

條 件

別 名

相反指令

JG

如果大於(>)則跳轉

符號標誌=溢位標誌或0標誌=0

JNLE

JNG

JNLE

如果小於或等於(<=)則跳轉

符號標誌=溢位標誌或0標誌=0

JG

JLE

JGE

如果大於或等於(>=)則跳轉

符號標誌=溢位標誌

JNL

JGE

JNL

如果不小於(不<)則跳轉

符號標誌=溢位標誌

JGE

JL

JL

如果小於(<)則跳轉

符號標誌<>溢位標誌

JNGE

JNL

JNGE

如果大於或等於(>=)跳轉

符號標誌<>溢位標誌

JL

JGE

JLE

如果小於或等於(<=)跳轉

符號標誌<>溢位標誌或0標誌=1

JNG

JNLE

JNG

如果不大於(不>)則跳轉

符號標誌<>溢位標誌或0標誌=1

JLE

JG

JE

如果等於(=)則跳轉

0標誌=1

JZ

JNE

JNE

如果不等於(<>)則跳轉

0標誌=0

JNZ

JE

5.  具體內容及示例

首先是匯出表,能夠檢視具體對應的相關函式,可以與VS中的具體進行對應(主要使用了IDA能夠反彙編的功能,例如如下情況的對應)

可以看出IDA反彙編出的程式碼與原始碼基本上是一致的,當沒有原始碼的時候,就更多的需要使用IDA反彙編出的程式碼進行具體內容的查詢。

可以看出此處進入呼叫函式。

Mov一般是取具體的資料或引數內容,push為取對應的引數(例如上圖中的push 1 就是kPGPKeyDBObjType_Key所對應的定義值),因此可以一直執行到call指令處。

已知道函式會在此處出錯,因此到達此call指令時,使用F11進入。

對比可以發現,兩者一致。

原始碼和IDA反彙編出的程式碼相比較,兩者一致,這是就可以查詢具體對應的函式。