我有一个(相对较大的)静态二进制文件,我想用另一个函数替换其中的一个函数。鉴于函数的复杂性,我想用C和gcc编译拼接函数,然后直接替换代码。显然,为了使其工作,我需要以某种方式强制执行函数和我将访问的某些全局变量位于特定的偏移量处。我如何使用 gcc 和 ld 做到这一点?
一个非常简单的例子 - 给定一个这样的程序:
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
注意:
global
变量的地址为 0x600918get_global
得到 0x4004ad
基本上,问题是,我如何使用 gcc 和 ld 来生成一个函数的代码,该函数将:
- 引用
global
变量和/或函数在提到的确切地址上 - 从我希望它开始的地址开始(我对从地址 0x4004ad 开始特别感兴趣,因此它可能用于拼接现有的
get_global
实现)
我认为可以使用为函数原型(prototype)和/或全局变量指定的一些编译指示或特定于编译器的属性,事实上,gcc has some variables attributes that control packing and placement of functions/variables in certain sections , 但不可能指定固定地址。
我强烈怀疑这可以通过手动调用 ld
并使用一些 ld 链接器脚本魔术来完成,但是 a quick look at its documentation似乎没有为我敲响任何警钟。我错过了什么吗?
最佳答案
我以前见过这样做,使用 ASM 文件将变量固定到特定地址。这专门用于共享内存中使用的全局变量。
在任何其他源文件中,您显然需要声明全局变量 extern
因此,编写一个仅包含变量的简短 asm 文件,然后编译并将其与其余代码链接。
关于c - gcc 和 GNU ld 链接器 - 生成具有强制固定地址/偏移量的静态链接代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25276741/