在研究一个应用的 so hook,之前在 arm 真机上已经用 substrate 实现了,所以我判断注入相关代码没有问题。
在移植到模拟器环境中时,发现基于 x86 架构的模拟器在加载 App 内部的 arm 库时,使用了libhoudini。通过 hook libdvm 中 houdini 的 dlopen 方法拿到了 app arm so 的地址,并且通过MSFindSymbol找到了要 hook 的目标函数地址,但是使用MSHookFunction之后就会一直崩溃。log 里面显示的也是看不出来什么有用的信息。
核心代码如下
// target hook
void fake_target()
{
// 这里只做简单的日志输出,logcat 没内容
}
// 原始的 houdini dlopen 句柄
void* (*_hookDlopen)(const char *filename, int flag, bool* useHoudini);
// houdini dlopen hook
void* fake_hookDlopen(const char *filename, int flag, bool* useHoudini){
void* handle = _hookDlopen(filename, flag, useHoudini);
if(strstr(filename, "libAppArm.so")){
void * target = MSFindSymbol(handle, "target_function");
if (target != NULL){
MSHookFunction(target, (void*)&fake_target);
}
}
return handle;
}
// 初始化过程
MSInitialize {
MSImageRef image;
image = MSGetImageByName("/system/lib/libdvm.so");
if (image != NULL) {
void * houdini = MSFindSymbol(image, "_ZN7houdini10hookDlopenEPKciPb");
if (houdini != NULL){
MSHookFunction(houdini, (void*)&fake_hookDlopen,(void **)&_hookDlopen);
}
}
}
- 在找到要 hook 的函数之后,进行 MSHookFunction 的过程在 arm 上已经测试过,上面的代码被我简化了
- 各种 NULL 和非 NULL 的分支都加了 log,也被我简化了,比较确定的是 MSHookFunction 一旦调用必然崩溃
- 猜测 MSHookFunction 会对原始地址、替换地址进行某些指令集相关的操作,libAppArm 中 MSFindSymbol 的结果是一个 arm 相关的地址,我用本地的函数应该是 x86 的,MSHookFunction 在转换的过程中指针操作异常了
- cydia substrate 在模拟器上只能 link x86 的 so,所以我写的 module 也只能导出 x86 版本的 so。
- 是不是关键在于把 hook 的某个环节变成 arm so,也用 libhoudini 加载就可以解决?这个路子完全没思路。
请各路 v 友指点一二……