从某厂的应用市场里下载apk,解包,先看看是mono还是il2cpp。发现是libmono.so,并且相关的DLL都被加密了,二话不说,老套路,直接hook mono_image_open_from_data_with_name,然而运行就奔溃
if((strstr(name,"libmono.so")!=NULL)) {
void *mono_image_open_from_data_with_name = (void *) dlsym(handle,
"mono_image_open_from_data_with_name");
if (mono_image_open_from_data_with_name != NULL) {
MSHookFunction((void *) mono_image_open_from_data_with_name,
(void *) new_mono_image_open_from_data_with_name,
(void **) &old_mono_image_open_from_data_with_name);
}
}
不知道为啥奔溃,关键是奔溃时的调用栈信息也被抹了,先把libmono.so脱到IDA里看看什么情况,发现libmono.so的所有导出函数全部被加密了
猜测是InlineHook把函数头部的字节修改后,在其解密时异常导致的奔溃。于是想到了本站
友贴说用GOT Hook,直接把他的代码拷贝过来试试。然而依然不起作用(没异常也没效果)。
怎么办呢,,我先看看游戏运行是加载了哪些so把,可能有那么一点点线索。
找点什么有Protect、Security关键字的so简单分析分析,没有结果。。
与此同时我发现一个很奇怪的地方,如下图,为啥Dll会被以这种方式加载起来?而且之后我在/proc/pid/maps里也没发现有相关的信息,很奇怪
冷静下来 ,暂时放弃这个问题。我先去内存里dump libmono.so(因为我之前怀疑,该厂的保护是自己hook了这些关键函数进行检测,才导致我上的hook崩溃。最开始我是通过打印函数头部的4个字节,结果发现一直不正常,反正不是跳转指令,也不是压栈指令)
IDA附件到进程,然后喜闻乐见
反正只是为了dump so,又不为了调代码,试试附加到他的子进程去dump 吧。
找到模块地址,常规的IDC dump代码一运行,dump_libmono.so就出来了,懒得修复,直接脱到IDA,所以发现根本没符号信息。只好先从能定位到的地方(通过静态分析apk里的libmono.so,可以知道mono_image_open_from_data_with_name的偏移是0x192f08)开始分析,单击G,输入
0x192f08,然后F5。通过对比mono源码,发现没问题
(之前有听说自己魔改mono,特殊处理Assembly-CSharp.dll的保护方案,本打算盯着有改动的代码,顺藤摸瓜)
,也没有InlineHook的痕迹,代码基本长的一样。
上个源码图
怎么办呢,所有的导出函数都加密了,并且hook他们就要崩溃,而且你还没有调用栈的信息。。。那我试试hook非导出函数(基址+偏移),于是就近找了一个,就是上图中的do_mono_image_load(参数比较诱人),然后我在原libmono.so中的导出表里查了查,确实没有导出这个函数
配合这下两图的信息(就地取材),定义了这么一个结构体
IDA视图
源码视图
结构体定义
struct simple_image{
char tmp[8]; //0
char* data; //8
size_t length; //12
char tmp1[4]; //16
char *name; //20
};
然后就dump下来了。。
int (*old_func)(char* a1,int a2 ,int a3,int a4);
int new_func(char *a1,int a2 ,int a3,int a4){
simple_image* si = (simple_image*)a1;
MYLOGD("load iamge name %s",si->name);
MYLOGD("load iamge data %s",si->data);
MYLOGD("load iamge size %d",si->length);
dumpFileToSdcard(si->name,si->data,si->length);
return old_func(a1,a2,a3,a4);
}
并且Dll完整,没加密。。
有点失望,在我心里,该厂不应该这样啊。。
tips:
1.libmono.so会被加载很多次,在hook的时候注意被重入了
2.内容实在过于简单,目的是为了和大家交流交流手游保护姿势,还有就是之前那个Dll以so方式加载的情况
3.欢迎批评指正
if((strstr(name,"libmono.so")!=NULL)) {
void *mono_image_open_from_data_with_name = (void *) dlsym(handle,
"mono_image_open_from_data_with_name");
if (mono_image_open_from_data_with_name != NULL) {
MSHookFunction((void *) mono_image_open_from_data_with_name,
(void *) new_mono_image_open_from_data_with_name,
(void **) &old_mono_image_open_from_data_with_name);
}
}
不知道为啥奔溃,关键是奔溃时的调用栈信息也被抹了,先把libmono.so脱到IDA里看看什么情况,发现libmono.so的所有导出函数全部被加密了
冷静下来 ,暂时放弃这个问题。我先去内存里dump libmono.so(因为我之前怀疑,该厂的保护是自己hook了这些关键函数进行检测,才导致我上的hook崩溃。最开始我是通过打印函数头部的4个字节,结果发现一直不正常,反正不是跳转指令,也不是压栈指令)