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