http://blog.51cto.com/haidragon/2135226
https://github.com/gaffe23/linux-inject
目的:将动态库so注入到目标程序中
核心原理:1、获取目标程序函数(__libc_dlopen_mode、malloc、free)的地址;2、获取一段可执行的内存地址;3、将汇编注入代码写入这段内存地址;4、通过int3断点来查看函数调用返回值和恢复写入内存数据。
1、通过读取(/proc/%d/maps)获取libc的基地址,通过dlopen和dlsym获取当前程序中需要获取的函数(__libc_dlopen_mode、malloc、free)的地址,函数如下:
long getFunctionAddress(char* funcName)
{
void* self = dlopen("libc.so.6", RTLD_LAZY);
void* funcAddr = dlsym(self, funcName);
return (long)funcAddr;
}
因为函数(__libc_dlopen_mode、malloc、free)都在libc库中,所以用获取的地址-基地址=偏移地址;
同样读取目标程序的(/proc/%d/maps)获取libc的基地址,用此基地址+偏移地址=函数地址;
所以:偏移地址 = (当前函数地址)-(当前基地址);
目标函数地址 = (目标库基地址) + (获取的偏移地址)
2、读取目标程序(/proc/%d/maps)一段可执行(属性为x)内存地址,此内存地址需要计算最佳位置:
// find a good address to copy code to
long addr = freespaceaddr(target) + sizeof(long);
// now that we have an address to copy code to, set the target's rip to
// it. we have to advance by 2 bytes here because rip gets incremented
// by the size of the current instruction, and the instruction at the
// start of the function to inject always happens to be 2 bytes long.
regs.rip = addr + 2;
,计算注入函数的大小,注入函数的最后一个返回值写为int3用于恢复现场等,将需要写入内存大小的数据保存,写入注入的汇编函数(