为了简单起见,我们有两个相似的函数:
void f1()
{
printf("%d", 123);
}
void f2()
{
printf("%d", 124);
}
现在我们在main中调用f1,它打印123。编译时,f1
的反汇编可能是这样的:
08048424 <f1>:
8048424: 55 push %ebp
8048425: 89 e5 mov %esp,%ebp
8048427: 83 ec 18 sub $0x18,%esp
804842a: b8 40 86 04 08 mov $0x8048640,%eax
804842f: c7 44 24 04 7b 00 00 movl $0x7b,0x4(%esp)
8048436: 00
8048437: 89 04 24 mov %eax,(%esp)
804843a: e8 05 ff ff ff call 8048344 <printf@plt>
804843f: c9 leave
8048440: c3 ret
f2 的机器码与f1 的类似。
现在我想在运行时将 f1 替换为 f2 的机器码。我使用 memcpy(f1, f2, SIZE_OF_F2_MACHINE_CODE)。 肯定会出现问题 - 段错误。
现在我想知道是否有办法解决这个问题。这是一个普通的C程序。 据我所知,我们可以使用下面这样的代码来设置 Linux 内核中的页面可写:
int set_page_rw(long unsigned int addr)
{
unsigned int level;
pte_t *pte = lookup_address(addr, &level);
if(pte->pte & ~_PAGE_RW)
pte->pte |= _PAGE_RW
}
但它在普通的 Linux C 程序中不起作用。那什么有效呢?
最佳答案
不要覆盖过程,而是覆盖符号表中的符号引用。那确实需要动态链接。或者,您可以使用对其他函数的调用来覆盖对函数的调用,但是诸如 NX
位之类的东西可能会妨碍您。自修改代码通常不受欢迎。
关于c - 有没有办法在运行时修改 Linux C 程序中的函数代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12947388/