笔记
学习最新前沿软件逆向安全技术、游戏安全辅助脚本技术,B 站 小迪 xiaodi 老师
微信 i-xiaodi
基本的数学运算指令
操作符 |
功能 |
示例 |
|
加法 |
|
|
减法 |
|
|
无符号乘法 |
|
|
有符号乘法 |
|
|
无符号除法 |
|
|
有符号除法 |
|
|
自增 |
|
|
自减 |
|
以下是 mul
、imul
、div
和 idiv
指令的详细讲解和代码示例。这些指令主要用于整数的乘法和除法操作,分别处理无符号和有符号数据。通过反汇编代码,我们可以更好地理解它们在汇编中的实际作用。
乘除法
1. mul
(无符号乘法)
- 功能:执行无符号整数乘法。
- 操作数:
-
- 单操作数:默认为
EAX
寄存器作为被乘数,操作数为乘数。 - 结果:
- 单操作数:默认为
-
-
- 如果是 32 位:低 32 位结果存储在
EAX
,高 32 位存储在EDX
。
- 如果是 32 位:低 32 位结果存储在
-
示例代码:
mov eax, 5 ; 被乘数
mov ecx, 3 ; 乘数
mul ecx ; 无符号乘法,EAX * ECX
; 结果存储在 EAX(低 32 位),高位结果存储在 EDX
反汇编:
00401000 B8 05 00 00 00 mov eax, 5 ; 将 5 加载到 EAX
00401005 B9 03 00 00 00 mov ecx, 3 ; 将 3 加载到 ECX
0040100A F7 E1 mul ecx ; EAX = EAX * ECX
结果:
EAX = 15
EDX = 0
(因为乘积小于 2^32,EDX 为 0)2 ^ 32
- 1
= FFFF FFFF
2. imul
(有符号乘法)
- 功能:执行有符号整数乘法。
- 操作数:
-
- 支持单操作数、双操作数或三操作数形式:
-
-
- 单操作数:默认被乘数在
EAX
。 - 双操作数:
imul dest, src
,目标寄存器存储结果。 - 三操作数:
imul dest, src, imm
,将src * imm
的结果存入dest
。
- 单操作数:默认被乘数在
-
示例代码:
mov eax, -5 ; 被乘数
mov ecx, 3 ; 乘数
imul eax, ecx ; 有符号乘法,EAX = EAX * ECX
; 结果存储在 EAX
反汇编:
00401000 B8 FB FF FF FF mov eax, -5 ; 将 -5 加载到 EAX
00401005 B9 03 00 00 00 mov ecx, 3 ; 将 3 加载到 ECX
0040100A 0F AF C1 imul eax, ecx ; EAX = EAX * ECX
结果:
EAX = -15
3. div
(无符号除法)
- 功能:执行无符号整数除法。
- 操作数:
-
- 被除数默认是
EDX:EAX
组成的 64 位整数(高 32 位在EDX
,低 32 位在EAX
)。 - 操作数为除数,结果:
- 被除数默认是
-
-
- 商存储在
EAX
- 余数存储在
EDX
- 商存储在
-
注意:需要确保 EDX
被清零(或正确设置),否则结果可能出错。
示例代码:
mov edx, 0 ; 高位被除数清零
mov eax, 15 ; 低位被除数
mov ecx, 3 ; 除数
div ecx ; 无符号除法,EAX = EAX / ECX,EDX = EAX % ECX
反汇编:
00401000 BA 00 00 00 00 mov edx, 0 ; EDX = 0
00401005 B8 0F 00 00 00 mov eax, 15 ; EAX = 15
0040100A B9 03 00 00 00 mov ecx, 3 ; ECX = 3
0040100F F7 F1 div ecx ; EAX = EAX / ECX, EDX = EAX % ECX
结果:
EAX = 5
(商)EDX = 0
(余数)
4. idiv
(有符号除法)
- 功能:执行有符号整数除法。
- 操作数:
-
- 被除数为
EDX:EAX
组成的 64 位整数(同div
)。 - 操作数为除数,结果:
- 被除数为
-
-
- 商存储在
EAX
- 余数存储在
EDX
- 商存储在
-
注意:与 div
类似,需正确设置 EDX
,且结果符号由操作数符号决定。确保 EDX 符号开启:cdq 指令
示例代码:
mov eax, -15 ; 低位被除数
cdq ; 扩展符号位到 EDX(符号扩展指令)
mov ecx, 3 ; 除数
idiv ecx ; 有符号除法,EAX = EAX / ECX,EDX = EAX % ECX
反汇编:
00401000 B8 F1 FF FF FF mov eax, -15 ; EAX = -15
00401005 99 cdq ; 扩展符号到 EDX(EDX = -1)
00401006 B9 03 00 00 00 mov ecx, 3 ; ECX = 3
0040100B F7 F9 idiv ecx ; EAX = EAX / ECX, EDX = EAX % ECX
结果:
EAX = -5
(商)EDX = 0
(余数)
总结
指令 |
类型 |
被除数 / 被乘数 |
操作数 |
商 / 结果存储位置 |
余数存储位置 |
|
无符号乘法 |
|
操作数寄存器 |
|
|
|
有符号乘法 |
|
操作数寄存器 |
根据目标寄存器 |
N/A |
|
无符号除法 |
|
除数寄存器 |
|
|
|
有符号除法 |
|
除数寄存器 |
|
|
拓展阅读
在反汇编技术和安全对抗中,mul
、imul
、div
和 idiv
指令确实存在一些针对性的使用场景,尤其在逆向工程、代码混淆、漏洞利用和恶意软件分析等领域,这些指令可以被用来达成特定目的。以下是它们的典型使用场景和在安全领域的作用
1. mul
(无符号乘法)和 imul
(有符号乘法)
典型场景
- 加密和哈希算法:
-
- 乘法指令常用于实现简单的加密或哈希算法。例如,很多哈希函数(如 CRC、FNV-1a)会使用乘法来增加数据的混淆性。
- 反汇编中分析到大量乘法时,可能意味着代码在处理数据混淆、加密或哈希操作。
- 指针计算与数组索引:
-
- 在复杂数据结构中,特别是二维数组或动态分配的数据结构,编译器可能用乘法来计算内存偏移。
- 在逆向中看到
imul
或mul
指令时,可能需要关注操作数,推断是否涉及数组或内存访问。
- 混淆和虚拟机(VM)保护:
-
- 恶意软件或受保护的程序可能会用
imul
和mul
生成复杂的数值计算路径,增加反汇编后的逻辑复杂性,使其难以理解。
- 恶意软件或受保护的程序可能会用
- 数据溢出漏洞利用:
-
- 当有符号和无符号数据混用时,乘法可能导致整数溢出(如超出 32 位范围),引发逻辑漏洞。
- 攻击者可以利用这一点,在输入数据时精心构造数值,导致计算结果异常。
对抗分析
- 如果乘法用于混淆,在逆向中需要分析乘法结果的具体意义。
- 通过数据追踪和解密算法复现,逆向分析人员可以还原加密或混淆逻辑。
2. div
(无符号除法)和 idiv
(有符号除法)
典型场景
- 数据格式化与解析:
-
- 除法常用于数据格式化(如时间戳计算、文件偏移计算)。例如,从字节流中解析结构化数据时,除法用于拆分字段。
- 反汇编时,看到
div
或idiv
时,可能需要检查是否在处理协议数据或文件格式。
- 计算模块与循环控制:
-
div
和idiv
常用于模运算。例如,程序可能通过div
或idiv
提取数组索引或检查数据对齐性。- 攻击者可利用这一点构造特定输入,破坏程序逻辑。
- 触发除零漏洞:
-
- 安全漏洞利用:如果程序没有检查除数是否为零,攻击者可以提供特定输入,触发除零异常,导致程序崩溃或执行异常。
- 在逆向中,分析除法操作的除数来源是否可控,是定位潜在漏洞的重要方法。
- 指令执行时间攻击:
-
- 除法操作比其他算术操作(如加法、乘法)耗时更多。攻击者可能通过分析程序的执行时间,推断关键数据(如密码或密钥)。
- 代码混淆与陷阱:
-
- 有时恶意软件会用故意复杂的除法操作混淆逻辑。例如,通过嵌套多层除法,将简单的逻辑包装成看似复杂的操作。
对抗分析
- 动态分析:在调试环境中检查除法操作的输入数据,尤其是除数,确定是否存在溢出或异常。
- 解混淆:对于混淆代码,可以通过符号执行或数学化简,还原原始逻辑。
3. 在恶意软件与反调试中的作用
反调试检测
- 恶意软件可能利用
idiv
触发异常的特性来检测调试环境:
-
- 在调试器运行时,程序故意用
idiv
执行除零操作。如果调试器没有正确处理异常,程序会进入异常处理流程,进而检测到调试器存在。 - 示例:
- 在调试器运行时,程序故意用
xor eax, eax ; 设置被除数为 0
idiv ecx ; 故意执行除零操作
; 如果被调试器捕获,进入异常处理逻辑
混淆代码生成
- 恶意软件使用
imul
和div
生成复杂的数学路径,例如:
mov eax, key
imul eax, 0x1337
div ecx
-
- 这种操作隐藏了关键数据(如
key
),让逆向分析更困难。
- 这种操作隐藏了关键数据(如
4. 逆向与安全对抗中的分析重点
- 操作数追踪:
-
- 关注乘法和除法指令的操作数,明确数据来源(常量、寄存器、内存地址)。
- 在工具(如 IDA Pro、Ghidra)中,通过符号追踪明确值的意义。
- 异常处理逻辑:
-
- 分析代码是否对除法异常(如除零)有特定处理逻辑,结合反调试场景加以分析。
- 混淆逻辑解读:
-
- 尝试用数学化简方法,解读乘法和除法结果。例如,
mul
和div
的链式调用通常可以还原为简单的代数表达式。
- 尝试用数学化简方法,解读乘法和除法结果。例如,
- 溢出检测:
-
- 如果存在
mul
和imul
操作,检查高位结果(EDX
)是否被使用或丢弃,判断是否可能导致整数溢出。
- 如果存在
5. 案例总结
以一个恶意软件的混淆示例为例:
mov eax, 0x1234
imul eax, 0x5678
div ecx
在代码中,imul
和 div
配合实现了数据混淆。在反汇编中,我们可以:
- 动态调试,检查寄存器值在每条指令执行后的变化。
- 解混淆,通过将
imul
和div
的操作还原为代数公式,简化逻辑。
总结
mul
、imul
、div
和 idiv
在反汇编技术和安全对抗中,既可以作为分析目标,也能用作保护手段:
- 攻击者可能利用它们的异常特性(如除零)或溢出特性来制造漏洞或反调试逻辑。
- 恶意软件可能使用这些指令混淆数据流,隐藏真实逻辑。
- 逆向工程师需要通过静态和动态分析工具,还原这些指令的逻辑和用途,从而解读隐藏意图。
对这些指令的深入理解,是掌握反汇编技术和安全对抗的关键环节!