反汇编基础速记
学习笔记。一份 x64 寄存器的"点名册",按反汇编时的重要性分三层。 快照背景:x64dbg 程序刚加载、还没执行任何指令时的全 0 状态。
第一层:必须滚瓜烂熟(反汇编里天天见)
通用寄存器
| 寄存器 | 角色 | 反汇编里的典型出现 |
|---|---|---|
| RAX | 累加器 | 函数返回值 ;乘除隐含操作数;xor eax,eax 清零 |
| RBX | 基址 | 被调用者保存;跨函数保留的变量 |
| RCX | 计数 | 第 4 个参数 ;rep 循环计数;移位量 |
| RDX | 数据 | 第 3 个参数 ;imul/idiv 高位结果 |
| RSI | 源索引 | 第 2 个参数 ;movs/lods 源地址 |
| RDI | 目的索引 | 第 1 个参数 ;stos/scas 目的地址 |
| RBP | 基址指针 | 栈帧基址 ;[rbp-8] 是局部变量 |
| RSP | 栈指针 | 栈顶 ;push/pop/call/ret 自动改它 |
x64 调用约定速记 :RDI, RSI, RDX, RCX, R8, R9 = 第 1~6 个参数,返回值在 RAX。
指令指针
| 寄存器 | 角色 |
|---|---|
| RIP | 下一条要执行的指令地址,反汇编"当前行"就是它 |
标志寄存器 RFLAGS
| 标志 | 名字 | 什么时候被看 |
|---|---|---|
| ZF | 零标志 | cmp 后 je/jne;test eax,eax 判 0 |
| CF | 进位/借位 | 无符号比较 ja/jb;加法溢出 |
| SF | 符号标志 | 有符号比较 jg/jl;正负 |
| OF | 溢出标志 | 有符号运算溢出;jo/jno |
| PF | 奇偶标志 | 很少用 |
| DF | 方向标志 | movs/stos 向前向后(cld/std) |
| IF | 中断允许 | 内核态才关心,用户态基本恒 1 |
| TF | 单步陷阱 | 调试器单步执行靠它 |
| AF | 半进位 | BCD 用,现代代码基本不看 |
第二层:知道用途,不用死记
x64 新增的 R8~R15
| 寄存器 | 角色 |
|---|---|
| R8, R9 | 第 5、第 6 个参数 |
| R10, R11 | 调用者保存的临时寄存器,syscall 前后常用 |
| R12~R15 | 被调用者保存,长生命周期变量 |
段寄存器
| 寄存器 | 64 位模式下的作用 |
|---|---|
| CS | 代码段,基址恒 0,基本只看权限级 |
| DS/ES/SS | 数据/附加/栈段,64 位下平坦化,基本是摆设 |
| FS | Windows x64 指向 TEB;fs:[0x30] 指向 PEB |
| GS | Linux x64 的 TLS 基址 |
反汇编里看到 fs:[0x30] 或 gs:[0x28],就是访问线程/进程环境块或栈保护 cookie。
SSE/AVX 寄存器 XMM0~XMM15
| 用途 | 说明 |
|---|---|
| 浮点参数 | x64 ABI 用 XMM0~XMM3 传前 4 个浮点参数 |
| 浮点返回值 | 在 XMM0 |
| 数据搬运 | movaps/movups/movdqa 搬 128 位数据 |
| 整数 SIMD | paddb/pmulld 等 |
注意:标准 x86-64 只有 XMM0
XMM15,XMM16XMM31 是 AVX-512 才有。
MxCsr
SSE 的控制/状态寄存器,管浮点舍入模式、异常掩码和标志。看到 ldmxcsr/stmxcsr 就是它在被读写。
第三层:看得到,但现在可以完全忽略
x87 浮点栈 ST(0)~ST(7)
历史遗留的 x87 协处理器寄存器,8 个 80 位寄存器组成栈。现代编译器基本不用(除非 long double 或老代码)。
- 看到
fld/fstp/faddp/fmul这类f开头指令才是 x87 x87TagWord/x87ControlWord/x87StatusWord是它的控制/状态字- 学反汇编这部分可以先跳过
调试寄存器 DR0~DR7
| 寄存器 | 作用 |
|---|---|
| DR0~DR3 | 硬件断点地址(最多 4 个) |
| DR6 | 断点触发状态 |
| DR7 | 断点使能、类型(读/写/执行)、长度控制 |
x64dbg 下"硬件断点",底层就是往 DR0~DR3 写地址、往 DR7 写控制位。软件断点(int3/0xCC)不占这 4 个槽位。
LastError / LastStatus
- LastError :调试器缓存的
GetLastError()值 - LastStatus:最近一次异常/NTSTATUS 状态码
排查 Windows API 调用失败时有用,平时不用管。
学习优先级建议
| 优先级 | 寄存器 | 理由 |
|---|---|---|
| P0(条件反射) | RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, RIP, RFLAGS(ZF/CF/SF/OF) | 反汇编 90% 代码都在这上面转 |
| P1(知道角色) | R8 |
x64 参数传递、TLS、浮点 ABI |
| P2(用到再查) | DR0~DR7, MxCsr | 下硬件断点、调浮点异常时查 |
| P3(直接跳过) | ST(0)~ST(7), x87 全部字段 | 现代代码基本不碰 |
一句话总结
反汇编时要盯死的是:RAX (返回值)、RDI/RSI/RDX/RCX/R8/R9 (参数)、RBP/RSP (栈帧)、RIP (当前指令)、RFLAGS 的 ZF/CF/SF/OF (条件跳转依据)。R8
R15 和 XMM 是 x64 新增,FS/GS 管 TLS,DR0DR7 是硬件断点的物理载体,x87 的 ST(0)~ST(7) 是上世纪遗产,可以直接忽略。