如何以编程方式识别二进制调用约定?

逆向工程 C++ 调用约定
2021-06-19 22:16:23

我在检测剥离的二进制文件时遇到了问题;我不知道main(). 但是总是有一个init(), 和init()调用libc_start_main(),它接收一个指向 main 的指针。

如果我可以用分析代码检测 libc 来拦截参数,那么我可以检索该地址并在那里放置另一个 pin 回调,以便我可以获取它的参数。问题是,我不知道调用约定是什么;我在想,如果我可以将其归结为调用约定的问题,那么我会为任何函数执行此操作。我确实注意到它gdb知道 的调用约定libc_start_main(),实际上它非常好,它也知道参数的顺序。

我确实读过一篇关于 stackoverflow 的简短说明,该说明指出函数的名称会产生调用约定:«如何找到第三方 dll 的调用约定?»

如果无法以编程方式知道调用约定,那么对于创建 libc 的本地构建以便能够强制执行特定调用约定的意见是什么__libc_start_main()……你看我的思路。有没有人认为这是一种更好的方法,而不是在一般情况下解决它?

2个回答

既然你提到了__libc_start_main,你似乎只需要担心 Linux。在这种情况下,调用约定是已知和固定的在大多数情况下,它将是SystemV ABI或类似的。

我发现(至少在 Linux 上)拦截 _init 是可靠的,并且从堆栈指针的常量偏移量中读取是非常可靠的。我最终生产了一个可以做到这一点的 pintool。