Rover12421's Blog

The End.

Inject Replace eglSwapBuffers Problems

在项目中有个功能是获取FPS,用到了root注入来获取FPS,这个方法是通过计算eglSwapBuffers调用次数来统计的,那目的就简单了,直接注入替换eglSwapBuffers,再在新的函数统计并调用原始的eglSwapBuffers即可.

看起来挺简单的事情,放到实际情况中却又是另外一回事了.

第一个问题是在刷了ColorOS的小米机器上遇到的.问题简单描述就是:通过shell手动执行二进制文件注入成功,通过java代码执行命令,注入失败.

原因是通过java代码执行,在注入的时候找到的mmap偏移地址不对.导致计算远程mmap地址不正确,而无法继续.通过各种测试,最后问题得到解决.

以前的代码是直接使用函数地址:

1
mmap_addr = get_remote_addr(target_pid, libc_path, (uint32_t)mmap);

修改后的代码则从so中查找函数地址:

1
2
3
4
5
void* handle = dlopen(libc_path, RTLD_LAZY);
void* local_mmap = dlsym(handle, "mmap");
dlclose(handle);

mmap_addr = get_remote_addr(target_pid, libc_path, (uint32_t)local_mmap);

第二个问题,则发生在三星系列手机上,注入正常,eglSwapBuffers地址确实替换成功了.但就是不调用替换的函数.没办法,只好硬着头皮看FPS Master的反汇编了.先看图. Alt text 图片上的反汇编,我加来注释.其中的函数名我也改了.可以看到他有去查找/system/lib/hw/system/vendor/lib/hw目录下以hwcomposer开头的文件.(其中的findStartStringFile函数名是我修改的,内容就不贴图了)

知道他会查找hwcomposer开头的文件,那是不算这个文件里也有eglSwapBuffers的实现呢?拿出来对比就知道了. Alt text 第一个eglSwapBuffers.msm8974.so是Z5S上copy出来的,并没有eglSwapBuffers,第二个eglSwapBuffers.omap4.so是三星的一款手机上拿出来的,可以看到确实是有eglSwapBuffers字符串,大致能猜测到,这个so里又实现eglSwapBuffers.那就一起替换吧.

效果和想的一样,这下三星也没问题了.

注入不稳定,各种问题.还有通过eglSwapBuffers得到的fps貌似不理想,不管卡不卡,得到的帧率可能都很底或很高.感觉和性能完全不靠边似的.如果谁还有更好的办法,请提示哦:)

Comments