Reputation: 1696
I tried to modify the first instruction of a function called g, but got a segment fault on the second statement in the following snippet
int a = *(int*)g;
*(int*)g=0; // segment fault!
*(int*)g=a;
Was this segment fault due to the no-write permission in the page table entry for the page where the instruction I wanted to modify was located ?
I did so because I wanted to see if I could patch a function with some bugs, while keeping the process running, like this:
1) A process with function g is running, and that g has been found to have some bugs. So write a new function called patch_g, which has no bugs.
2) Compile the new function into patch.so
3) dlopen & dlsym the .so file. Get the address of patch_g.
4) Suspend the running process
5) Use some code (somewhat similar to the second statement of the snippet above) to change the first instruction of g into jump patch_g
.
Upvotes: 1
Views: 101
Reputation: 3935
Ok, let's do an experiment. Here is the code:
#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;
}
Compile
$ gcc -o ./main.c main
Launch this app in first console.
$ ./main
0x40052d
In second console
$ 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
...
This r-xp means that when kernel loaded this binary, it has mapped text section into private virtual mapping with read and execute permissions, but without write permissions. I think this is done because of security reasons.
So appropriate vma_area in kernel marked as non writable, what leads to unhandled userspace page fault i.e. segfault is occured.
Now let'us add mprotect call to appropriate place
17 if (mprotect((void *)0x00400000, 4096, PROT_READ | PROT_WRITE | PROT_EXEC)) {
18 printf("error\n");
19 return -1;
20 }
You will notice that this will help your with your run-time patching idea.
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
Upvotes: 1