二进制安全必备函数栈帧与反汇编全景复习笔记这份笔记为你完整还原了 C 语言源码到经典 x8632位 Intel 语法、无优化编译反汇编的映射关系包含了行级详细解析与核心复习表。你可以直接复制本段 Markdown 源码保存为本地文件方便随时复盘。 1. C 语言源代码intmain(){add(0xAA,0xBB);return0;}voidadd(intx,inty){intz0xCC;}️ 2. 反汇编代码行级详解 main 函数反汇编流; main 函数的开端 (函数序言 Prologue) push ebp ; 1. 将 main 上级函数的 EBP 压栈备份保存现场 mov ebp, esp ; 2. 让 EBP 等于当前的 ESP正式确立 main 函数自己的栈帧基准线 ; 准备参数并调用 add(0xAA, 0xBB) push 0BBh ; 3. [对应C: y 0xBB] 将第二个参数压入栈顶 (ESP ESP - 4) push 0AAh ; 4. [对应C: x 0xAA] 将第一个参数压入栈顶 (ESP ESP - 4) ; 注x86 下参数按从右往左Right-to-Left顺序压栈 call _add ; 5. [对应C: add(...)] 核心动作 ; A. 将下一行指令的地址返回地址压入栈顶 (ESP ESP - 4) ; B. 将 EIP 寄存器修改为 _add 函数的入口地址实现跳转 ; 从 add 函数返回后的清理工作 add esp, 8 ; 6. [栈平衡 Balance] 重点由调用者main亲自清理栈顶。 ; 刚才 push 了两个参数4字节 4字节 8字节 ; 这里把 ESP 加上 8强行把这两个参数从栈顶“踢除” ; main 函数的收尾 (函数尾声 Epilogue) xor eax, eax ; 7. [对应C: return 0] 清零 EAX作为 main 函数的默认返回值 pop ebp ; 8. 弹栈恢复 main 上级函数的 EBP ret ; 9. 结束 main 函数返回更上层 add 函数反汇编流_add proc near ; add 函数入口 ; 1. 函数序言 (建立专属办公室) push ebp ; 将 main 函数的 EBP 压栈备份 (ESP ESP - 4) mov ebp, esp ; 让 EBP 等于当前的 ESP。从此当前函数的 EBP 固定在分水岭位置 ; 2. 局部变量空间开辟 sub esp, 4 ; [对应C: int z] 将 ESP 减去 4在栈上强行留出 4 字节的空地给变量 z ; 3. 执行业务逻辑 (赋值) mov dword ptr [ebp-4], 0CCh ; [对应C: z 0xCC] ; 往 [EBP - 4]刚才开辟的空地写入 4 字节的常数 0xCC ; 4. 函数尾声 (拆除办公室、退租) mov esp, ebp ; 清空局部变量让 ESP 直接回到 EBP 的位置 (无视并放弃了 [EBP-4] 的空间) pop ebp ; 弹栈把刚才保存的 main 函数的 EBP 还给 EBP 寄存器 (ESP ESP 4) ; 此时 EBP 恢复为 main 的ESP 指向栈顶的返回地址 ret ; 魂归故里弹出当前栈顶的返回地址直接赋给 EIP 寄存器 ; CPU 控制权瞬间跳回 main 函数中即 call _add 的下一行 _add endp⚙️大佬敲黑板在真实的 IDA Pro 反汇编中你经常会看到编译器把add函数尾声的mov esp, ebp和pop ebp两条指令合并精简为一条著名的指令leave。它们在硬件层面上完全等价。 3. 终极复习作弊表Cheatsheet当你在汇编中看到以EBP为基准的内存寻址中括号表达式时直接套用下表进行肉眼翻译这是分析栈溢出Pwn和逆向的关键汇编表达式它的真实身份产生的原因Pwn 视角漏洞安全意义[ebp]Saved EBP旧 EBP 的备份函数序言第一步push ebp留下的。栈溢出时如果把它改掉原函数在退栈时会迷失方向导致程序崩溃SegFault。[ebp 4]Return Address返回地址call指令在跳入函数前自动强行压入的。Pwn 的终极劫持目标只要覆盖这里就能在函数执行ret时让程序跳去执行任意恶意代码如 system 逻辑。[ebp 8]第 1 个输入参数 (x)在返回地址的上方高地址由调用者提前压入。只读。改变它不会破坏栈结构但会改变函数的业务运行逻辑。[ebp 12]第 2 个输入参数 (y)在第 1 个参数的上方。多个参数以此类推16, 20…。只读。[ebp - 4]第 1 个局部变量 (z)函数内部sub esp, 4之后在低地址方向自己开辟的。溢出的源头如果这个变量是个缓冲区如char buf[16]当你输入过长数据时数据会**向上往正号/高地址方向**依次淹没[ebp]和[ebp4]返回地址。 4. 核心逻辑闭环思维导图高地址 (楼顶) | ... | [EBP 12] - 参数 2 (0xBB) --【Caller压入】 | [EBP 8] - 参数 1 (0xAA) --【Caller压入】 | [EBP 4] - 返回地址 (EIP) --【CALL指令自动压入】-- 漏洞劫持核心 | [EBP] - 旧 EBP 备份 --【Callee序言 push ebp】 | [EBP - 4] - 局部变量 z --【Callee自减开辟 sub esp】-- 溢出污染源 V 低地址 (地下室)一句话总结复习流栈是倒着长的向低地址生长输入数据是顺着写的向高地址溢出。所以位于低地址的局部变量一旦发生溢出会无情地向高地址方向横扫依次冲毁旧 EBP 和关键的返回地址。