ELF 结构的工具链与取舍
.plt 与 .got 支撑延迟绑定,函数第一次被调用时才把真实地址写进 GOT
工具解决的是「看得见」的问题,判断还是要靠人。
先说结论
工具要少而熟。
- 静态:看结构
- 动态:看数据
- 辅助:做批量
- 先用熟的描述问题
- 效率来自脚本
三类工具
按这个分工选:
程序头表决定加载时的内存映射,节区头表只在链接与调试时有意义,可以完全剥离。
| 类别 | 代表 | 强项 |
|---|---|---|
| 静态 | 反汇编器/反编译器 | 结构与逻辑 |
| 动态 | 调试器 | 真实数据与分支 |
| 辅助 | 脚本与插件 | 批量与自动化 |
怎么选
.plt 与 .got 支撑延迟绑定,函数第一次被调用时才把真实地址写进 GOT。
先用最熟的那个把问题描述清楚,再换工具验证。
几个具体经验
下面这些是相对确定的细节:
- 静态链接会把 libc 打进二进制,体积 800KB 起步,符号信息也完整得多

别做的事
拿节区头表判断加载布局,遇到剥过的样本直接读不出。
换工具不能代替思考,只会让你更晚发现问题。
一句提醒
先看程序头表再谈其它,加载视图才是运行时的真相。
工具链稳定下来之后,效率提升来自脚本,不来自新工具。
还有几处容易忽略的
这些细节不影响入门,但影响你判断的准确度。
- ELF 的入口是 _start 而不是 main,main 由 libc 的启动代码在初始化之后调用
- strip 只删掉符号表,字符串常量与调用结构依然可读,分析成本没有想象中高
- PIE 让装载基址随机化,但函数之间的相对偏移与调用关系完全不变,分析时按偏移定位而不是记地址
- 把 e_entry 当成 main,跟进去发现是启动代码
- 以为 strip 过的二进制就没法分析了
工具是手脚,判断是脑子。
评论 (3)
终于有人讲清楚「为什么」而不是只给命令。
审计检查点可以直接做成 checklist。
补一句:修完要回归,很多人修一半。
发表评论