banner
lca

lca

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

《從零開始學IDA逆向》學習筆記-6(整數與邏輯運算)

image

6.1 整數運算指令#

ADD#

ADD A,B指令將 B 的值與 A 相加,並將結果保存到 A。A 可以是一個寄存器或者記憶體值。B 可以是一個寄存器、一個常數或者記憶體值。在同一條指令中,A 和 B 不能同時是記憶體值。

image

add 文本搜索結果

在上圖中,有很多 ADD 指令的實例,在這些例子中第一個操作數是寄存器,第二個操作數是常數,那麼在程序運行時,常數加寄存器值的結果將保存回這個寄存器當中。

image

實例 1 寄存器加常數

在上圖中,如果ECX = 10000,加上常數 4, 結果是 10004,結果重新保存到ECX當中。

image

實例 2 記憶體值加常數

上圖中,ADD 指令將在ECX+30指向地址存儲的值上加上0xffffffff常數,如果程序對這個地址有寫入權限的話,計算結果也會傳回存儲在這個地址上。假設ECX = 0x10000那麼加上 30 就是0x10030,如果這個地址保存的數是 1, 加上常數0xffffffff也就是 - 1, 結果是 0 並且保存到0x10030地址上。

image

實例 3 寄存器相加

上圖中,兩個寄存器相加的結果保存到 eax 中。ADD 指令另外也可以對 16 位和 8 位寄存器進行操作。

例如:

ADD AL,8
ADD AX,8
ADD BX,AX
ADD byte ptr ds: [EAX],7 # 在EAX指向的字節上加上7,並且保存在同一地址。

ADD 指令的操作數只要 A 不是常數,或者 A、B 都是記憶體值,其他寄存器、記憶體的組合都是允許的。

SUB#

SUB A,B這個指令和ADD指令一致,只不過它是對兩個操作數相減,最後結果保存到 A。SUB 允許的操作数组合和 ADD 是一樣的。

image

實例 1 sub 搜索結果

INC & DEC#

INC ADEC A指令對一個寄存器或者記憶體值 ±1。這是加減操作的一個特例。一般這兩個指令用來對計數器 ±1。

image

IMUL#

IMUL 是帶符號整數乘法指令,這裡介紹兩種使用方式。
IMUL A,BIMUL A,B,C

  • 第一種對 A 和 B 相乘,結果返回給 A
  • 第二種方式對 B 和 C 相乘,將結果返回給 A。

在這兩種方式下,A 只能是一個寄存器,B 可以是寄存器或者記憶體值 (第一種方式下可以是常數) , 而 C 只能是個常數。

例如:

Imul eax, [ecx] 
Imul esi, edi, 25

image

實例 1 imul 使用指令

上述只有一種使用方法,對兩個操作數相乘並把結果保存到第一個操作數中。

IDIV#

IDIV A指令中,僅僅指定了除法的除數。被除數沒有指定,因為存放的地方是固定的。

Dividend (D) ➗ divider (d) = quotient (q)
Dividend (D) 是被除數,divider (d) 是除數,quotient (q) 是除法的結果,也就是商。

在 32 位運算中,EDX 和 EAX 組成一個 64 位數,EDX 在高位,EAX 在低位,這個 64 位數除以 A 後,商返回給 EAX,餘數返回給 EDX。

實例 1 IDIV 使用實例

上圖中,假如 EAX=5,EDX=0,ECX=2,那麼 5➗2 的結果是 2,保存導 EAX 中,餘數 1 保存到 EDX 中。

如果 A 十個記憶體值也是一樣,EDX被 A 除,商返回給 EAX,餘數返回給 EDX。

6.2 邏輯運算指令#

首先是 AND (按位與) 、OR (按位或) 和 XOR (異或) 運算。

AND A,B 對 A 和 B 進行與運算,將最終結果保存到 A。對於 OR 和 XOR 運算也是一樣的。

image

A 和 B 可以是寄存器或者記憶體值,但同一條指令中 A 和 B 都是記憶體值是不允許的。

XOR#

最常用的例子對同一個寄存器 XOR (異或) 運算,將它的值清零。例如XOR EAX,EAX或者其他寄存器將清零,XOR (異或) 運算的真值表上圖。對同一個數進行異或運算結果都是 0,操作是在二進制模式下進行的。

在 16 進制下也可以進行異或操作,在 python 中異或用符號^表示,兩個相同的值異或最後結果為 0。

image

AND#

and eax,0xf

0xf 二進制表示位 1111。

image

由於 0xf 最後 4 位為 1,eax 的最後 4 位保持不動,其他位全部變成 0,通過這種方式留下了 eax 最後 4 位,並對其他位進行清零。

image

and 在 python 中用 & 符號進行表示,上圖中的結果為 0b111,也就是最低位的 4 個 bit。

OR#

OR 運算在 Python 中是 “|” 符號。

image

NOT#

NOT A將 A 所有的位取反然後保存到 A。Python 中按位取反是~符號。對於 0101,結果會對每一位取反。所有的 0 反轉為 1,1 反轉為 0。

image

實例 1 對 0b0101 取反

image

實例 2 結果位 0b1010

NEG#

NEG A將 A 轉變成 - A。NEG 運算和按位取反不一樣,按位取反多減了 1。

在 python 中使用 NEG 可以取反後再加 1。

image

SHL#

SHL A,B

SHR A,B 中 A 是一個寄存器或記憶體值,B 是一個常數或者一個 8 位寄存器。 這兩個指令將操作數按位向左或向右偏移,缺少的位用 0 來填補,舉個例子,例如 - 1。

image

實例 1 -1 的二進制

執行 SHL 2 之後,如下圖所示。

image

當這些比特向左偏移時,最左邊的 2 個比特被丟棄,右側的 2 個比特用 0 表示。

image

對於 SHR 來說也是一樣的,這些比特向右偏移,右側的比特被丟棄,左側的空位用 0 來填充。

還有 2 個類似的指令 ROL 和 ROR,指令會將每個比特移動一定的位置,但是一端超出的字節會返回給另一端,指令對每個比特進行了偏移但不改變內容。

image

本章主要介紹了匯編語言中的整數和邏輯運算指令,夯實一些基礎。

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