首先,我对这篇文章的篇幅感到抱歉,但我想清楚地解释这个问题.
我尝试在C中编写一种小型自修改程序,但是我遇到了一些麻烦,我不确切知道为什么.
平台是: Ubuntu/Linux 2.6.32-40 x86_64,prog是基于x86 arch,gcc(Ubuntu 4.4.3-4ubuntu5.1)4.4.3,GNU ld(GNU Binutils for Ubuntu)2.20.1-system.20100303
该程序的目的是创建一个读/写/执行内存块(使用memalign(3)和mprotect(2)),复制一个在这块内存中调用p()(在.text段中定义)的小函数,然后执行通过指针复制函数.该p()函数只显示一条消息printf(puts).
为了得到的代码的开始和结束地址p()(以复制),我用的是函数本身的地址和地址dummy()刚过创建功能p()在.text.
int p() { ... } <- address where the copy starts
int dummy() { ... } <- address where the copy stops
Run Code Online (Sandbox Code Playgroud)
成功完成块内存创建和复制,但是当块中的代码运行时,会发生段错误.通过使用gdb它很明显我们输入了块的代码(复制函数的主体),但是对printf的调用失败了.当反汇编p()函数和块中的代码时,我发现'call'中使用的地址不一样.
而且我不知道为什么地址不正确,当代码被复制时它被显示,并且它与objdump(或gdb)在我反汇编p()函数时给我的相同.
创建二进制文件是-static为了避免got/plt …