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

标签 c linux gcc assembly writable

为了简单起见,我们有两个相似的函数:

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/

相关文章:

c - -lpthread链接错误

c - 试图学习 C,但我遇到了奇怪的错误(至少对我而言)

c - 如何更改 scanf ("%d",&variable) 以从 C 中的命令行接收 argv

python - 尝试在需要它的 python 脚本中定义 DJANGO_SETTINGS_MODULE 时出现错误

c - 如何强制 OpenMPI 使用 GCC 而不是 ICC?是否需要重新编译 OpenMPI?

c++ - 编译器说每个构造函数和函数都被重新定义并且不会编译。我使用的#IFNDEF 错了吗? - C++

c - 操作系统如何为文件执行缓冲

c - 如何唤醒正在 recvmsg() 中休眠的 pthread?

linux - 应用程序的性能测试 - Cloud foundry

android - `flutter config --android-sdk/opt/android-sdk/` 在 arch linux 上无法工作我该如何配置?