int main()
{
while (1)
{
print();
cout << "Going to sleep ..." << endl;
sleep(3);
cout << "Waked up ..." << endl;
}
return0;
}
上面的app.cpp程序在一个循环里面调用print()函数(print()函数位于libdynlib.so动态库中),然后睡眠几秒钟,之后继续执行这样的循环。
// injection.cpp
#include<stdlib.h/>extern"C"void print();
extern"C"void injection()
{
print(); // do the original job, call the function print()
system("date"); // do some additional job
}
在main()函数里调用print()函数会被injection()函数会替换。injection()函数首先调用原始的print()函数,之后会做一些额外的操作。比如,你可以用system()函数来执行一些其他可执行文件,或者就像我做的直接打印当前日期。
-rwxr-xr-x 1 gregory ftp 52248 Feb 12 02:05 app
-rw-r--r-- 1 gregory ftp 1088 Feb 12 02:05 injection.o
-rwxr-xr-x 1 gregory ftp 52505 Feb 12 02:05 libdynlib.so
需要注意的是动态连接库libdynlib.so编译链接的时候需要用-fPIC参数,这样生成的代码是位置无关的(我也不懂什么是位置无关的,原文是 produces position independent code,有懂的请不吝赐教),编译injection的目标文件需要用C编译器。编译完成就可以执行 app 程序了。
[lnx63:code_injection] ==> ./app
1: PID 4184: In print()
Going to sleep ...
Waked up ...
2: PID 4184: In print()
Going to sleep ...
Waked up ...
3: PID 4184: In print()
Going to sleep ...
进入调试器
app程序刚执行几个循环,但我们假定它已经跑了好几个礼拜了,这样的话我们就可以现在注入我们的代码了。在注入的过程中会用到Linux gdb调试器。首先需要把调试器附加到4184进程上,看上面打印出来的PID(application process id)。
[lnx63:code_injection] ==> gdb app 4184
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/tls/libthread_db.so.1".