如何在二进制文件中定位使用特定字符串的函数位置
定位二进制中引用特定字符串的函数——解决静态地址与运行时地址差异问题
这种情况在二进制逆向分析里太常见啦!你猜的没错,核心问题就是二进制文件里的静态文件偏移和程序运行时的虚拟地址(VA)完全不是一回事,尤其是带ASLR(地址空间布局随机化)或者编译成位置无关代码(PIC/PIE)的程序,静态偏移和实际运行地址之间差了一个加载基地址。下面给你几个一步步解决的实用方法:
1. 先搞清楚二进制文件的加载属性
首先得确认你的目标文件是不是位置无关可执行文件,这决定了地址计算的方式:
- 用
file命令快速查看:file your_target_binary,如果输出里包含"Position-Independent Executable",那就是PIE程序,运行时会随机分配加载基址;如果是普通ELF,基址通常是固定的(比如0x400000)。 - 用
readelf -h your_target_binary查看ELF头部信息,重点看Entry point address和Start of program headers,能帮你了解默认的加载基址(无ASLR时的地址)。
2. 计算字符串的运行时虚拟地址(VA)
你已经找到了字符串在文件中的静态偏移(file offset),接下来要把它转换成程序运行时的虚拟地址:
- 用
readelf -S your_target_binary查看段表,找到包含该字符串的段(绝大多数情况是.rodata只读数据段)。 - 记下这个段的两个关键值:
Offset(段在文件中的起始偏移)和VirtAddr(段加载到内存后的起始虚拟地址)。 - 用公式计算字符串的VA:
举个实际例子:如果字符串VA = 段的VirtAddr + (字符串的文件偏移 - 段的Offset).rodata段的Offset是0x1000,VirtAddr是0x555555556000,你找到的字符串文件偏移是0x1234,那最终VA就是0x555555556000 + (0x1234 - 0x1000) = 0x555555556234。
3. 用逆向工具搜索引用
现在有了正确的虚拟地址,就可以用逆向工具找到所有引用它的指令了,推荐几个常用工具的操作方式:
- radare2(免费开源):
- 加载文件:
r2 your_target_binary - 运行全量分析:
aaa - 查看字符串的VA:
x 0x555555556234(替换成你的VA) - 搜索所有引用:
axt 0x555555556234,结果里就能看到引用这个字符串的指令地址,跳转到对应的地址就能找到目标函数。
- 加载文件:
- Ghidra(免费开源):
- 导入二进制文件后,先运行
Auto Analysis(自动分析)。 - 在左侧
Data Manager里找到.rodata段,定位到你找到的字符串。 - 右键点击字符串,选择
Find References to,工具会自动列出所有引用该字符串的指令,点击就能跳转到对应的函数。
- 导入二进制文件后,先运行
- IDA Pro(商用):
- 导入文件后等待自动分析完成。
- 找到字符串的位置,右键选择
Cross references to(或者按Ctrl+X),就能看到所有引用该字符串的位置,进而定位到目标函数。
4. 特殊情况处理
如果上面的方法还是找不到,可能是以下情况:
- PIC程序的相对寻址:引用字符串的指令用的是RIP相对寻址(比如
lea rdi, [rip+0x123]),这种情况下静态搜索绝对地址肯定找不到,必须依赖逆向工具的分析功能——工具会自动计算RIP相对地址对应的实际VA,帮你关联到字符串。 - 运行时解密的字符串:如果字符串是加密后存储在二进制里,运行时才解密,那静态文件里的内容是加密后的,你需要用动态调试工具(比如GDB)在程序运行时找到解密后的字符串VA,再搜索引用。
内容的提问来源于stack exchange,提问作者Anonymous1847
相关产品推荐
相关产品推荐

