有没有办法在运行时修改Linux C程序中的函数代码?

简单来说,我们有两个类似的功能:

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.

现在我想在运行时用f2的机器代码替换f1.我使用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位这样的东西可能会阻挡你.自修改代码通常不受欢迎.

上一篇:java-在hadoop FS中编写二叉树


下一篇:Javascript可写描述符是否会阻止实例的更改?