我在当前的项目中遇到了这个问题,这需要在二进制级别对代码进行推理。
我认为我们可以通过查看 CALL 指令的操作数来确定程序中所有函数的起始位置。 有了这个列表后,我们是否可以通过简单地向后搜索直到找到起始地址来确定哪个函数包含一个地址? IE是包含指令的函数的起始地址小于指令地址的最大函数地址?
如果上述方法不正确,是否有其他方法可以找到包含指令的函数的起始地址?
编辑: 添加了问题的澄清。
编辑2: 我的方法可能是错误的。 编译器不能保证将函数体放置在机器代码的连续区域中。
你需要更多地限制你的问题空间。即使仅局限于“编译语言的输出”,现在的编译器也擅长模糊函数之间的界限。内联意味着一个函数可以包含在另一个函数中。尾部调用优化无需
CALL
指令即可在两个函数之间转移控制。配置文件引导的优化可以创建不连续的函数。代码流分析和noreturn
提示可能会导致代码陷入数据。跳转表意味着数据可以在没有 CALL
目标的情况下进入代码。唯一可靠的方法是让编译器显式告诉您指令到函数的映射,例如通过调试信息。您没有说您使用什么平台,所以很难提供更具体的信息。
不,汇编代码可以做各种奇怪的事情。 一个调用可能会完全跳过另一个函数、向后跳转或进入另一个模块。