« 1 23» Pages: ( 1/3 total )
本页主题: Galgame 汉化破解初级教程:以 BGI 为例,从解包到测试  上一主题 | 下一主题 | 底端
[使用道具]
amemiya
まい散る空へ
级别: 学生会副会长

精华: 1
发帖: 1395
学分: 66 点
澄空币: 4825 KID
GPA: 0 点
注册时间:2008-05-11
最后登录:2019-09-30


 Galgame 汉化破解初级教程:以 BGI 为例,从解包到测试

管理提醒:
本帖被 乙津夢 执行加亮操作(2015-06-21)
囧,CK 这边的编辑器是 WindCode,也不能直接插入 HTML,只能大概排一下版了。对排版和格式有高要求的同学请看这里

  转载请注明出处。



Ever tried. 
Ever failed.
No matter. 
Try again.
Fail again. 
Fail better.


一直想写一篇面向新手的 Galgame 汉化教程,但一直苦于没有时间。现在终于考完了试,申请也告一段落,这才抽了点时间来写这篇文。还有,工口你认真学,今后杏爱会的程序就看你的了。

本教程假设你已经满足以下条件:

  • 玩过 Galgame,了解一般 Galgame 资源存储的方式
  • 会一门编程语言,VB6 和 JavaScript 等前端语言除外
  • 能看懂用其它编程语言写出的源代码,此处特指用 C++
  • 能看懂汇编,51 单片机的汇编语言就行
  • 懂数据结构
  • 知道什么是字符编码
  • 英语水平还说得过去
  • 懂一点儿日语

本教程中使用的名词:

  • 封包:指游戏的资源文件在游戏安装目录下的保存形式
  • 脚本:含有二进制控制符和纯文本的文件
  • 文本:从脚本中提取,人类能够读懂的文本文件

首先来看看破解都要干啥:

  • 解开游戏的封包文件
  • 从提取出的脚本中提取出文本
  • 从提取出的脚本中提取出图片
  • 把翻译好的文本写回到脚本里
  • 把新的图片和脚本放回到封包里
  • 修改游戏主程序,使之能正常读取中文

好,让我们开始吧。

1. 准备

我们以方糖社的《花色ヘプタグラム》为例进行实战。不过在开始之前,你需要准备几种工具:
  • 一款支持多语言编码的文本编辑器,例如 Notepad2
  • 一款十六进制编辑器,最好也能支持多语言编码,例如 010Editor
  • 一款反汇编工具,例如 OllyDbg
  • 你常用的 IDE,比如 Visual Studio
工具的用法在此不再赘述,请自行谷歌。
安装游戏后打开游戏的主目录,你会发现这些文件(已略去部分无用文件):
Copy code
2012/09/26  16:33               643 autoload.arc
2012/09/26  16:33         1,817,109 data01000.arc
2012/09/26  16:33       876,414,725 data02000.arc
2012/09/26  16:33       654,502,744 data02001.arc
2012/09/26  16:33     1,179,169,979 data02010.arc
2012/09/26  16:33        12,594,853 data02050.arc
2012/09/26  16:33       299,065,396 data02100.arc
2012/09/26  16:33        21,874,416 data02950.arc
2012/09/26  16:33        14,331,692 data03000.arc
2012/09/26  16:33       922,747,352 data04000.arc
2012/09/26  16:33        75,902,855 data05000.arc
2012/09/26  16:33           860,160 Heptagram.exe
2012/09/26  16:33        34,148,877 sysgrp.arc
2012/09/26  16:33           290,498 sysprg.arc
2012/09/26  16:33         3,702,778 syssnd.arc
2012/09/26  16:33             2,825 system.arc


很明显,Heptagram.exe 是游戏的主程序,*.arc是游戏的封包文件。接下来,我们开始正式的流程。

2. 破解

2.1. 运行破解


双击 Heptagram.exe 来测试一下,发现没有出现游戏主窗口;而用 AppLocate 工具加载后却能够正常运行。这说明开发商在游戏中进行了某种检查,以防止游戏在日本日外的国家运行(原因大家都知道,而且还有家中二公司把这点做到了极致)。

好,让我们想一想,如何得到当前操作系统的区域信息?



透露一下,BGI 引擎使用 GetSystemDefaultLangID 来确定当前操作系统的区域。
运行 OllyDbg,载入 Heptagram.exe,如图。



按下 CTRL + N,在打开的 API 列表中找到 GetSystemDefaultLangID,右键选择“在每个参考上设置断点”。如图。




双击 Breakpoints 窗口中的项,来到 GetSystemDefaultLangID 的调用位置:
Copy code
00455CE0  /$  FF15 D0E04A00 call    dword ptr [<&KERNEL32.GetSystemD>; [GetSystemDefaultLangID
00455CE6  |.  8B5424 04     mov     edx, dword ptr [esp+4]
00455CEA  |.  25 FF030000   and     eax, 3FF
00455CEF  |.  33C9          xor     ecx, ecx
00455CF1  |.  3BC2          cmp     eax, edx
00455CF3  |.  0F94C1        sete    cl
00455CF6  |.  8BC1          mov     eax, ecx
00455CF8  \.  C3            retn

在简体中文环境下, GetSystemDefaultLangID 返回值是 0x804,而在日语环境下,返回值是 0x411。那么怎么改?很简单,直接把 0x411 写入返回值的寄存器就行了。这样,无论是什么语言的系统,都会被认为是日语系统。
双击 00455CE0 这一行,把汇编改为 mov eax, 411。改好后的这部分代码如下所示:
Copy code
00455CE0      B8 11040000   mov     eax, 411
00455CE5      90            nop                ;修改后的代码比原先的要短,所以剩余的部分会用 nop 补齐
00455CE6  |.  8B5424 04     mov     edx, dword ptr [esp+4]
00455CEA  |.  25 FF030000   and     eax, 3FF
00455CEF  |.  33C9          xor     ecx, ecx
00455CF1  |.  3BC2          cmp     eax, edx
00455CF3  |.  0F94C1        sete    cl
00455CF6  |.  8BC1          mov     eax, ecx
00455CF8  \.  C3            retn


改好之后,在 CPU 窗口右键,复制到可执行文件 -> 所有修改 -> 全部复制,再在弹出的窗口中右键,保存文件,命名为 Heptagram_NoCheck.exe,完成后退出 OllyDbg。

接下来找到刚保存的 Heptagram_NoCheck.exe,双击运行,游戏界面是不是出来了?

2.2. 游戏脚本

2.2.1. 解包

这一步可以说是整个汉化过程中最简单的了(当然,这是建立在前辈们的辛苦分析上的):用老毛子出品的 AnimED 即可(不推荐使用 Crass)。

从 BGI 汉化经验来看,脚本文件一般都保存在前几个封包中(本游戏的脚本就在 data01000.arc 中)。如果你找不到,你可以把封包逐一拖到 ExtractData 窗口中观察。单个脚本的大小一般不会超过 200KB。

使用 AnimED 解开 data01000.arc ,拿到脚本(同样,略去了部分文件):
Copy code
2013/01/13  16:31            64,740 a01
2013/01/13  16:31            72,838 a02
2013/01/13  16:31            76,598 a03
2013/01/13  16:31             6,433 b06_3
2013/01/13  16:31            47,365 b07_1
2013/01/13  16:31            71,012 b07_2
2013/01/13  16:31            92,156 c06_2
2013/01/13  16:31            77,374 d09
2013/01/13  16:31            79,352 d10_1
2013/01/13  16:31             1,712 main
2013/01/13  16:31             3,150 s_ci_02
2013/01/13  16:31           110,513 Yuzuriha
2013/01/13  16:31           128,763 _01
2013/01/13  16:31            93,819 _02
2013/01/13  16:31           154,264 _03
2013/01/13  16:31           100,339 _07
2013/01/13  16:31           268,696 _08
2013/01/13  16:31            28,475 _10_2

打开准备好的 Notepad2,载入其中的 _01 文件,然后按下 F8,选择 Japanese (Shift-JIS)。你会发现,这个文件就是游戏的第一章:



2.2.2. 二进制脚本分析

在打开的 _01 文件中,你可以看到不可读的二进制代码和可读的文本混在一起。接下来,打开你的十六进制编辑器,载入_01 文件。



如图所示,BGI 脚本分为四部分:

  • 头部 Magic:用于校验该文件的类型
  • 脚本头部:定义了该脚本所需的全局变量
  • 指令部分:控制游戏的流程
  • 文本列表:我们最感兴趣的东西


在游戏执行中,引擎不断地读取指令部分中的指令,形成了游戏的时间线。 可以看出,0x00000003 之后的四字节(DWORD)和下面文本列表中字符串 _01.txt (起始地址为 0x18D1C)有关:
Copy code
0x18D1C = 0x1C (MAGIC 长度) + 0x34 (头部长度) + 0x18CCC (0x00000003 之后的四字节)

如果你不放心,可以再找几句话计算看看。
那么,思路就确定下来了:
逐个读取所有的 0x00000003,把之后的四字节作为地址,修正后用来查找目标处的字符串。也就是
Copy code
String = GetStringAt(GetUnsignedIntAt(AddressOfAny(0x03) + 4) + LengthOf(magic) + LengthOf(header))


接下来,用你最擅长的编程语言写一个提取文本的工具吧。

2.3. 图片提取与转化

BGI 引擎的图片有两种格式:标准 BMP/PNG 和去掉文件头的 BMP。前者用于 CG 和立绘,后者用于系统图片(sysgrp.arc中的图片文件)。
注意:部分图片的像素排序是反转的,保存时也要保持反转排序(在 PS 的保存窗口中勾选翻转行序
注意2:如果图片含有 Alpha 通道,那么 Alpha 通道也要修!


2.3.1. 标准 BMP/PNG 文件

这些文件很好判断。对于 BMP 文件,文件头部总是 BM 两个字母;而对于 PNG 格式,文件头总是 {0x89, 0x50, 0x4E, 0x47}(写成中文的话就是 塒NG)。给解出来的文件添加相应后缀,用 Photoshop 打开即可。

2.3.2. 系统图片

让我们再次祭出十六进制编辑器。



如图,文件的钱六个字节分别是图片宽度,图片高度和色深。可以看出,sys_title_006 图片是一个 1280 * 720 的 32 位图片。
再次使用你最拿手的编程语言,写一个小程序来修复 BMP 文件头吧:请阅读 BeginBuildBMP 函数的代码

至此,资源破解结束。

3. 资源回封

3.1. 游戏脚本

脚本的回封很简单,照着提取工具写一个对应的逆运算就行了。注意,新文件中的汉字必须是 GBK 编码。

3.2. 图片

3.2.1. 标准图片

去掉后缀就行。

3.2.2. 系统图片

刚刚我们添加了 BMP Header,现在我们需要一个去掉 BMP Header 的工具:请阅读 BeginBuildResource 函数的代码

4. 测试运行

上面,我

  • “汉化”了一张 CG (ev_warn02 来自 data02010.arc):


  • 汉化了一张 系统图 (sys_title_006 来自 sysgrp.arc):

  • 汉化了 _01 脚本的前几句话:


把 ev_warn02 的后缀去掉,把 sys_title_006 的文件头去掉,把文本回写到 _01 中,生成新文件再重新命名为 _01。
完成后,把三个文件重命名为原本的名字,复制到游戏目录下。双击游戏,运行。





图片很正常,能用。可是脚本就没这么方便了:



出现了乱码。
这就不得不说字符编码和边界检查了。点击这里这里,仔细阅读肠姐姐的文章。
BGI 引擎中存在多处校验边界的代码,具体可以通过 OllyDbg 查找(CTRL+L)cmp al, 0A0 来定位(《花色ヘプタグラム》中只有两处)。
其它需要修改的地方:
  • CreateFontA 的 fdwCharSet 参数:改为 86 (其他游戏可能会有 CreateFontIndirectA 函数,后者要麻烦一些)
  • MultiByteToWideChar 的 Charset 参数:改为 3A8
  • cmp eax, 0EF40 ; 改为 0FE40
  • cmp ebx, 0EF40 ; 改为 0FE40
  • cmp ebx, 8140 ; 8140 是 Shift-JIS 编码中的全角空格,所以此处应改为 0A1A1 (GBK 的全角空格)

修改后保存主程序,再次运行,一切正常。




5. 后续工作

5.1. 字体

用十六进制编辑器打开刚刚运行成功的主程序,把所有MS 明朝(俵俽 柧挬),MS ゴシック(俵俽 僑僔僢僋),MS Mincho,MS Gothic 改为黑体,或 SimHei,别忘了把空余的字节全填上 0x00。

5.2. 窗口标题

从 system.arc 中得到 ipl._bp,用十六进制编辑器修改字符串。

5.3. (按需)人名乱码,下一句提示符乱码,方括号乱码

从 sysprg.arc 中提取相应的 ._bp 文件,用十六进制编辑器修改。下面的是完成品,补丁质量:





5.4. 补丁的注意事项

既然 BGI 不用封包就能读取汉化后的文件,那么在发补丁时怎么办?打补丁之后,游戏目录不得一下子多出几百个文件么?孩子,你需要 MoleBox

6. 接下来?

如果你觉得自己需要再次学习基本知识,请把这里所有回复大于 2 的主题帖读完。
如果你觉得自己能够挑战更高难度的破解,请点这里
如果你有任何疑问,请留言。
[ 此帖被amemiya在2014-05-15 23:49重新编辑 ]
顶端 底端 2013-01-14 01:08 | [楼 主]
IoriHayami
级别: 澄空文学社

精华: 0
发帖: 100
学分: 5 点
澄空币: 169 KID
GPA: 0 点
注册时间:2011-06-14
最后登录:2019-09-25


 

花色...
话说aya姐能帮艹下花色的程序么
虽然现在翻译是没什么问题...
顶端 底端 2013-01-14 02:16 | 1 楼
朝倉明日
级别: 澄空一年生下学期

精华: 0
发帖: 288
学分: 0 点
澄空币: 538 KID
GPA: 0 点
注册时间:2012-07-13
最后登录:2014-07-15


 

怒跪AYA菊苣!

怒保存網頁,此乃BGI引擎破解之寶貴教程!

學習了!

感謝菊苣分享!

話說NeXAS引擎的腳本貌似都有加密,正在解密中

還有,封包時可以分析專用的解包工具的keyword進行逆向封包的說...就是得看遊戲主程式能否加載罷了
[ 此帖被朝倉明日在2013-01-14 11:53重新编辑 ]
顶端 底端 2013-01-14 10:45 | 2 楼
恒の风
级别: 学生会会长

精华: 2
发帖: 10451
学分: 527 点
澄空币: 2069 KID
GPA: 0 点
注册时间:2005-05-28
最后登录:2019-09-24

 

我觉得你需要补充一句OllyICE和OllyDbg的关系。
人生很短,请多珍惜,不要浪费在无谓的事情上
顶端 底端 2013-01-14 16:36 | 3 楼
d49685268419
级别: 澄空新生

精华: 0
发帖: 18
学分: 0 点
澄空币: 663 KID
GPA: 0 点
注册时间:2012-11-04
最后登录:2013-04-20

 

感觉好像是为我们软件工程专业定制的~~~~~~

不过大二了我们还没接触到汇编和数据结构~~~估计等到大三应该就可以投身伟大的汉化事业了~~~~
顶端 底端 2013-01-14 17:09 | 4 楼
trigaharos
君の孤独を分けてほしい~ ♫
级别: 澄空一年生下学期

精华: 0
发帖: 477
学分: 0 点
澄空币: 495 KID
GPA: 0 点
注册时间:2011-12-28
最后登录:2019-10-01


 

技术贴啊啊啊啊啊~!! 一直很想自己玩破解和汉化之类的, 可惜没教程,
结果到现在还只会用C, C++, Java, C#编一些小程序.. 而且都是半吊子..
感谢LZ~~!! 立马保存~!!
顶端 底端 2013-01-14 17:29 | 5 楼
odyssey
级别: 澄空一年生上学期

精华: 0
发帖: 52
学分: 0 点
澄空币: 219 KID
GPA: 0 点
注册时间:2010-04-04
最后登录:2018-09-22

 

正是感谢楼主了,学习了!
顶端 底端 2013-01-14 18:54 | 6 楼
area11
级别: 澄空一年生下学期

精华: 0
发帖: 255
学分: 0 点
澄空币: 800 KID
GPA: 0 点
注册时间:2011-12-23
最后登录:2016-05-04


 

阿雅菊苣你需要再发一个脱AlphaRom这个日本Gal最常用的商业防拷壳的教程……
顶端 底端 2013-01-15 21:52 | 7 楼
xiayuanzhong
CROSS†CHANNEL完整汉化补丁已经发布!
级别: 澄空一年生上学期

精华: 0
发帖: 121
学分: 0 点
澄空币: 419 KID
GPA: 0 点
注册时间:2010-07-05
最后登录:2019-04-20

 

此贴甚好,本菜菜学到了很多,收获很多方法!~
谢谢LZ!~新年快乐
CROSS†CHANNEL 原版 & 复刻版 汉化 项目:
汉化组博客:crosschannel.cn
欢迎大家关注!~《少女们向荒野进发》同样欢迎大家~~
顶端 底端 2013-01-16 20:07 | 8 楼
galleryfake
级别: 澄空三年生上学期

精华: 0
发帖: 1697
学分: 30 点
澄空币: 599 KID
GPA: 1 点
注册时间:2006-05-21
最后登录:2015-05-09


 

我会告诉你其实为了看懂这贴我在刻苦学习编程中么
顶端 底端 2013-01-16 20:37 | 9 楼
风织翼
级别: 澄空一年生下学期

精华: 0
发帖: 259
学分: 1 点
澄空币: 612 KID
GPA: 0 点
注册时间:2009-11-12
最后登录:2014-11-02

 

Aya逼你看你的帖子招来了多少把你当发资源的句句拜的回复w
我是不是也该回一句:感谢句句分享,收下了?
乃们敢不敢先把程序日好了,把测试补丁出了再开坑?
顶端 底端 2013-02-13 09:05 | 10 楼
アルクェイド
级别: 澄空一年生上学期

精华: 0
发帖: 113
学分: 1 点
澄空币: 1349 KID
GPA: 0 点
注册时间:2008-04-13
最后登录:2019-10-01

 

感谢句句分享,收下了
顶端 底端 2013-02-13 18:34 | 11 楼
amaranthf
はい、変態です。
级别: 澄空三年生上学期

精华: 1
发帖: 302
学分: 159 点
澄空币: 914 KID
GPA: 0 点
注册时间:2008-11-23
最后登录:2019-08-30


 

这种时候应该说
1024
顶端 底端 2013-02-14 17:58 | 12 楼
SOST
级别: 澄空一年生下学期

精华: 0
发帖: 302
学分: 0 点
澄空币: 545 KID
GPA: 0 点
注册时间:2012-08-18
最后登录:2017-02-20


 

Quote:
引用第4楼d49685268419于2013-01-14 17:09发表的  :
感觉好像是为我们软件工程专业定制的~~~~~~

不过大二了我们还没接触到汇编和数据结构~~~估计等到大三应该就可以投身伟大的汉化事业了~~~~

我愤慨的表示大三读完还不够,,,,,
顶端 底端 2013-02-14 18:06 | 13 楼
sgdxpdqqzh
级别: 新注册会员

精华: 0
发帖: 2
学分: 0 点
澄空币: 652 KID
GPA: 0 点
注册时间:2012-12-24
最后登录:2013-03-01

 

吓跪了 新人表示还在学习中...
顶端 底端 2013-03-01 22:42 | 14 楼
999china678
级别: 澄空新生

精华: 0
发帖: 14
学分: 0 点
澄空币: 655 KID
GPA: 0 点
注册时间:2012-03-28
最后登录:2014-05-28

 

谢谢大大,正在尝试爆破大图书馆的牧羊人体验版主程序,正好试试
顶端 底端 2013-03-07 16:31 | 15 楼
月下人静
几山河越えさり行かば寂しさの终てなむ国ぞ今日も旅ゆく
级别: 学生会干事

精华: 0
发帖: 1405
学分: 57 点
澄空币: 2220 KID
GPA: 1 点
注册时间:2009-09-19
最后登录:2019-10-01


 

首先我用app加载游戏,菜单栏图标闪下就没了……不用app闪都不会什么都没发生~按你说的做了一遍达到了像用app一样的效果,可以闪下了= =~是不是还有什么问题,为什么你app可以,我却不可以呢~
顶端 底端 2013-03-09 20:42 | 16 楼
qq1657246676
级别: 新注册会员

精华: 0
发帖: 3
学分: 0 点
澄空币: 551 KID
GPA: 0 点
注册时间:2013-04-15
最后登录:2013-05-28

 

新人表示看过此贴后发现只会些C的我想要参加汉化还嫩的很·····
顶端 底端 2013-04-15 18:00 | 17 楼
dsy5983448
级别: 新注册会员

精华: 0
发帖: 1
学分: 0 点
澄空币: 656 KID
GPA: 0 点
注册时间:2012-03-28
最后登录:2013-04-18

 

这篇帖子对于一个不懂编程的我真的是帮了大忙了,非常感谢。我想请教一下关于BGI的游戏,如果有必须要插入光盘的话那一步该如何解决呢?使用OD吗?希望能够详细一点。谢谢各位大大
顶端 底端 2013-04-16 16:24 | 18 楼
桜のちるころ
自宅警備員仕事中
级别: 澄空一年生上学期

精华: 0
发帖: 71
学分: 0 点
澄空币: 987 KID
GPA: 0 点
注册时间:2010-07-02
最后登录:2015-06-20

 

Quote:
引用第18楼dsy5983448于2013-04-16 16:24发表的  :
这篇帖子对于一个不懂编程的我真的是帮了大忙了,非常感谢。我想请教一下关于BGI的游戏,如果有必须要插入光盘的话那一步该如何解决呢?使用OD吗?希望能够详细一点。谢谢各位大大

一般情况下,验证 CD 已经插入的逻辑是:枚举光驱盘符 -> 打开光驱 -> CreateFile 检查其中某一个文件是否存在。你要做的就是把 CreateFile 后面的条件跳转改成强制跳转或 nop(视具体情况而定)。具体做法就是断下所有 CreateFileA,然后运行看它停在哪儿了。
还有个方法就是把调用 CD 验证的跳转给 nop 掉,不过这个得按情况分析了。

顶端 底端 2013-04-21 10:33 | 19 楼
« 1 23» Pages: ( 1/3 total )
帖子浏览记录
『澄空学园』 » 【汉化破解研讨室】
快速发帖
内容
使用签名
Wind Code自动转换


出售此帖
加密此帖


如何在帖子中贴图?
Wind Code使用教程
恢复帖子内容
澄空娘:『学园倡导以理性思考为主的和睦讨论气氛,希望参与讨论的人能够保持平和的心态并主动维持讨论的气氛 』
认证码:
按 Ctrl+Enter 直接提交