拿到样本,解包无壳,如图所示jsc
格式文件就是编译过的源代码
和lua
开发生成的luac
形式上很像,猜测一样是xxtea
加密来的,同时CocosCreator
上提供了个构建编译时填写密钥的选项,所以先不论是否有现成的反编译工具,这个密钥应该是必须要获取的。亦或者密钥也可能被转换成别的形式存放在某个地方,然后运行时用key
解密。
起初还以为jsc跟V8有什么关系,看了非虫前辈的文章
才知道是用的另一个JavaScript解释引擎 SpiderMonkey,为了掌握更多的信息,上Jadx
稍微读一下assets下二进制源代码的加载情况,在Cocos2dxActivity
入口处我们看到有一个onLoadNativeLibraries
函数,跳转到其声明发现加载了一个叫android.app.lib_name
的字符串资源
在AndroidManifest.xml
下找到其定义为cocos2djs
,即加载了libcocos2djs.so
明确了加载Assets目录资源的操作大概率不在java层后,研究对象随即转移到libcocos2djs.so
上。
IDA打开so,导出函数名很整洁看起来没有加什么奇怪的东西,搜索xxtea / key
之类的函数名得到这几个相关函数
稍微看了下几个相关decrypt的函数内容,在xxtea_decrypt
这个函数里看到有memcpy
和memclr
操作,很像在开内存拷贝数据,并且sub_597B9C
这个函数里大量的计算很像解密算法
通过CocosCreator源代码同时验证了这一点 jsb_global.cpp
其中的第三个参数正是xxteaKey,证实了我的猜想。所以当下考虑直接在运行时Hook这个函数打印出key。熟悉Xposed的我对Native层好像没什么办法
那就剩下俩个方案:写Magisk模块
或者Frida脚本
来Hook,最终选了没上手过的Frida
,想着借此机会实践一下其威力。
按照官网wiki,随便扒拉两下在PC安装好Frida
的python实现,Server端推荐使用Magisk仓库
中的模块,无需自己推到手机/data/local/tmp
目录下手动运行转发端口,开机直接挂载对应文件自动运行。
这里我选用网络adb的方式链接手机进行调试,别问 问就是局域网下不用插线很方便,终端adb connect 设备IP
连接上手机
终端输入 frida-ps -U
查看当前手机上的进程 以测试是否连通
haleclipse@Haleclipses-iMac:~$ frida-ps -U
PID Name
----- ---------------------------------------------------
3640 ATFWD-daemon
707 adbd
728 adsprpcd
26041 android.hardware.audio@2.0-service
741 android.hardware.biometrics.fingerprint@
接着编写一个js脚本直接hook xxtea_decrypt
函数
Interceptor.attach(Module.findExportByName("libcocos2djs.so", "xxtea_decrypt"), {
onEnter: function(args) {
console.log(Memory.readUtf8String(args[2]));
//send("Function called!");
console.log("\n");
},
onLeave: function(retval) {
}
});
终端输入
拉起对应app进行hook
结果要么没输出,要么直接闪退,大多直接提示
看起来没加载到这个so,那就是加载的时机不对。遂改进脚本,先hook dlopen
函数当扫描到包含 libcocos2djs.so
时进行xxtea_decrypt
函数的hook
function hooknative1() {
Java.perform(function() {
Process.enumerateModules({
onMatch: function(exp) {
if (exp.name == 'libcocos2djs.so') {
send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);
send(exp);
return 'stop';
}
},
onComplete: function() {
send('stop');
}
});
var soAddr = Module.findBaseAddress("libcocos2djs.so");
send(soAddr);
hooknative2();
});
}
这次想着应该能够命中了,结果运行以后打印出来的so愣是没有libcocos2djs.so
,屡次复查无果
没有办法,所以dlopen
这个时机抓不到那只能换条路,突然想到Java
层的System.loadLibrary
函数也是一个等价的hook时机,再次改进添加如下代码
function startHook() {
Java.perform(function() {
var Cocos2dxActivity = Java.use('org.cocos2dx.lib.Cocos2dxActivity'); //要hook的类名完整路径
Cocos2dxActivity.onLoadNativeLibraries.implementation = function() { // 重写要hook的方法getSign,当有多个重名函数时需要重载,function括号为函数的参数个数
var onLoadNativeLibraries = this.onLoadNativeLibraries(); //调用原始的函数实现并且获得返回值,如果不写的话我们下面的代码会全部替换原函数
console.log("File loaded hooking");
// send("arg1:" + arg1); //打印参数值
// send("arg2:" + arg2);
// send("arg3:" + arg3);
// send("result:" + Sign); //打印返回值
// return Sign; //函数有返回值时需要返回
hooknative2();
};
})
}
这下就很准确的在libcocos2djs.so
刚加载的时机hook。成功拿到key
拿到key剩下解密的逻辑直接参照CocosCreator
源代码xxtea_decrypt
部分,抄一份对应实现即可
其实按照Frida的Hook能力是一定能够将xxtea_decrypt
解密后的内容打印出来的,但多次尝试都没办法打印出来,大概是因为类型没写对 又或者 是解密后的内容太大了就打出来一堆乱码。
最最后我发现,so的十六进制文本里直接就能定位到key(此地无银三百两哈哈哈哈艹
直接用Hex Workshop
打开libcocos2djs.so
搜索jsb-adapater
陈馄荻:文章真不错https://www.laishike.com/laishike/2540.html
被360加固过,加载不到 libcocos2d.so ,怎么办呢,大佬
代码执行后依然无任何输出emm
在MacOS上已经成功找到Key, 两种办法
Hopper 反编译so,然后找到jsb_set_xxtea_key,找到函数ref的地方,附近有jsb-adapter/jsb-builtin.js相关字眼,点过去上面几个地址就是存的Key。2.直接使用OSX自带的strings命令
strings -a so文件位置
, 然后Command+F搜索jsb-adapter/jsb-builtin.js,上面的一行就是Key大佬 666
strings -a libcocos2djs.so | grep -B1 "jsb-adapter" | head -n1
hooknative2() 的实现是怎么的,代码可以分享一下吗? lgnice@sina.com
你好,已经给你传送了一份邮件。闲暇之余可不可以帮我看一下。
果然 死宅男都喜欢用handsome主题,买了一份 做了一年博客 ,然后转移到内网了 好看是真的
想做伸手党,能分享一份代码么
1932322862@qq.com
文中就是全部的详细代码
xxtea加解密jsc的,不会搞C代码
你好,用hex workshop打开libcocos2djs.so搜索jsb-adapater没有搜索到那个值。是不是最新版本的cocoscreator做了其他的处理,我用的2.4.2的版本?
SO样本可以发我看下,传个蓝奏云什么的
https://wwpo.lanpv.com/i3NWk1lqp6hc
可以帮忙看看这个libcocos2djs.so ?
多谢了