galgame第一次汉化记录

游戏概述

  • 游戏名称:しょうよん! ~コドモ★ちゃれんじ~(柚子社早期作品)
  • 原始语言:日文
  • 目标语言:中文

汉化工具

  • 使用的翻译:deepseeek-v3
  • 使用的编辑器:vscode、IDA
  • 其他辅助工具:winhex、吾爱破解(LCG)、GARbro、EXtractDATA

汉化过程

一、分析游戏exe文件

① 更改游戏编码

一般日本galgame的游戏编码都是shift-jis、近些年来少部分galgame的游戏编码是utf-8可以支持中文。所以想要完成游戏汉化,首先得把游戏里面的编码更改为支持中文的gbk编码

关于编码的一些经验之谈可以参考b站大佬的视频:[Gal汉化入门]#3.1 编码&范围校验修改演示_哔哩哔哩_bilibili

对于しょうよん! ~コドモ★ちゃれんじ~这个游戏的游戏编码更改具体步骤如下:

1、通过利用吾爱破解(LCG)分析了游戏exe文件、在CreateFontA的输入函数下切换断点。

2、会发现编码的控制非常简单,只需将对应部分的0x80(shift-jis)->0x86(gbk)即可

img

3、更改完会发现游戏出现乱码,是因为原来的文本内容是shift-jis

可以通过这个断点将所有涉及到日文编码的部分全部更改为gbk编码,也就是将0x80更改为0x86既可,

image-20250131175335926

② 提取游戏脚本文件

方法一:通过已有工具去提取脚本文本

通过GARbro初步分析游戏里面的文件,发现arc.nsa相关的文件都是关于游戏里面的音频以及对应的图片和cg部分。一般的脚本文件的大小都不会太大,通过分析发现游戏的脚本文件为根目录的nscript.dat文件。这个文件利用ExtractData既可提取里面的内容,并且利用vscode进行打开

img

方法二:利用IDA进行逆向exe文件,分析里面的加密逻辑进行提取

通过IDA进行逆向对应的exe文件,通过分析发现nscript.dat的读取解密逻辑在sub_40B390里面。发现里面对于nscript.dat文件的解密只是简单的与0x84进行异或既可

img

所以根据以上的分析可以很简单的得到对应的解密代码,下面是简单的用python进行实现的解密代码逻辑。

with open('nscript.dat', 'rb') as f:
encrypted_data = f.read()
decrypted_data = bytes([b ^ 0x84 for b in encrypted_data])
with open('nscript_decrypted.txt', 'wb') as f:
f.write(decrypted_data)

解密之后可以既可以得到里面的明文数据。

③ 文本汉化和应用

通过搜索游戏里面开始出现的游戏文本歩くだけで汗が流れ出る炎天下の中,可以发现大概游戏文本出现在2508行的部分,前面也有相关控制游戏标题以及各种部分的日文,

其实也可以利用最简单的提取思路,只需要提取里面非英文以及英文标点符号之外的所有文本既可

利用re正则表达式

def extract_jp_text(text):
# 正则表达式匹配非英文字符和标点
pattern = r'[^\u0020-\u007E]+'
# 提取匹配的文本
jp_text = re.findall(pattern, text)
# 无匹配文本则返回为None
if not jp_text:
return None
jp_text = "".join(jp_text)
# 过滤空白行
jp_text = jp_text.strip()

return jp_text

可以利用AI大模型的接口去进行汉化,我这边推荐用DeepSeek | 深度求索

对于如何应用进游戏有两个策略。

1、免封包策略

  • 优点:简单、可以不依赖逆向完成简单的应用
  • 缺点:有时候会导致有大量的敏感明文翻译内容,很多平台无法上传自己的补丁

2、加密封包策略

  • 优点:可以防止自己翻译的敏感明文内容被暴露
  • 缺点:需要利用IDA等工具去进行分析exe里面的加密封包逻辑

方案一、免封包策略

通过前面提取游戏脚本文件的分析我们可以很容易发现,文件一开始是读取了多个文件的操作,里面包括就有0.txt以及00.txt,如果没有读取到就解包nscript.dat

if ( !_access("0.txt", 0) || !_access("00.txt", 0) || _access("nscript.zat", 0) )
{
if ( _access("0.txt", 0) && _access("00.txt", 0) && !_access("nscript.dat", 0) )
{
v9 = _open("nscript.dat", 0);
v10 = v9;
if ( v9 == -1 )
{
v11 = 0;
}
else
{
v12 = _filelength(v9);
_close(v10);
v11 = v12;
}
v5 = (const char *)malloc(v11 + 5);
dword_5E0288 = (int)v5;
*v5 = 0;
v13 = fopen("nscript.dat", "rb");
v7 = v13;
if ( !v13 )
goto LABEL_45;
for ( i = fgetc(v13); i != -1; i = fgetc(v7) )
v5[v0++] = i ^ 0x84; // 解密部分
goto LABEL_10;
}

所以我们可以直接把利用ExtractData提取到的文本更改为00.txt或者0.txt放进游戏根目录然后将编码更改为前面我们已经修改为的GBK编码,再通过修改里面的剧情文本内容。最后发现游戏可以正常进入,并且测试正常

image-20250131192140929

方案二、加密封包策略

通过前面利用IDA的分析,我们发现游戏的加密逻辑十分简单,故可以利用对应的python代码进行反向封包成dat文件,具体代码如下

with open('128.txt', 'r', encoding='gbk') as f:
text_data = f.read()

# 将文本转换为字节并加密
binary_data = text_data.encode('gbk')
encrypted_data = bytes([b ^ 0x84 for b in binary_data])

# 写入dat文件
with open('nscript1.dat', 'wb') as f:
f.write(encrypted_data)

将最后得到的dat文件放入游戏里面发现测试正常

image-20250131192509318

汉化总结

经过不断的摸索,我的首个汉化补丁终于在2DFan上线啦!(补丁下载地址)作为汉化新手,这次从翻译到技术调试全程自学的经历,让我真正体会到汉化工作的不易——每一个流畅运行的补丁背后,都是无数细节的打磨和付出的努力。

关于这次汉化: 虽然是第一次尝试,但过程中积累了许多实用经验:比如游戏文本的提取以及相关工具的使用。特别推荐B站UP主Dir-A的教程(主页链接),他的GitHub技术文档(Dir-A_Essays_MD)给了我超多帮助!