016、指令—位运算与操作数
返回:网络安全知识库 · 上一节:加减乘除基础 · 下一节:线程栈与 PUSH/POP
位运算的观察方式
位运算直接对二进制位进行处理。逆向时不必先把所有数转换成十进制,使用十六进制观察掩码通常更直观。
1 | 0x5A = 0101 1010 |
AND:保留或清零
只有两个对应位都为 1,结果位才为 1。
1 | mov al, 5Ah |
1 | 0101 1010 |
常见用途:
- 通过掩码保留指定字段;
- 清除某些位;
- 对齐地址,例如
and eax, 0FFFFFFF0h; - 配合后续跳转判断标志状态。
OR:设置指定位
只要有一个对应位为 1,结果位就为 1。
1 | or eax, 00000004h ; 把 Bit 2 设为 1,其他位保持不变 |
常用于启用选项、组合权限或设置标志字段。
XOR:翻转与清零
对应位不同则为 1,相同则为 0。
1 | xor eax, eax ; EAX = 0 |
xor reg, reg 是常见的寄存器清零方式。它会把 ZF 置 1,并把 CF、OF 清零。
不能把任意 XOR 都理解成加密。XOR 既可用于普通掩码,也可用于校验、混淆和加解密,必须结合数据来源和循环结构判断。
NOT:逐位取反
1 | not eax |
每一位 0 变 1、1 变 0。NOT 不修改标志寄存器。
1 | 0000 1111 -> 1111 0000 |
四种掩码操作
假设 flags 中 Bit 3 表示某个开关:
1 | ; 设置 Bit 3 |
看到 AND/OR/XOR + 常量 时,优先把常量写成二进制,观察哪些位被保留、设置或翻转。
对标志位的影响
AND、OR、XOR 通常具有以下效果:
CF = 0;OF = 0;- 根据结果更新
SF、ZF、PF; AF的结果未定义。
NOT 不影响标志位。
操作数类型
汇编指令中的操作数可以来自不同位置:
| 类型 | 示例 | 说明 |
|---|---|---|
| 立即数 | 10h |
编码在指令中的常量 |
| 寄存器 | eax |
CPU 内部存储位置 |
| 内存 | [ebx+4] |
通过有效地址访问内存 |
| 隐式操作数 | EAX、EDX、ESP 等 | 由特定指令固定使用 |
1 | mov eax, 10h ; 寄存器 <- 立即数 |
操作数组合限制
大多数普通双操作数指令不允许两个显式操作数同时是内存:
1 | ; 不可直接这样写 |
目标与源的宽度也应匹配,否则汇编器无法确定编码,或数据会发生截断。
逆向中的典型模式
判断奇偶
1 | and eax, 1 |
结果为 0 表示原值最低位为 0,也就是偶数;结果为 1 表示奇数。
清除低位实现对齐
1 | and eax, 0FFFFFFF0h |
低四位被清零,结果向下对齐到 16 的倍数。
提取字段
1 | mov eax, [flags] |
先保留 Bit 4~7,再右移到最低位,得到一个 4 Bit 字段。
学习检查清单
| 检查项 | 状态 |
|---|---|
| 能用 AND 清位、OR 置位、XOR 翻转 | 待复盘 |
| 记得 NOT 不修改标志位 | 待复盘 |
| 能区分立即数、寄存器、内存和隐式操作数 | 待复盘 |
能识别 xor reg, reg 清零模式 |
待复盘 |
| 能从掩码常量推断程序关注的位 | 待复盘 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!












