最近我们要开一个新项目,UI与交互打算借鉴当前正火的《圣火英雄传》,程序开发为了和美术制作并行,打算用圣火的资源暂代使用。我解压圣火apk,发现用TexturePacker命令行无法把它的pvr.ccz资源文件转成png,稍微了解一下,才知道TP提供了加密功能。我最近做Unity开发,只需要TP最基本的打图集功能,所以一直用v2.4.5,很久没有升级了,out了。

圣火资源加密了,没有密钥无法打开

美术同学可以先截图或画草图给程序用,但是,截图/草图跟原图比:大小规格不对,质量差,图元叠在一起,也会缺漏很多。不说耗费美术大量精力做繁重的体力活,这样做出的东西也会“惨不忍睹”,等正式美术资源来了,所有美术显示也都需要程序重新调整,这是不小的工作量。所以,最好的方法是研究破解圣火的加密资源。工程师的工作就是减小人的劳动,提高生产效率。

动态库注入与API拦截

开始时,我心里一点底儿也没有,因为我是开发游戏的,从来没做过破解。仅有的一点相关经验是几年前看《Windows核心编程》时用DLL注入和API拦截,做过一些游戏的反外挂工作。几年没做PC开发,具体实现早忘光了,只记得大致原理是通过注入自己的DLL到目标进程,劫持某些API,替换成自己的实现。

android内核是基于linux的,我想linux下是否也可以通过注入拦截API呢?只要能劫持API,就能破解。google "linux + inject",linux下果然也可以注入,更进一步发现有人已经开源了自己写的注入库,LibInject,核心的系统API是ptrace,还有几个操作动态链接库的API,dlopen、dlsym、dlclose、dlerror。注入之后,就是劫持,遍历got表,找到接口的地址然后替换成自己写的接口即可。

注入和劫持都ok之后,我试着劫持printf,替换成自己的函数,成功,我心里对破解有底了。下面是一些具体的操作过程。

首先要把手机root,把注入进程和劫持库拷贝到手机上,比如/data目录下,adb push命令。如果提示“Permission Denied”,就先把/data挂载(mount),然后改变文件权限(chmod)。

然后,打开圣火包里面lib目录,发现圣火用的是cocos2d-js v2.2开发,去cocos2d-x官方下载v2.2.5。然后,找到加载pvr.ccz的模块,都在ZipUtils.h/.cpp文件中。

1 void ZipUtils::ccSetPvrEncryptionKeyPart(int index, unsigned int value)// 设置密钥的接口
2
3 int ZipUtils::ccInflateCCZFile(const char *path, unsigned char **out) // 加载ccz文件的接口

我本想劫持设置密钥的用户自定义接口:ccSetPvrEncryptionKeyPart,这样可以直接获取密码。但是,从soinfo->symtab中获取的符号名始终是乱码,目前我还没搞明白原因,请知道的朋友指导。我就转而看ccInflateCCZFile的实现,这个接口会读取ccz文件的二进制数据,然后根据前四个字节判断是否合法的ccz文件(“CCZ!”)或者是否加密的ccz文件(“CCZp”),如果是加密的,就解密。接着,调用了libz的解压缩接口:

1 int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);  

原来ccz也是一种zip压缩格式。这里需要用到source和destLen这两个参数,source是解密出来的ccz文件数据,*destLen是压缩前的大小。既然如此,我只要把uncompress接口劫持了,就可以破解出资源。ps. 除了劫持uncompress,还可以劫持opengl接口,毕竟所有图都要送到opengl绘制。

破解

看看ccz的文件头:

1 /** @struct CCZHeader
2 */
3 struct CCZHeader {
4 unsigned char sig[4]; // signature. Should be 'CCZ!' 4 bytes
5 unsigned short compression_type; // should 0
6 unsigned short version; // should be 2 (although version type==1 is also supported)
7 unsigned int reserved; // Reserverd for users.
8 unsigned int len; // size of the uncompressed file
9 };

source是不包含文件头的,所以需要自己把文件头填充进去。sig是“CCZ!”,compress_type是0,version是2,reserved是0,len是*destLen。创建一个ccz文件,把文件头和source写入。然后,把生成的ccz文件拷回本机,adb pull,“Permission Denied”?chmod。怀着激动地心情用TexturePacker打开,却报告失败。然后用Notepad++的Hex Editor打开,转成16进制,发现文件头的大小端逆序了。比如version,在大端机器上16进制表示是0x00 02,小端机器上是0x02 02。如果是小端,逆序写就可以了。改了之后重新生成ccz,成功打开。

解密出来的圣火资源——Activity.pvr.ccz

文件命名

劫持uncompress是无法知道文件名的。写一个文件扫描圣火资源目录,根据以文件size为key,文件名为value。然后,根据文件size做匹配就可以了。因为文件的size是精确到byte的,一般不会有文件是同样大小。我检查了圣火,211个ccz文件,没有同样大小的。

转png与切图

TexturePacker可以直接命令行把ccz转png,然后再写一个工具,读plist切散图就可以了,可以用CocosStudio,网上也有人用python写的。至此,我们已经完美的破解了圣火所有的资源,获得了所有美术资源。

切出来的圣火美术资源散图

除了《圣火英雄传》,还有很多游戏也是用TexturePacker加密资源,都可以用这个方法破解。为了避免争端,暂不放出工具及代码。

ps. 两篇相关的操作blog:

查看android进程信息 http://blog.csdn.net/ynnmnm/article/details/38417829

使用adb在电脑和手机间传文件 http://blog.csdn.net/ynnmnm/article/details/38415221

转载请注明出处: http://blog.csdn.net/ynnmnm/article/details/38392795。作者:夜风。

[转载]破解TexturePacker加密资源的更多相关文章

  1. 破解TexturePacker加密资源

    http://blog.csdn.net/ynnmnm/article/details/38392795 最近我们要开一个新项目,UI与交互打算借鉴当前正火的<圣火英雄传>,程序开发为了和 ...

  2. 破解ZIP加密文件密码fcrackzip

    破解ZIP加密文件密码fcrackzip ZIP是最常见的文件压缩方式.由于其压缩算法开源,主流操作系统都支持这种压缩算法.ZIP压缩方式支持密码加密.加密的时候会在文件头部保存密钥相关信息.利用这个 ...

  3. 秀尔算法:破解RSA加密的“不灭神话”

    RSA加密 VS 秀尔算法 作为RSA加密技术的终结者——“太多运算,无法读取”的秀尔算法(Shor’s algorithm)不是通过暴力破解的方式找到最终密码的,而是利用量子计算的并行性,可以快速分 ...

  4. 爬虫破解js加密(一) 有道词典js加密参数 sign破解

    在爬虫过程中,经常给服务器造成压力(比如耗尽CPU,内存,带宽等),为了减少不必要的访问(比如爬虫),网页开发者就发明了反爬虫技术. 常见的反爬虫技术有封ip,user_agent,字体库,js加密, ...

  5. 秀尔算法:破解RSA加密的“不灭神话” --zz

    http://netsecurity.51cto.com/art/201508/488766.htm RSA加密曾被视为最可靠的加密算法,直到秀尔算法出现,打破了RSA的不灭神话. RSA加密 VS ...

  6. Python爬虫—破解JS加密的Cookie

    前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站.上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521.抱着帮人解决问题的心态去跑了一遍代码.发现果真是这样. ...

  7. Python破解js加密实例(有道在线翻译)

    在爬虫爬取网站的时候,经常遇到一些反爬虫技术,比如: 加cookie,身份验证UserAgent 图形验证,还有很难破解的滑动验证 js签名验证,对传输数据进行加密处理 对于js加密经过加密传输的就是 ...

  8. 秒秒钟破解eval加密

    前言  准确的说eval处理过的代码应该叫做压缩代码,不过效果上算是加密过了一样!很多小伙伴不想直接让别人看到自己的js代码往往就会采取这样的处理措施.不过,其实这样的方法只能防御那些小白.对于真正的 ...

  9. 博主有偿带徒 《编程语言设计和实现》《MUD游戏开发》《软件破解和加密》《游戏辅助外挂》《JAVA开发》

    <考研专题>操作系统原理 理论解答:8K 实战 1.5W CPU设计 理论解答:1W 实战 2.5W <编程语言设计和实现>初窥门径<5K>:编译原理.编译设计小试 ...

随机推荐

  1. 手把手教你自动生成Makefile

    概述:autoconf/automake工具用于自动创建功能完善的Makefile文件,接下来简单介绍一下,如何使用上述工具 自动生成Makefile 前提:安装autoconf工具(ubuntu:s ...

  2. 【Construct Binary Tree from Inorder and Postorder Traversal】cpp

    题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume ...

  3. 三门概率问题之C#版

    前言: 早上看到一片关于三门问题的博客http://www.cnblogs.com/twocats/p/3440398.html,抱着该博客结论的怀疑态度用C#语言写了一些代码.实验证明该博客的结论是 ...

  4. sql语句not in判断条件注意事项

    sql语句not in判断条件注意事项 问题描述:mysql数据库,存在两个表org表和kdorg表,用于存储组织信息.现在我需要从org表找出组织,条件为该组织不在kdorg表里. sql语句:se ...

  5. python-面向对象(指数对象举例)

    class Index(object): def __init__(self,index_name,index_code,closePrice_yesterday,closePrice_today): ...

  6. 【BZOJ】【1028】【JSOI2007】麻将

    暴力/模拟 $n\leq400$,嗯……这是一个很小的数据范围= = 判断一副牌是不是听牌并求出听什么牌太麻烦了,干脆我们直接判是不是胡牌好了~ 枚举胡的是哪张牌,然后判一下加上这张牌后是否能胡. 算 ...

  7. Spring3.0实现REST实例

    关于REST是什么东西,在这里我就不再多说,大家可以去http://blog.csdn.net/pilou5400/archive/2010/12/24/6096861.aspx看看介绍,直接切入主题 ...

  8. Java compiler level does not match the version of the instal

    一.问题描述 新建了一个项目,workspace默认jdk编译版本是1.7的,新建项目使用的是jdk1.5的版本,肯定会报@override错误.这个时候,修改项目的compilor即可. 这时候,你 ...

  9. GameMap(类结构)(不断跟新)

    暂时有个疑问为什么这些需要这么复杂的继承

  10. date format 精辟讲解

    link: http://stackoverflow.com/questions/19533933/nsdateformatter-how-to-convert-wed-23-oct-2013-045 ...