我有一个(相对较大的)静态二进制文件,我想用另一个函数替换其中一个函数。鉴于函数的复杂性,我想使用C和gcc编译剪接函数,然后只需替换代码即可。为了使其有效运行,我需要以某种方式强制执行函数和我将访问的某些全局变量位于特定偏移量处。如何使用gcc和ld完成这项工作?
一个非常简单的示例-给出这样的程序:
编译和反汇编此函数产生以下结果:
请注意:
- 全局变量的地址为0x600918 - get_global函数的地址为0x4004ad
基本上,问题是:如何使用gcc和ld为一个函数生成代码,使其能够:
- 引用全局变量和/或函数确切地在上述地址处 - 从我想要它开始(我特别感兴趣的是从地址0x4004ad开始,这样它就可以潜在地用于覆盖现有的get_global实现)
我认为可能可以通过一些指定给函数原型和/或全局变量的编译器特定属性或编译指示来实现,实际上,gcc有一些变量属性控制函数/变量在某些部分的打包和放置, 但无法指定固定的地址。
我强烈怀疑可以通过手动调用
肯定相关:C中的固定地址变量
一个非常简单的示例-给出这样的程序:
int global = 42;
int get_global() { return global; }
int main() {
return get_global();
}
编译和反汇编此函数产生以下结果:
00000000004004ad <get_global>:
4004ad: 55 push %rbp
4004ae: 48 89 e5 mov %rsp,%rbp
4004b1: 8b 05 61 04 20 00 mov 0x200461(%rip),%eax # 600918 <global>
4004b7: 5d pop %rbp
4004b8: c3 retq
请注意:
- 全局变量的地址为0x600918 - get_global函数的地址为0x4004ad
基本上,问题是:如何使用gcc和ld为一个函数生成代码,使其能够:
- 引用全局变量和/或函数确切地在上述地址处 - 从我想要它开始(我特别感兴趣的是从地址0x4004ad开始,这样它就可以潜在地用于覆盖现有的get_global实现)
我认为可能可以通过一些指定给函数原型和/或全局变量的编译器特定属性或编译指示来实现,实际上,gcc有一些变量属性控制函数/变量在某些部分的打包和放置, 但无法指定固定的地址。
我强烈怀疑可以通过手动调用
ld
并使用一些ld链接器脚本魔法来完成,但是快速查看其文档对我来说似乎没有任何提示。我有什么遗漏吗?肯定相关:C中的固定地址变量