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

本章主要介绍了汇编语言中的整数和逻辑运算指令,夯实一些基础。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。