搜档网
当前位置:搜档网 › 安卓软件APK编译反编译与汉化高级篇

安卓软件APK编译反编译与汉化高级篇

安卓软件APK编译反编译与汉化高级篇
安卓软件APK编译反编译与汉化高级篇

这里以汉化愤怒的小鸟为例。

已经帮大家整理了一些汉化的教程,但是那些教程只能汉化软件和一些简单的游戏,对于大部分游戏来说,以前的教程可能不适用了,有的是找不到需要汉化的字符,有些是找不到需要汉化的图片。这里为大家整理一个游戏的汉化教程,希望对大家有所帮助,这里以汉化愤怒的小鸟为例。

winrar解压开apk文件后,怒鸟的图片都放在assets\data\images\目录下,里面的文件分为4种:

1、pvr

*.dat:图片管理数据。因为大部分的素材都是很多个一起放在同一个图片文件里,这类文件的作用就是在同名的图片文件中标记出各素材的位置和大小,后面会简略描述下其结构。

*.pvr:主要的图片格式文件,基本为16位色图片,主要分R4G4B4A4和R5G6B5A0两种,后面会较为详细地介绍其结构。

*.png:标准图片格式,不再多讲。

*.zip:解压后为pvr文件,注意修改替换后要压缩回去即可,也不再多讲。

本帖隐藏的内容

首先说一下pvr图片的查看问题,下载软件UltraEdit-32

https://www.sodocs.net/doc/b49438008.html,/file/bhqc91l5,然后用UltraEdit-32打开PVR文件其结构如图:

文件头部:长度34h

00h~03h:4字节,文件头长度,基本是固定的34h

04h~07h:4字节,图片高度

08h~0Bh:4字节,图片宽度

0Ch~0Fh:4字节,固定为00h

10h~13h:4字节,固定为8010h

14h~17h:4字节,图片数据长度(不包含头部)

18h~1Bh:4字节,固定为10h,应该是颜色位数

1Ch~1Fh:4字节,固定为F000h,B位段,意为最高4位对应蓝色

20h~23h:4字节,固定为0F00h,G位段,意为相应4位对应绿色24h~27h:4字节,固定为00F0h,R位段,意为相应4位对应红色

28h~2Bh:4字节,固定为000Fh,A位段,意为最低4位对应Alpha通道,即透明度

2Ch~2Fh:4字节,文件标识"PVR!"

30h~33h:4字节,固定为01h

图片数据:2字节对应1像素,颜色分配按照如上所述。

上面是R4G4B4A4的情形,R5G6B5A0的如下图:

文件头部:长度34h

00h~03h:4字节,文件头长度,基本是固定的34h

04h~07h:4字节,图片高度

08h~0Bh:4字节,图片宽度

0Ch~0Fh:4字节,固定为00h

10h~13h:4字节,固定为13h

14h~17h:4字节,图片数据长度(不包含头部)

18h~1Bh:4字节,固定为10h,应该是颜色位数

1Ch~1Fh:4字节,固定为F800h,B位段,意为最高5位对应蓝色

20h~23h:4字节,固定为07E0h,G位段,意为相应6位对应绿色

24h~27h:4字节,固定为001Fh,R位段,意为最低5位对应红色

28h~2Bh:4字节,固定为0000h,A位段,固定为不透明

2Ch~2Fh:4字节,文件标识"PVR!"

30h~33h:4字节,固定为01h

图片数据:2字节对应1像素,颜色分配按照如上所述。

另外,BMP图片的结构为(简便起见,仅对我们要转换到的32位色而言,详细的结构数据可以去google"BMP文件结构")

00h~01h:2字节,文件标识"BM"

02h~05h:4字节,文件总长度,在这里是"宽度*高度*4+36h"

06h~09h:4字节,00h

0Ah~0Dh:4字节,像素数据开始地址,36h

0Eh~11h:4字节,位图信息部分数据长度,28h

12h~15h:4字节,宽度

16h~19h:4字节,高度

1Ah~1Dh:4字节,200001h

1Eh~21h:4字节,00h

22h~25h:4字节,00h

26h~29h:4字节,00h

2Ah~2Dh:4字节,00h

2Eh~31h:4字节,00h

32h~35h:4字节,00h

36h~末尾:4字节对应1像素,分别为ARGB数据。

注意:BMP文件中,像素数据按照从下到上、从左到右顺序排列,即先保存图片最后一行的像素数据,最后才是第一行。

根据这些信息,我们很容易将其转换为32位色BMP图片,以R4G4B4A4为例,得到的R、G、B、A数据都左移4位,下图即为BUTTONS_SHEET_1.pvr 转换后得到的图片。

修改的时候要注意Alpha通道的影响,然后再按照pvr的格式转换回去。转换的时候要注意,因为我们实际修改的是32位色的图片,而pvr是16位色,色板的缩减就成了一个问题,一般的处理办法有两种:

1、修改图片时注意选色,尽量只是用原图片里有的颜色。这样的时候只需把R、

G、B、A数据再右移4位就好了(以R4G4B4A4为例);

2、在转换程序中设定近似颜色的取法,即R、G、B、A数据的低4位不为0时如何选取数值。这样做的优点是在修改图片,尤其是使用一些颜色渐变效果时不用顾忌

太多,但转换得到pvr文件后最好再用之前的程序转回BMP看一下,确实颜色变动是否有大的影响。

2、dat

下面的问题就是如何修改了,虽然我们得到了素材图片,但是这个图片并不是可以随意修改的,因为每项素材所占用的矩形区域并没有在图片里标注,贸然修改可能导致图片显示不全或者不需要修改的图片被改动等问题。这时就要分析下*.dat文件的结构:

这里因为不涉及dat文件的修改,而是仅仅从中获取信息,所以只做简单分析:

文件头部包含有文件长度,对应图片文件名等信息,图片含有素材个数等信息,掠过不看。其后,对应每个素材的数据按照如下方式排列

2字节:标签字符串长度

若干字节:标签字符串

2字节:素材左上角的横坐标(最左端为0)

2字节:素材左上角的纵坐标(最上端为0)

2字节:素材宽度

2字节:素材高度

4字节:不确定,因为前面的信息已经足够了

举例:第一个素材,标签为MENU_BUTTON,位置在坐标(366,89)处,宽高都是65。

有了这些信息,我们就可以放心的修改图片了,例如我们把BUTTONS_SHEET_1.pvr中的"开始游戏"修改成接近游戏原"PLAY"字体的风格。

至于为什么不是修改游戏原本显示的"PLAY"而是图片里面的"开始游戏",这会在文本汉化部分提到。

本帖最后由回归_Ju 于 2011-10-20 21:02 编辑

愤怒的小鸟文字汉化(1)——字库

一般来说,游戏汉化中,文字汉化相对于图片要更为重要和困难些,当然,也有些游戏只需要汉化图片就够了。这一章继续以怒鸟为例,讲解一下文字汉化的方法。

通常文字汉化需要考虑两个对象:字库和文本。

有些游戏使用的是手机系统自带的字库,对于这类游戏我们就只需要关注于文本了。但是还有很多的游戏为了画面和文字风格的需要,选择使用特殊设计的字体,那么相应的,要为之配上专门制作的字库。

对于字库,可以将其理解为很多张图片的集合,每张图片的内容是一个个字符,并且每张图片拥有一个唯一的标号,这个标号我们通常称之为编码。看完后面的内容可以帮助你更好地理解前面这段话。

怒鸟的字库数据文件放在都放在assets\data\fonts\目录下,我么可以看到其文件类型和图片部分是一致的,这章主要讲解一下字库的调用

方式,以及如何利用其达到显示汉字的目的。

我们可以继续使用上一章的方法来将FONT_BASIC.pvr转换成可以直接查看的BMP图片,如图:

我们可以看到在这个图片里包含有大量字符的图片,包括英语、简/繁中文、日语假名等。我们将这个字库文件的作用按下不谈,先继续看与之相应的dat文件的结构。

00h~03h:文件标识"KA3D"

04h~07h:文件长度(从08h到末尾)

08h~0Bh:数据段标识"FONT"

0Ch~0Fh:数据段长度(从10h到末尾)

10h~11h:2字节,不确定功能,保留即可

12h~13h:对应字库(图片)名称字符串长度

14h~21h:对应字库(图片)名称字符串

22h~25h:4字节,不确定功能,保留即可

26h~27h:字库中的字符(素材)个数

28h~末尾:位置数据,每个字符使用12字节来记录,共032Ah个字符

其他的dat文件可以类似分析。

位置数据:0Ch字节

00h~01h:字符编码(Unicode编码)

02h~03h:字符位置横坐标(左上角)

04h~05h:字符位置纵坐标(左上角)

06h~07h:字符宽度

08h~09h:字符高度

0Ah~0Bh:未知数据

类似于上一章中图片的情况,我们可以看到,字库中每一个字符的图片被作为了一个单个的素材,我们举例说明一下其调用方式。

首先,游戏要显示的文字,被以Unicode编码的形式一个一个调用出来,比如游戏想要显示"權"这个字,其Unicode编码为"6B0A",那么游戏会在FONT_BASIC.dat文件中对“位置数据”逐个对比寻找,看是否有某项的

Unicode编码和"權"字相同,我们很容易就能找到地址0040h处的这项:

0040:6B0A 015F 00BD 001B 001B 0012

即其位置在(351,189)处,宽度和高度都是27。

找到后,游戏就根据其后面的位置数据,将字库图片中的某块素材截取出来,显示在屏幕的指定位置。也就是把"權"这个字符显示了出来。

而如果游戏在dat文件中没有找到一致的项,就会出现文字显示不出或者死机等问题。

事实上,操作系统(包括Windows或Android等)其字符的显示原理都与此类似,只不过他们所使用的"字库图片"更大更全,而不是像这个游戏一样只能显示少部分被指定的字。当然,我们也可以通过修改dat和pvr文件,增加其长度来让游戏支持更多的字。

了解了文字的显示原理后,我们就可以进行下一步的文本汉化了。

本帖最后由回归_Ju 于 2011-10-20 21:09 编辑

愤怒的小鸟文字汉化(2)——文本

了解了字符显示的原理后,我们就可以修改游戏文本来显示出我们希望的字符了。

首先看一下游戏的文本是如何存储的。

怒鸟几乎所有的文本都存放在assets\data\localization目录下的TEXTS_BASIC.dat文件,下面对其结构进行简单说明:

00h~03h:固定00h

04h:语言分类段长度(39h)

05h~3Dh:长度39h字节,语言分类段

3Eh~3Fh:文字项个数(71h)

40h~079Bh:文字项标识(71h个)

079Ch~07BBh:4字节1项,共8项,各语言文字项相对偏移(相对于每项结尾)

07BCh~结尾:各语言文字项顺序存放,每种语言71h项。

注:每个文字项结构为,2字节长度数据+字符串(字符串不带有00h作为结束标记)

其中,相对偏移可能不太好理解,可以自行用16进制编辑器打开该文件进行查看,看下每种语言的文字开始于什么位置,实际操作下有助于理解。

看得出来,这个文件本身包含8种语言的文本,我们需要的是其中的英语和简体中文部分。

下一步就是将文本导出成txt文件,方便直接查看和翻译。

在TEXTS_BASIC.dat中使用的是UTF-8编码,而上一章中我们说过的字库里

面用的是Unicode编码,这两种编码是可以比较容易地相互转换的,转换方法如下:

------------------------------------------

| UTF-16 | UTF-8 |

|----------------------------------------|

| 0000-007F | 0xxxxxxx |

| 0080-07FF | 110xxxxx 10xxxxxx |

| 0800-FFFF | 1110xxxx 10xxxxxx 10xxxxxx |

------------------------------------------

之所以要提到转换,是因为我们在翻译结束后还需要对使用的字是否在在库里进行判断(没有的话就需要改变翻译或者添加这个字到字库)。

导出后的文本如下图(仅为例子,这个结构由编写的程序决定,可以根据自己的习惯来设计格式):

1.0000=Select$

2.……

3.0021=Vibra: OFF$

4.0022=Continue game$

5.0023=Pause$

6.0024=Level selection$

7.0025=Options$

8.0026=Play$

9.0027=Settings$

10.0028=About$

11.0029=More Games!$

12.0030=Edit$

13.0031=Settings$

14.……

复制代码

下一步是根据游戏进行翻译,因为里面大部分的内容实际上在游戏里并没有显示,我们只选出需要的句子翻译就可以了,翻译内容可以参考下原本自带的中文文本,毕竟是官方翻译。

1.0000=Select$

2.……

3.0021=Vibra: OFF$

4.0022=Continue game$

5.0023=Pause$

6.0024=Level selection$

7.0025=Options$

8.0026=开始游戏$

9.0027=Settings$

10.0028=About$

11.0029=更多游戏!$

12.0030=编辑$

13.0031=Settings$

14.……

复制代码

翻译的时候一般需要确认下对应的句子在游戏里是不是有显示,很多文字在游戏初期设计的时候有,但是后来又会因为各种原因放弃显示,因此在导出的文本中可能会有很多句子是没有用处的。这样的就不需要翻译了。

然后我们根据翻译好的文本重新生成TEXTS_BASIC.dat文件,事实上只需保留原本的英文部分(已翻译),其余语言对应部分留空即可。

文本导入后并不意味着工作结束,前面说过,只有字库所支持的字才能被显示,所以下一步我们需要确认使用的汉字是否都被字库所支持,不支持的话就要在字库里添加。同时原字库的字体略显呆板,和英文的字体风格不一致,也可以一并修改下。此外还要注意,游戏在不同屏幕大小下有两个不同的字库,都要做相应修改才可以。

这样,我们的游戏就基本汉化完成了,可以打包安装试玩一下,看看还有没有哪里遗漏。

本帖最后由回归_Ju 于 2011-10-20 21:13 编辑

愤怒的小鸟汉化补遗

图片修改、文本导入后可以发现,仍然有两个句子是英文的,一个是章节选择画面下的"Golden eggs",一个是退出时要求确认的句子。

另外,我们还要修改下应用名称,改为中文"愤怒的小鸟",并且可以考虑把广告去掉。

其中遗漏的文本经过搜索可以在assets\data\scripts目录下的gamelogic.lua文件里找到,经测试,这个文件里不能使用中文编码,虽然不会引起死机,

但是文字会显示不出。其中的"Golden eggs"我们可以用一个同样长度的文本标签替换掉,借助其显示中文;而后面那句话比较长,没有合适的标签,所以最终只保留了一个单词"QUIT?"。

修改应用名称可以参照第二章软件汉化,用apktool反编译后在strings.xml文件里找到并修改。

去广告同样需要反编译,然后再*.smali文件中搜索"http",修改其中的链接到广告的网址,例如把地址都改为"127.0.0.1"(本机回送地址),这样广告就无法下载和显示了。

这样,我们的游戏才算基本汉化结束。之后还要进行实机测试来确保图片以及文字都显示正确。

后面几章的叙述稍微有些笼统,一方面是汉化的方法并没有固定的要求,很大程度上取决于个人习惯和经验,另一方面不同的游戏一般都需要不同的方法,可以借鉴思路而不适合照办。

实际的操作中需要很熟悉16进制下的数据查找和计算,并且能敏锐把握到文件的内部结构,否者很多修改都会无从下手,或者修改后引起各种各样的错误。

最后列举下一般的自带字库的文字汉化流程,仅供参考,很多时候一些步骤可以省略:

1、分析文本编码,可以在16进制编辑器下手动修改数据看显示效果。其中Unicode编码比较容易认出,而ASCII、UTF-8、ANSI、SJIS 等编码使用相同的文字编码来显示英文,很多时候不容易区分开。

2、分析文本结构。例如上一章中的TEXTS_BASIC.dat文件,只有弄清楚了结构才能修改。

3、导出文本。这一过程很多时候需要自己写程序来完成,因此破解一般至少需要掌握一门编程语言。

4、翻译。无需多说。

5、统计使用字符。用于下一步。

6、分析字库结构,并根据统计出的使用了的字符重新构建字库。

7、导入文本。

8、测试效果。

其中第1、2和6步可以放在最前面做,用于判断文字汉化的可行性。很多时候我们会发现文字汉化“无法”进行,比如遇到单字节编码方式(ASCII),或者文本/字库结构分析不出来(导致无法修改),或者字库大小受到限制(无法添加统计出的使用了的字符)等等。

本帖最后由回归_Ju 于 2011-10-20 21:20 编辑

smali文件中文本的处理

相信跟着前几章操作过的读者可以发现,有相当一部分游戏的汉化方法和软件是类似的,只要会使用apktool反编译apk文件,然后修改xml文件里面的文字就能完成汉化工作。这类游戏很适合新手来尝试,类似于怒鸟那样的游戏汉化起来就相对复杂,最好积累了足够经验后再进行。

这章我们会用一个简单的游戏来说明下游戏汉化的过程,大部分的操作和第二章里的软件汉化是类似的,主要是想用通过其说明下classes.dex文件中(反编译后为若干smali文件)文本的处理方法和注意事项。

首先可以下载到我们要汉化的游戏。

然后用apktool对apk文件进行反编译。

查看后发现,strings.xml文件中只有一个"Find It Disney",这是游戏在手机里显示的名字。其他的文本,例如菜单项的内容都不在这里。

对于这样的文本我们有两种处理办法:

第一种是逐个打开反编译出的xml文件,看里面是不是有需要翻译的

文本。一般推荐按照这个进行,虽然每个都打开看比较麻烦,但是可以最大限度地避免出现遗漏。

第二种是利用软件的搜索功能,一般这个方法更多地用在查找遗漏的文本,因为未必所有文字都能找到合适的关键字。

我们先用第一种方法,大部分的文本在layout文件夹下的xml文件里,例如mainmenu.xml中是菜单里的文字。(仅截取部分)

1.……

2.