banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

《從零開始學IDA逆向》學習筆記-7(流程控制)

image

1、無條件跳轉指令 JMP#

EIP(指針寄存器)指向下一條將要執行的命令,執行完畢後,EIP 指向再下一條。EIP(指針寄存器)中的值會在每條指令執行後自動更新,指向下一條將要執行的指令的地址。匯編語言中的一些跳轉指令(例如 JMP、JE、JNE 等)可以修 EIP 的值,從而實現跳轉到指定地址處執行。

JMP A指令當中,A 是程序作者期望的無條件轉向的一個內存地址。

image

jmp short 指令

JMP SHORT指令是一個兩字節的短程跳轉指令,只能向前或者往回跳轉。第一個字節 EB 是跳轉操作碼 (OPCODE)。跳轉的方向由第二個字節的值確定。這種跳轉是有距離限制的。

image

顯示 jmp short 指令的機器碼

上圖中,EB 是 jmp 的操作碼,這條指令向前跳轉到指令結束後的 5 個字節,計算目標地址可以採用下圖的方式,指令的起始地址➕指令本身的長度(2 字節)➕ 第二個字節跳轉的距離(5 字節)。

image

計算跳轉位置

short 的跳轉距離:最大的正向跳轉距離是 0x7f。

注:ida 顯示機器碼

菜單欄 Options-General 設置,將 Number of opcode bytes (graph) 的值改為 12(10),默認位 0。

image

注:數據庫快照功能

逆向其間會對程序做些修改,會打斷已識別的函數,使用數據庫快照能夠返回之前某個時候的狀態,當遇到問題不知如何修復時,可以使用這個功能。

image

給快照命名

image

加載快照,View-Database snapshot manager

image

可以看到所有的快照清單以及創建的日期

image

實驗 2 將跳轉的第二個字節從 05 改成 7f

使用 ida patch byte 功能將 05 改成 7f

image

image

image

實驗2 將05修改位7f

image

實驗2 修改後的匯編視圖 從上圖可以看出左側的箭頭,程序在這裡向前跳到0x4013a5。

image

image

接下來將 0x7f 改為 0x80。

image

改為 0x80 後,程序往回跳轉,之前的 0x7f 是最遠的向前跳轉,那麼,0x80 是最遠的往後跳轉。

image

由於 python 不會從數值上判斷向前還是往後跳轉,必須輸入一個 dword 表示 - 0x80,也就是0xffffff80,計算的結果和0xffffffff進行按位與運算,超過 32 位的比特位會被清零,所以得到0x4012a6這個值。

如果把 0xff 作為第二個字節的跳轉距離,這是一個最小跳轉距離 - 1,由上圖可知,最終跳到 0x401325,也就是跳轉了 1 個字節。

如果再往回多跳轉一個字節,指令的第二個字節改為 fe,最終會跳回起點位置,從而形成一個無限循環。

image

如果將第二個字節改為 fd,從指令的結尾往回跳轉 3 個字節,最終跳到 0x401323。

image

image

使用短跳轉只能在當前地址的附近跳轉,無法跳轉到所有的地址。所以程序會使用長跳轉。

image

上圖中顯示了一些長跳轉,圖中的 loc 表示那一條指令是一般指令。

image

上圖是一個長跳轉,0x4026ae 到 0x4029b3 的距離超過了短跳轉的作用範圍。

image

跳轉範圍計算公式位:終點指令起始地址 - 起點指令起始地址 - 5

5 是跳轉指令的長度,結果是 0x300,也就是長跳轉指令操作碼 E9 後面的 dword。

image

2、有條件跳轉指令#

CMP A,B #對A和B進行比較,根據比較結果進行不同的操作

image

條件跳轉指令

上圖中,CMP 對 eax、ebx 進行比較(寄存器相減),如果它們相等,那麼結果就是 0,就觸發了標誌寄存器(EFLAGS)中 Z 標記或者 zero 標記,JZ 指令檢測到這個標記然後進行跳轉。如果觸發 Z 標記,就會執行上圖中的綠色箭頭路徑,如果沒有觸發,那麼就執行青色箭頭路徑。

16 進制ASM描述
74 or 0F84JE等於則跳轉
75 or 0F85JNE不等於則跳轉
77 or 0F87JA大於則跳轉
7CJL小於則跳轉
7DJGE不小於則跳轉
7EJLE小於等於則跳轉
7FJG大於等於則跳轉
80JO溢出則跳轉
81JNO不溢出則跳轉
82JB/JNAE低於則跳轉
83JNB/JAE不低於則跳轉
86JNA/JBE不大於等於則跳轉
88JS符號為負則跳轉
89JNS符號為正則跳轉
8CJL/JNGE小於則跳轉
8DJGE/JNL不小於則跳轉
8EJLE/JNG小於等於則跳轉
8FJG/JNLE大於等於則跳轉

除了 JMP 和 NOP 之外,剩餘的都是根據比較結果執行的條件跳轉指令。

3、CALL 和 RET 指令#

  • CALL 指令用來調用一個函數。
  • RET 指令用來返回調用這個函數的指令的下面一條指令處。

下圖中有一個 CALL 調用指令,程序將跳轉到0x4013d8去執行這個函數。 (在0x4013d8這個地址前面的sub_表示這裡是一個函數) CALL 指令會將返回的地址0x40123d保存到棧上。

image

call 指令實例

雙擊這個函數,可以跳轉到如下位置,函數具體內容如下:

image

0x4013d8 函數具體內容

如上圖所示,函數執行完畢後執行 ret 指令,跳轉到棧上保存的返回地址 0x4012d 處,就是調用這個函數指令的下一條。

image

返回地址

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。