002、基本数据类型的表现形式
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:全书总览 · 上一章:工具与环境 · 下一章:启动函数与用户入口
类型不会完整保存在机器代码里反汇编通常只能直接告诉我访问宽度和指令语义,不能自动还原源码类型。
1mov eax, dword ptr [ebp+8]
这里只能确定读取 4 Byte。它可能是 int、unsigned int、指针、枚举或浮点数的原始位模式,必须结合后续使用判断。
类型恢复是一组证据的交叉验证,不是由单条 MOV 指令决定。
整数与符号有符号和无符号整数采用相同位模式,差异体现在解释和指令选择上。
线索
有符号倾向
无符号倾向
扩展
MOVSX
MOVZX
除法
IDIV
DIV
乘法
IMUL
MUL
大小比较
JL/JG
JB/JA
整数溢出时:
CF 主要描述无符号进位或借位。
OF 主要描述有符号结果超出范围。
浮点数浮点数采用 IEEE 754 编码。常见观察点:
x8 ...
001、熟悉工作环境和相关工具
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:全书总览 · 下一章:基本数据类型
工具不是主角逆向分析的主线是提出假设并验证,工具只是观察程序的不同窗口。
工具
主要用途
适合回答的问题
Visual Studio
编译、源码调试、查看编译器输出
一段 C++ 会生成什么代码
GCC / MinGW
对比不同编译器和 ABI
同一语法在不同工具链下是否相同
OllyDbg
经典 32 位用户态动态调试
指令执行时寄存器和栈如何变化
x64dbg
x86/x64 用户态动态调试
断点、模块、内存和调用跟踪
WinDbg
用户态、内核态和转储分析
异常、线程、符号和系统结构
IDA
静态反汇编、函数识别、交叉引用
程序整体结构和调用关系是什么
静态分析负责建立全局地图,动态调试负责验证某一次真实执行。
建议实验矩阵同一份最小代码至少保留四个构建:
12x86 Debug x86 Re ...
000、《C++反汇编与逆向分析技术揭秘》读书笔记总览
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:读书拾贝 · 知识库首页
这组笔记怎么用这组内容以第二版 18 章目录为骨架,属于我阅读前使用的结构化底稿。笔记不是原书正文的替代品,也不代表作者原话;阅读时需要结合书中示例、自己的编译结果和调试记录不断修正。
最有效的阅读方法是:先读一节,再亲自编译最小示例,最后关闭源码只看反汇编复述语义。
推荐每章完成四轮:
看目录和本章问题,建立预期。
阅读原书,标记与笔记不一致或遗漏之处。
使用 Debug、Release、x86、x64 四种组合观察差异。
把自己的截图、地址变化和结论补回笔记。
正版电子书
得到电子书:第2版
当当云阅读:第1版
豆瓣阅读:第1版
公开笔记与校对资料这些资料主要用于交叉核对章节结构、实验思路和旧版反汇编现象,不直接复制原文。多数内容基于第 1 版、VC6 或 32 位环境,阅读时需要结合当前编译器重新验证。
Aye’s house:第5~10章整合笔记
博客 ...
019、逆向—调试回溯与函数分析
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:CALL/RET 与函数调用
从栈帧回溯调用关系函数分析的核心不是只读当前函数,而是回答三个问题:
谁调用了它?
参数从哪里来?
返回后数据流向哪里?
在传统 x86 栈帧中,可以从当前 EBP 读取上一层栈帧和返回地址:
123[EBP] → 上一层 EBP[EBP+4] → 返回地址[EBP+8] → 第一个栈参数
沿着保存的 EBP 逐层查看,可以恢复一条基本调用链。
返回地址落在哪个模块、哪个函数附近,是判断调用来源的重要依据。
模块、地址与符号调试器中的地址只有和模块基址、符号信息结合后才更有意义。
1实际地址 = 模块基址 + RVA
例如某函数位于:
1demo.exe + 0x1230
即使 ASLR 使模块每次加载到不同位置,RVA 通常仍能帮助定位同一段代码。
符号信息可能提供:
函数名和源码文件。
局部变量和参数名。
源码行与机 ...
018、堆栈—CALL/RET 与函数调用
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:线程栈与 PUSH/POP · 下一节:调试回溯与函数分析
CALL 做了什么CALL 的核心动作不是单纯跳转,而是:
保存下一条指令的地址,也就是返回地址。
把执行流转移到目标函数。
可以近似理解为:
12push 下一条指令地址jmp 目标函数
识别函数调用时,返回地址是串联调用者与被调用函数的关键证据。
直接调用与间接调用E8 相对调用常见的 E8 rel32 使用有符号相对位移:
1目标地址 = CALL 下一条指令地址 + 有符号 rel32
例如调试器把某条指令显示为:
100401000 E8 2B000000 call 00401030
CALL 长度为 5 字节,下一条指令地址是 00401005,再加相对位移得到目标地址。
FF 间接调用FF /2 形式从寄存器或内存中取得目标地址:
12call eaxcall dword ptr [004 ...
017、堆栈—线程栈与 PUSH/POP
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:位运算与操作数 · 下一节:CALL/RET 与函数调用
线程栈是什么每个线程都拥有自己的栈空间。函数参数、返回地址、局部变量以及部分需要临时保存的寄存器,都会在函数调用过程中进入线程栈。
栈是一段按照后进先出规则使用的内存,栈顶地址由 ESP/RSP 记录。
在 32 位程序中,常见的两个栈相关寄存器是:
寄存器
作用
ESP
指向当前栈顶
EBP
传统栈帧中作为当前函数的基准地址
在 64 位程序中,它们对应 RSP 和 RBP。
Windows 用户态程序的栈通常从较高地址向较低地址增长。因此,压栈会让栈指针减小,出栈会让栈指针增大。
1234567891011高地址┌─────────────────┐│ 调用者的数据 │├─────────────────┤│ 返回地址 │├──────────────── ...
016、指令—位运算与操作数
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:加减乘除基础 · 下一节:线程栈与 PUSH/POP
位运算的观察方式位运算直接对二进制位进行处理。逆向时不必先把所有数转换成十进制,使用十六进制观察掩码通常更直观。
120x5A = 0101 10100x0F = 0000 1111
AND:保留或清零只有两个对应位都为 1,结果位才为 1。
12mov al, 5Ahand al, 0Fh ; AL = 0Ah
12340101 10100000 1111--------- AND0000 1010
常见用途:
通过掩码保留指定字段;
清除某些位;
对齐地址,例如 and eax, 0FFFFFFF0h;
配合后续跳转判断标志状态。
OR:设置指定位只要有一个对应位为 1,结果位就为 1。
1or eax, 00000004h ; 把 Bit 2 设为 1,其他位保持不变
常用于启用选项、组合权限或设置 ...
015、指令—加减乘除基础
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:段定义与程序入口 · 下一节:位运算与操作数
加法指令ADD1add destination, source
ADD 执行普通加法,结果写回目标操作数,并更新 CF、OF、SF、ZF、AF、PF 等状态标志。
12mov al, 0FFhadd al, 1 ; AL = 00h, CF = 1, ZF = 1
这里按无符号数解释发生进位,所以 CF = 1;按 8 位有符号数解释,-1 + 1 = 0,没有有符号溢出。
ADC1adc destination, source
实际计算:
1destination = destination + source + CF
ADC 用于处理超过寄存器宽度的多精度加法。
123; EDX:EAX + ECX:EBXadd eax, ebxadc edx, ecx
低 32 位产生的进位通过 CF 传递给高 32 位。
I ...
014、框架—段定义与程序入口
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:C 语言与汇编程序框架 · 下一节:加减乘除基础
为什么要划分段程序中的代码、只读常量和可写变量具有不同用途与权限。汇编源文件通过段声明组织内容,链接器再把它们合并到 PE 的相应节区中。
MASM 声明
常见内容
典型属性
.code
机器指令
读、执行
.data
已初始化可写数据
读、写
.data?
未初始化数据
读、写
.const
只读常量
读
123456789101112131415.data counter dd 1.data? buffer db 100h dup(?).const message db "hello", 0.codemain proc inc counter retmain endpend main
源代码里的“段”与 PE 文件里的“节”在语境上经 ...
013、框架—C 语言与汇编程序框架
🎨 颜色标记说明
粉色:特别重要、主线必掌握、优先复盘的内容。
蓝色:核心概念、术语、分类名。
橙色:需要关注的边界、易错点、注意事项。
绿色:解释类内容、帮助理解知识点。
返回:网络安全知识库 · 上一节:内存读写与寻址 · 下一节:段定义与程序入口
从 C 程序看执行框架一个最小 C 控制台程序看起来只有 main:
1234567#include <stdio.h>int main(void){ puts("Hello, reverse!"); return 0;}
但生成 EXE 后,操作系统通常不会直接跳到源码中的 main。在使用 C 运行库时,大致流程是:
123456Windows Loader -> PE 入口点 -> CRT 启动代码 -> 初始化运行库与全局对象 -> 调用 main -> 处理返回值并结束进程
源码入口 main 与 PE 入口点 OEP 不是同一个概念。逆向时经常需要从启动代码继续跟踪,才能定位真正的业务函数。
...














