【问题标题】:How can I modify an instruction in a process? Linux & ARMv7如何修改流程中的指令? Linux 和 ARMv7
【发布时间】:2016-07-12 19:39:48
【问题描述】:

我试图修改名为 g 的函数的第一条指令,但在下面的 sn-p 中的第二条语句出现段错误

int a = *(int*)g;
*(int*)g=0;  // segment fault!
*(int*)g=a;

此段错误是否是由于我要修改的指令所在页面的页表条目中的 no-write 权限?

我这样做是因为我想看看我是否可以修补一个带有一些错误的函数,同时保持进程运行,如下所示:

1) g 函数的进程正在运行,并且发现该g 存在一些错误。因此,编写一个名为 patch_g 的新函数,它没有任何错误。

2) 将新函数编译成patch.so

3) dlopen & dlsym .so 文件。获取patch_g的地址。

4) 暂停正在运行的进程

5) 使用一些代码(有点类似于上面sn-p的第二条语句)将g的第一条指令改成jump patch_g

【问题讨论】:

    标签: linux permissions arm


    【解决方案1】:

    好的,我们来做一个实验。 代码如下:

    #include <stdio.h>
    
    int (*functionPtr)(int,int);
    
    int addInt(int n, int m) {
            return n+m;
    }
    
    
    int main()
    {
        functionPtr = &addInt;
        printf("%p\n", functionPtr);
        while(1){};
        *(int *) functionPtr = 0x0;
        return 0;
    }
    

    编译

    $ gcc -o ./main.c main
    

    在第一个控制台中启动此应用。

    $ ./main 
    0x40052d
    

    在第二个控制台

    $ cat /proc/`pidof main`/maps
    00400000-00401000 r-xp 00000000 08:01 6345711                            /tmp/main
    00600000-00601000 r--p 00000000 08:01 6345711                            /tmp/main
    00601000-00602000 rw-p 00001000 08:01 6345711                            /tmp/main
    

    ...

    这个r-xp意味着当内核加载这个二进制文件时,它已经将文本部分映射到具有读取和执行权限的私有虚拟映射,但没有写入权限。我认为这样做是出于安全原因。

    内核中适当的 vma_area 标记为不可写,导致未处理的用户空间页面错误,即发生段错误。

    现在让我们将 mprotect 调用添加到适当的位置

     17         if (mprotect((void *)0x00400000, 4096, PROT_READ | PROT_WRITE | PROT_EXEC)) {
     18                 printf("error\n");
     19                 return -1;
     20         }
    

    您会注意到这将有助于您实现运行时修补的想法。

    00400000-00401000 rwxp 00000000 08:01 6345711                            /tmp/main
    00600000-00601000 r--p 00000000 08:01 6345711                            /tmp/main
    00601000-00602000 rw-p 00001000 08:01 6345711                            /tmp/main
    

    【讨论】:

    • 非常感谢,亚历克斯。很高兴知道 /proc/pid/maps 和 mprotect。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 2018-03-20
    相关资源
    最近更新 更多