好吧,讓我們來做一個實驗。 下面是代碼:
#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被標記爲不可寫,導致未處理的用戶空間頁錯誤,即發生段錯誤。
現在let'us 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
非常感謝你,Alex。有用的/ proc/pid/maps和mprotect。 – xiaokaoy