首页
社区
课程
招聘
[原创]Galgame汉化中的逆向 (一):文本加密(压缩)与解密
发表于: 2020-6-6 10:48 14871

[原创]Galgame汉化中的逆向 (一):文本加密(压缩)与解密

2020-6-6 10:48
14871

看到关于游戏汉化相关的逆向教程挺少的,作为某汉化组的成员也帮过别的汉化组,于是就想把我见到的几个典型的例子整理分析一下,还是挺有意思的。此教程和我在贴吧和隔壁发的一样。

这个游戏还是很典型的,cpk封包,文本应该在sn.bin里面。
打开一看没有明显的字符,而且数据看起来很紧凑,应该是压缩或者加密了。

相比与主机游戏ida费劲的静态分析,pc动态调试真是太舒服了。
找文本很简单,等游戏运行起来后直接暂停,搜索内存sjis字符串。比如说“椿子”。
然后记住这个地址(或附近的某个),下硬断点write,重新启动游戏运行,游戏中断在这里。
图片描述

图片描述

然后顺腾摸瓜,我们能看到了解密函数,只不过这个游戏奇怪,
用了eax和ecx传参(之后分析这个应该是指向了全局变量),
进一步分析发现eax应该是解密后的缓冲区,ecx是sn.bin文件缓冲区。
这里提取解密后的文本可以直接memdump了,
其实汉化游戏我们甚至可以不管它用了什么加密,直接hook这里然后替换为其他缓冲区。
但是这样就没有分析的意义了,为了练习和游戏封包兼容性,我们最好还是要去分析算法。

怎么进行反汇编?
方便的办法是直接用ida的f5,但是这里我不想太依赖插件,就去直接看汇编代码了。
如果写汇编程序不多的可以先用c语言写一个接近汇编的版本,测试结果正确后,
然后再从这个版本中继续写一个接近于人写的程序(合并中间变量,改变量名),这样就方便逆向算法了。用接近汇编的C语言如下:

初步分析后,我们大概熟悉了算法流程。
然后可以用c语言写一个人能理解的版本了:

并且可以总结出怎么来解密文本了。

sn.bin 结构
0x0 size 4
0x4~ data

data部分第一字节为索引,每一位代表当前byte的状态,
索引为1:直接copy当前byte到环状缓存区
索引为0:则表示当前byte和下一个byte是索引,高12位为位置,低4位为长度。
环状缓存区大小0x1000,起始位置0xFEE。

顺便说一下位运算充当循环遍历的方法吧,
​a = 0b0011111, a>>1需要移位5次a=0,则循环次数是5

测试一下文本没问题:


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-6-18 17:57 被kanxue编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (17)
雪    币: 6266
活跃值: (1276)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
没想到论坛还能看到这种帖子,NB
2020-6-6 11:04
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
3
呐呐呐呐呐
2020-6-6 14:44
0
雪    币: 796
活跃值: (2044)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4

2020-6-6 18:29
0
雪    币: 1556
活跃值: (2297)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
呐呐呐呐呐
2020-6-6 19:05
0
雪    币: 9934
活跃值: (2554)
能力值: ( LV6,RANK:87 )
在线值:
发帖
回帖
粉丝
6
呐喊
2020-6-6 21:57
0
雪    币: 6096
活跃值: (5515)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
7
感谢分享!
2020-6-8 10:01
0
雪    币:
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
8
呐呐呐呐~
2020-6-9 13:55
0
雪    币: 66
活跃值: (2746)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
以前无聊做过两次软件汉化,支持!!
2020-6-10 09:40
0
雪    币: 340
活跃值: (922)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
10
看到这种压缩块,保存出来,用quickbms 的 comtype_scan2.bat 跑一遍,说不定就找到压缩算法了。
2020-6-12 14:34
0
雪    币: 10017
活跃值: (3457)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
老二次元了
2020-6-12 14:58
0
雪    币: 6296
活跃值: (4962)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
12
noword_forever 看到这种压缩块,保存出来,用quickbms 的 comtype_scan2.bat 跑一遍,说不定就找到压缩算法了。
因为当时以为是加密没看出来是压缩,就去分析算法了
2020-6-12 15:52
0
雪    币: 340
活跃值: (922)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
13
devseed 因为当时以为是加密没看出来是压缩,就去分析算法了
如果是加密,一般不会有这么多\x00
2020-6-12 16:47
0
雪    币: 2171
活跃值: (476)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
各位都是老声呐了
2020-7-12 21:29
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15

太感谢了,游戏汉化教程确实太少了,学习一下。刚学习这块不久,有时会遇到网上资料查找也难以解决的情况,请问能向您请教吗(QQ/email之类),我是看到这篇帖子注册的,还无法发送私信。

最后于 2020-8-10 10:26 被wx_oo_557编辑 ,原因:
2020-8-10 10:19
0
雪    币: 199
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
有点问题想不通,按照一般编程习惯,解压数据不应该是动态申请的内存块吗?这样下写断点,如何保证游戏重启后依然会是同样的地方因为解压而触发写断点?当然,不排除一开始就定义足够大的全局数组保存解压数据的另类。
2021-8-20 12:08
0
雪    币: 6296
活跃值: (4962)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
17
Otoboku 有点问题想不通,按照一般编程习惯,解压数据不应该是动态申请的内存块吗?这样下写断点,如何保证游戏重启后依然会是同样的地方因为解压而触发写断点?当然,不排除一开始就定义足够大的全局数组保存解压数据的另类 ...
所以不是所有情况都有效,如果malloc需要在virtualalloc函数下断点、
2021-8-20 22:12
0
雪    币:
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mz1
18
感谢师傅的分享,想请教一下x32dbg里怎么才能搜索sjis字符串啊,我只能先用记事本写了然后16进制打开再搜索这个16进制才能做到,跪求师傅点播一下下。
2021-11-3 13:56
0
游客
登录 | 注册 方可回帖
返回
//