一、前言
今天我们来看如何破解分析TexturePacker加密资源的加密Key。根据经验目前常用的方法有以下三种:直接hook uncompress函数,得到资源数据内容并保存;直接hook setPvrEncryptionKeyPart函数(不同版本的cocos2dx引擎可能函数略有不同)打印Key;用IDA调试并分析so文件来获取加密Key。前两种方法hook代码量比较多,通常要在Android环境中hook,显然有些麻烦。第三种方法要求对IDA工具会基本的常用操作,代码量相比要少。三种方法如果碰到so被加密或加壳了必须解密或脱壳后才能完成。当然不管用什么方法,只要找到适合自己的方法达到目的就可以。
二、案例分析
下面我们就对上面所提到的第三种方法进行调试分析。首先我们得有个案例程序,根据需要可自已找个类似的apk或自己写个demo编译成apk,这里我们选用类似的apk,这时我们就可以开始调试分析了。按照惯例:
第一步:解压apk,看下目录情况可知无常用加壳保护,得classes.dex文件,利用dex2jar+jd-gui得到java源码:
看到源码中无明显加壳特征。得到libcocos2dcpp.so文件,不难看出此so是引擎cocos2dx用C++语言开发编译的。用IDA工具打开无任何错误提示并且函数能正常显示,说明so文件没被加壳加密。
第二步:用apktool或ApkIDE反编译apk(本案例用ApkIDE),获取apk资源文件AndroidManifest.xml中信息,重点要看以下三个地方
1、application节点中android:debuggable="true",如果没有这句则添加上或者为“false”改为"true"后保存并重新编译得到前缀为ApkIDE_的apk。
2、manifest节点中package="com.mtx.thj" 这后面会用到……
3、activity节点中android:name="org.cocos2dx.cpp.AppActivity" 后面会用到……
第三步:启动Android模拟器或Android手机,把apk安装到Android模拟器或Android手机中(此案例为Android手机,数据线连接手机)。在cmd窗口输入如下命令 and install D:\apk\cocos2dx_cpp_1.0.apk 并回车(路径根据大家的apk路径为准)完成安装。
三、找出资源加密Key。IDA调试并分析libcocos2dcpp.so文件,找出TexturePacker编辑的资源加密Key。
第一步:在cmd命令行窗口启动手机中的android_server,本手机为sv文件。
第二步:在上面同一个cmd命令行窗口用debug模式启动程序并回车
adb shell am start -D -n com.mtx.thj/org.cocos2dx.cpp.AppActivity
这里的包名和入口Activity都可以在上面(2.2中)反编译之后的AndroidManifest.xml中找到。
启动程序成功
第三步:另启动个cmd命令行窗口进行端口转发
adb forward tcp:23946 tcp:23946
第四步:双开IDA,一个用于静态分析libcocos2dcpp.so,一个用于动态调试
记录上面两图示中setPvrEncryptionKeyPart函数及setPvrEncryptionKey函数的相对地址分别为:0067F188和0067F1B4再打开一个IDA,进行attach调试进程
在上面窗口中搜索目标进程包名com.mtx.thj
并按ok按钮attach调试进程,完成后F9运行并且设置debugger调试选项
第五步:使用jdb命令attach上调试器,这里可以用eclipse的devices查看进程端口
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8601
并回车
此时第二个IDA会暂停,F9运行几次后会加载so文件,出现下面窗口一直点Cancel
F9运行直到Output window出现 loaded /data/app-lib/com.mtx.thj-1/libcocos2dcpp.so,记下libcocos2dcpp.so在内存中的绝对地址:75237000
第六步:对setPvrEncryptionKeyPart函数及setPvrEncryptionKey函数下断点
setPvrEncryptionKeyPart函数的绝对地址=第三步中的相对地址:0067F188+75237000 = 758B6188
在第二个IDA的调试窗口中按下G键输入758B6188确定就可到setPvrEncryptionKeyPart函数位置并且下F2断点
同时F5键进入伪代码窗口在此函数下F2断点
同理setPvrEncryptionKey函数的绝对地址=第三步中的相对地址:0067F1B4+75237000 = 758B61B4
并在IDA的调试窗口中按下G键输入758B61B4确定就可到setPvrEncryptionKey函数位置并且下F2断点(图略)
同时在此函数的伪代码窗口中对setPvrEncryptionKey函数下F2断点
第七步:F9运行程序
出现add map窗口一直点Cancel,加载好几个so文件,直到执行到setPvrEncryptionKey函数断下
断下时在General registers窗口里的R0R1R2R3分别就是密码字符串,那么此apk里TexturePacker所加密资源加密Key估计为AAAAAAAABBBBBBBBCCCCCCCCDDEE1988,如果很难看出在setPvrEncryptionKey函数伪代码窗口中F9就可以断下,并将鼠标移动到a1,a2,a3,a4位置可以看到对应的密码字符串的值
此时再参考下cocos2dx引擎中setPvrEncryptionKeyPart函数解密调用Key的情况,可确定AAAAAAAABBBBBBBBCCCCCCCCDDEE1988就是资源的加密Key
第八步:验证密码正确性
用TexturePacker的Tools -> PVR Viewer打开之前解压的apk目录下assets目录中任一个.pvr.ccz后缀文件
注意:
.pvr.ccz的16进制数据中头4字节为 43 43 5A 70 ,才是加过密的.pvr.ccz资源文件
在TexturePacker工具如果输入过一次Key后,打开加过密的.pvr.ccz资源文件可直接打开
四、小结
1、对于cocos2dx资源加密用这种加密方式加密安全等级非常低,不建议使用。当然加密后也算是对游戏资源的一层防护……
2、对于用TexturePacker工具加密的资源要找密码Key用IDA调试时对函数setPvrEncryptionKey下断点很容易找到Key;
3、对于单个资源文件直接用TexturePacker工具打开后保存,如果要批量解密资源要在win平台下编写工具。
领取专属 10元无门槛券
私享最新 技术干货