玩过hook的人,都知道其的强大之处!
一、背景和意义
Unity3D是手游领域的主要游戏引擎,越来越多游戏对其dll进行加密。目前我知道有3种方法对其进行解密: 1.直接使用ida反编译libmono.so,寻找关键函数处的解密代码 2.使用gdb附加,gcore,在core文件中寻找相关MZ头和尾巴original filename:assembly-csharp.dll,掐头去尾 3.对libmono.so的关键函数进行hook,这也是本文的内容 p.s.代码中的*不见了,自己对照源码
二、工具和教程
本方法使用cydia substrate进行hook 官网:http://www.cydiasubstrate.com/ 相关教程: http://blog.csdn.net/guiguzi1110/article/category/2519125 http://www.gitzx.com/android-cydiasubstrate/ http://www.colordancer.net/blog/2015/03/16/substrateforandroid/
三、相关函数
mono框架里有许多涉及到dll的函数,但是mono框架本身较为复杂,请自行阅读mono源码,本文选取的函数是
MonoClass mono_class_from_name (MonoImage image, const char name_space, const char name)
该函数在class.c文件中,第一个参数是dll镜像的结构体,其定义在marshall.internal.h中。该结构的第三个成员,也就是+8的位置,是一个指向dll->rawdata的指针,也就是dll的内容。该结构的第4个成员,是rawdata的大小。 ###### 四、实现 介绍完工具和hook目标,就该开始行动了。 这里并不能直接像之前教程那样写一个apk,我自己测试过,不行,原因未知。 受论坛里“水波摇曳”的过签名验证的启发,本人采用了另一办法,也就是我写了一个so,在so里调用cydia的库文件libsubtrate.so里的函数,MSGetImageByName,MSFindSymbol,MSHookFunction,来进行hook。然后在java层loadlibrary我的so. so里的关键函数如下
int mymonoclass(void image,
const char name_space,
const char name) {
int imageAddr = (int)(image + 8);
int imageLen = (int * )(image + 12);
if (imageLen != 2590208 & imageLen != 647680) { //mscorlib.dll和unityengine.dll的大小
LOGE(name_space);
LOGE(name);
printf("发现DLL");
printf("imageAddr:%p", imageAddr);
printf("imageLength:%d\n", imageLen);
} //LOGE(imageAddr); //LOGE(imageLen);
return oldmonoclass(image, name_space, name);
}
本文链接:https://www.it72.com/11996.htm