今天测试一个用例,其实不能说是测试,因为前面都已经完成了,只是需要支持一些新的功能,所以需要在当前版本上进行相应的修改然后测试。简单来说,还是plt hook的实现,只不过前一段时间针对的都是java编写的目标程序,现在针对的是c编写的目标程序(c编写的目标程序的功能早就验证过了)。
本来以为是一个很轻松的事情,结果添加新功能的代码后,凉凉,根本找不到注入的函数,不应该啊,因为c编写的目标程序应该是最没有问题的。通过查看线程的maps信息,发现so注入都没有成功,再通过log查看,调用dlopen_mode来load hook_so.so时,返回值(rax里存储的值),的确是0——如果成功,返回的应该是注入的so在目标线程里的地址。
没办法,只能回退版本(幸亏保存了之前的注入C程序的成功的版本),然后在此基础上进行修改,最终定位出来原因是注入的so里起了了新线程!由于jvm本身在启动时就会把 -lpthread 参数给加进去,所以在注入的so里就不必再添加了,但是在c程序里,由于自己编写的目标程序的代码太简单,根本没起多线程,所以没有添加 -lpthread 参数,导致问题的出现。
网上查dlopen load so 失败的原因,有人总结如下,在此转载一下,也算是一个参考:
https://blog.csdn.net/xy010902100449/article/details/48036609
①动态库位置没有放对地方,dlopen 时候找不到你想操作的动态库
解决办法:放到指定目录。
②头文件没有包全,有不能识别的函数或者标识符 —— 我这里的问题应该是对应这一条,但由于我是通过寄存器修改来实现dlopen调用的,所以这种解决方法对我来说不现实。
解决办法:加一条打印信息,程序运行到这里,会输出不能识别标识符。
if((handle = dlopen(myso, RTLD_NOW)) == NULL) {
printf("dlopen - %sn", dlerror());
exit(-1);
}
或者用ldd(具体看编译交叉链,这里是用 gcc 编写的动态库,其它交叉编译链视具体情况而定)。
③makefile 编写问题
①没有指定 -fPIC 编译选项 (Position-Independent Code 代码与位置无关);
②没有指定 -shared 外部程序可以访问这个动态库。