| 本帖最后由 漆黑之翼 于 2014-10-8 22:19 编辑 
 
 前言: 天壤大乱斗(或者是天壤的暴风雨?)是用DxLib写的游戏,而DxLib的游戏最常用的打包方式就是用自带的DxArchive来进行解包打包。只要找到key就能把资源解出来。作为一个水平非常业余的破解者,求各位奆奆指点  。
 首先打开IDA加载game.exe,默认选项就行了。接着我们的目标是找出DxArchive用于加密的Key。 一、 一般向思路 Shift+F12打开字符串视图,找到包含资源文件文件名的字符串(Resource、Resource1……)。 
 接着双击该字符串来到反汇编视图,将光标定位在字符串的名称(如:aResourceVer_10)上按X查找引用。 跳到引用位置按F5反编译,运气好的话可以在附近看到把可疑的字符串作参数调用的函数。
   如果双击跟进这个函数之后看到拿字符串长度跟12作比较的话,那么这个很有可能就是Key(参考DxArchive的实现,Key最长只接受12个字符)。用DxLib自带的解包工具试试就清楚了。(这里在源码中的对应函数是DXA_DIR_SetKeyString)
 
   我一开始就是运气好直接找到key了
  ,运气不好的话……只能跟到解码循环里面根据变量引用找回去了……好麻烦……不想写了  看方法二吧。方法二是我后来想出来的,应该对使用DxArchive默认实现的游戏都适用。 
 
 二、查找特征码 看看DxArchive的源码就能发现,在把字符串Key转换为二进制Key的时候往memset压了两个常量,一个是0xaa,一个是0xc。这么长的指令说不定可以利用一下。
  我们可以写个Dxlib的demo调过去,看看msvc生成的反汇编字节码。 
   接着在IDA的反汇编视图按Alt+B搜索二进制序列:6A 0C 68 AA 00 00 00。(向下搜索的时候最好先把滚动条拖到最上面)
 
   接着F5反编译,看着跟DxArchive的源码挺像的。
 
   接着光标定位strlen函数按Tab切回反汇编视图下断点。
 
   然后选择调试器按F9开始调试
 
   断下来后双击edx就能看到Key啦。
 
    
 得到Key后:
 用DxLib提供的DxArchive解包工具写个批处理:
 
 执行之,就把资源解出来了。我们看Resource的目录结构,大部分作用都很明显。复制代码DxaDecode.exe -K:alice ./Resource.lhd
DxaDecode.exe -K:alice ./Resource1.lhd
DxaDecode.exe -K:alice ./Resource2.lhd
DxaDecode.exe -K:alice ./Resource3.lhd
DxaDecode.exe -K:alice ./Resource4.lhd
  Fnt应该就是指字体了,不过里面一大堆dat文件有点奇怪啊,用文本编辑器打开看看。一看文件头,原来是个图片。后缀改成png打开后发现原来是字库……
 
   而srd文件用文本编辑器打开可以发现是Shift-JIS编码的剧情脚本。
 
 
   
 字库替换:
 资源中的字库文件为四张图片a0, a1, b0, b1,每种颜色两张。根据IDA查找引用能找到读取的代码,然后找到使用的地方。游戏实际只使用了其中的蓝色字体。根据IDA反编译可以看到定位文字在图片中位置的方法:
 配合图片可以推断每行有0x2E个字,每个字大小为0x16像素,每个文件有0x10B6个字。那么0x8140是怎么来的呢?这里可以参考维基百科的Shift-JIS条目,其中提到Shift-JIS编码的第一位字节从0x81开始、第二位字节从0x40开始,合起来就是0x8140。0x8140对应的是全角空格,刚好是a0图片中的第一个字符。现在定位的方法就很明显了,先找到要画的字是从0x8140开始的第几个字,然后找到在哪一页,再找到是第几行第几列。复制代码srcX = 0x16 * (uCharByte - 0x8140) % 0x10B6 % 0x2E
srcY = 0x16 * (uCharByte - 0x8140) % 0x10B6 / 0x2E
汉化的话因为原来是用Shift-JIS编码,所以首先要把脚本文件转成中文编码GB2312。重新打包后可以看到对话是不能正确显示的,这时就要根据上面的规则自己生成一个字库了。
 首先要考虑的是起始字符。GB2312的起始字符是0xA1A1,但因为标准GB2312字符集是不包含繁体字的,所以最好根据GBK来生成字库。GBK的编码范围为0x8140~0xFEFE所以0x8140就可以不用改了。
 因为字库变大了,所以接下来要考虑要增加文件还是在原来的基础上加。不过因为天壤的字库的句柄是存在固定大小的全局数据里面的,安全起见就不加文件了。0x8140~0xFEFE共 0x7DBF个字符,为了少改代码维持原来每行0x2E个,需要0x2BB行。两个文件的话每个文件就要0x15E行,每个文件放0x3EE4个字。代码上只需要把0x10B6替换成0x3EE4就可以了。
 最后生成好字库把原来的替换掉,然后重新打包一下。效果如图:
 
   最终效果
 (我觉得有人来翻译的话就可以开始汉化了:
   
 |