pqy330 pqy330
关注数: 0 粉丝数: 94 发帖数: 2,602 关注贴吧数: 1
我要问一个相当有趣的问题 一个动态库: #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include "dynlib.h" void print() { static unsigned int counter = 0; ++counter; printf("%d:PID%d in print()\n",counter,getpid()); } void fun() { print(); system("date"); } 一个程序源码: #include <stdio.h> #include <unistd.h> #include "dynlib.h" const char *str = "free"; int main() { while(1){ print(); printf("Going to sleep...\n"); sleep(3); printf("Waked up...\n"); } return 0; } 一个等待注入的目标代码: #include <stdlib.h> extern void fun(); extern void injection() { fun(); system("free"); } 编译: gcc dynlib.c -shared -fPIC -ggdb -o libdynlib.c gcc app.c -L. -ldynlib -ggdb -o app gcc -c injection.c 首先运行app,得到其pid后使用gdb开始注入,先打开injection.o并映射到进程的地址空间,然后替换print符号的重定位为injection.o的injection,一切似乎很顺利。但是在我解决"free"字符串的重定位时,出现了问题,如果我重定位到app自带的str字符串,可以工作,如果重定位到injection.o里的.rodata,就不能工作。 例如某次实验中,injection.o被映射到了0x7fe42ba20000,injection.o的.text偏移为0x40,.rodata的偏移为0x5a,还有字符串符号在.text中的偏移为0xf,据此: set *(0x7fe42ba20000 + 0x40 + 0xf) = 0x7fe42ba20000 + 0x5a 但是这样并不会打印free命令的输出。 如果改为set *(0x7fe42ba20000 + 0x40 + 0xf) = 0x4007f4 其中0x4007f4是str字符串的地址,那么就会打印free的输出。 我还特意 p (char*)0x4007f4 p (char*)(0x7fe42ba20000 + 0x5a) 结果都是打印"free", 为何重定位到第二个地址不行呢?
首页 1 2 3 4 下一页