最后由 Tabing010102 更新于 2024年5月27日
主要记录下折腾的记录,废物笔者并不会逆向,全靠前人的铺垫,在此感谢先辈们。
图片模糊问题,目前建议新标签打开图片,把链接后的-1024x???
删除(如image-1024x597.jpg
更改为image.jpg
)
《リトルプリンセスGO!》
首先是《リトルプリンセスGO!》,引擎BGI/Ethornell(Shift_JIS版,新版BGI原生支持UTF-8,处理起来更简单),这个处理起来算是比较简单的,把data01110
、data01120
解包,用VNTranslationTools提取json,翻译,封回去就行了
需要注意的是,这里的脚本有工具不支持的opcode,需要改下代码(笔者这里设置的未知opcode直接跳过,暂时没有出问题)
封包时使用VNTextProxy的dll,打包使用MoleBox,可能需要取消勾选Relink,否则dll可能不会正确加载;Enigma Virtual Box貌似不能正确处理
《海と雪のシアンブルー》
下面是《海と雪のシアンブルー》,引擎krkrz
文本方面,使用KrkrExtract,解包data.xp3
(这里的文本之类的全部在这里,且封包不大),使用VNTranslationTools提取json,翻译,封回去
程序方面,修改forcedataxp3()
处3个括号里的值为0
将下面的data.xp3
换成任意其他字符串(游戏目录中没有的文件名),这时引擎会读取data
文件夹内容
字体修复部分,这里懒了,改了data.xp3>system/Initialize.tjs
,删掉了AddAutoPath("parts.xp3>font/");
,这时引擎会回落到默认字体(win10和win11中可能是微软雅黑)
打包时把修改后的程序和data目录一起打包即可(Enigma Virtual Box)
关于换行问题,这里注释了一个text = text.Replace("\r\n", "[r]\r\n");
好了(参考此commit)
《アイコトバ-Silver Snow Sister-》(失败)
下面是《アイコトバ-Silver Snow Sister-》,引擎Artemis,这个理论上是最好改的引擎之一,原生使用UTF-8编码,可惜VNTextPatch不支持此版本的ast脚本,再加上我也快玩完了,也就作罢
可以参考chinesize这个项目的Artemis部分,可能会有所帮助
《恋想リレーション》
下面是《恋想リレーション》,引擎BGI/Ethornell(Shift_JIS版)
这一版的BGI相对麻烦一点,需要去除区域认证,可以使用OD或者x64dbg改,不过x64dbg需要先使用LordPE去除redirect后再改(勾选重定向已分离)
OD(可能需要全英文路径,否则可能进不到断点就直接退出):使用OD打开rensou.exe后,F9运行程序至进入主模块,在CPU窗口中Ctrl+N(或右键->查找->当前模块中的名称),查找GetSystemDefaultLangID
,查找函数参考,双击跳转至函数调用处
然后直接返回0x411(将call调用改为mov eax, 411
)
更改完后在CPU窗口右键->复制到可执行文件->所有修改,之后保存文件即可
x64dbg:
首先使用LordPE去除重定向
保存后使用x64dbg打开,运行至主模块,右键搜索->当前模块->跨模块调用,搜索GetSystemDefaultLangID
后,双击跳转至CPU窗口
修改同OD,使用Space键汇编为mov eax, 0x411
最后Ctrl-P(右键补丁)->全选->修补文件,保存即可
文本方面,同《リトルプリンセスGO!》,使用VNTranslationTools提取json,翻译,封回去
修改过的文件放在游戏exe旁边,放入VNTextProxy的dll即可
字体修改方面,懒了,直接使用FontMod,根目录放自定义字体(这里是simhei.ttf
),配置(简体中文系统):
fonts:
# MS ゴシック:
俵俽 僑僔僢僋:
replace: simhei.ttf
<<: *style
SimSun: &zh-cn-font # Chinese (Simplified) fallback font
replace: simhei.ttf
<<: *style
本游戏笔者打包失败,于是就散装用了
方法2:效仿本文下方《ラブピカルポッピー!》处理方法,可能能解决异常换行问题
本次打包使用EVB 10.70,将除主程序外的其他资源打包为封包,主程序单独打包可以正常加载
《D.C.4 Sweet Harmony》
下个是《D.C.4 Sweet Harmony》,krkrz引擎
也是用KrkrExtract解包,程序修改forcedataxp3
及data.xp3
,和《海と雪のシアンブルー》不同的是,本作使用的TJS2脚本,无法作为文本修改
笔者用的解决办法,用WinHex打开startup.tjs
,查找Initialize.tjs
,将其修改为其他值(这里假设修改为Initializa.tjs
,最后一位修改为a)
然后在data/system/
文件夹下,建立Initializa.tjs
,写入以下代码。其中最后一行为加载原有的Initialize.tjs
,上面的很多行为加载原始data.xp3
中的文件,注意所有子目录都需要添加一行加载语句。加载原始封包的文件就可以从data文件夹删除,减小data文件夹大小
Storages.addAutoPath(System.exePath+'data.xp3>bgm/');
Storages.addAutoPath(System.exePath+'data.xp3>font/');
Storages.addAutoPath(System.exePath+'data.xp3>image/');
Storages.addAutoPath(System.exePath+'data.xp3>image/comu/');
Storages.addAutoPath(System.exePath+'data.xp3>image/cut/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/asa/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/asu/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/endroll/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/hiy/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/miu/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/nin/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/sii/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/sor/');
Storages.addAutoPath(System.exePath+'data.xp3>image/ED/tiy/');
Storages.addAutoPath(System.exePath+'data.xp3>image/effect/');
Storages.addAutoPath(System.exePath+'data.xp3>image/eyecatch/');
Storages.addAutoPath(System.exePath+'data.xp3>image/log/');
Storages.addAutoPath(System.exePath+'data.xp3>image/MAP/');
Storages.addAutoPath(System.exePath+'data.xp3>image/other/');
Storages.addAutoPath(System.exePath+'data.xp3>image/sys/');
Storages.addAutoPath(System.exePath+'data.xp3>image/thum/');
Storages.addAutoPath(System.exePath+'data.xp3>k2compat/');
Storages.addAutoPath(System.exePath+'data.xp3>main/');
Storages.addAutoPath(System.exePath+'data.xp3>rule/');
Storages.addAutoPath(System.exePath+'data.xp3>scenario/');
Storages.addAutoPath(System.exePath+'data.xp3>scenario/scripts/');
Storages.addAutoPath(System.exePath+'data.xp3>scenario/simpleanim/');
Storages.addAutoPath(System.exePath+'data.xp3>scenario/transitions/');
Storages.addAutoPath(System.exePath+'data.xp3>sound/');
Storages.addAutoPath(System.exePath+'data.xp3>sysscn/');
Storages.addAutoPath(System.exePath+'data.xp3>thum/');
Storages.addAutoPath(System.exePath+'data.xp3>uipsd/');
Storages.addAutoPath(System.exePath+'data.xp3>uipsd/func/');
Storages.addAutoPath(System.exePath+'data.xp3>video/');
Scripts.execStorage("system/Initialize.tjs");
本作可以选择字体,使用黑体或其他等宽中文字体
最后将汉化的游戏脚本、修改后的主程序和data文件夹用Enigma Virtual Box打包即可
《ここから夏のイノセンス!》
下面一个游戏是《ここから夏のイノセンス!》,引擎cs2/CatSystem2
文本方面,笔者一开始使用VNTranslationTools封包,但VNTextProxy的dll库无法正常加载/加载崩溃,后来使用Ineditor,但执行到某个地方回直接回到主菜单,无法正常进行游戏,最后修改VNTextPatch,使用GBK编码才算解决,参考GitHub项目
程序部分,主要需要破解key验证、修改编码、修改字符验证范围,主要参考Dir-A大佬的视频(链接)
破解key验证部分,使用x64dbg打开,运行至主模块,搜索字符串key.dat
双击跳转至对应汇编,修改下方的jne xxx
为jmp xxx
最后应用补丁,保存
修改读取编码部分,x64dbg打开,运行至主模块搜索跨模块调用CreateFontIndirectA
双击跳转至汇编,向上翻2个函数,双击call指令
修改下方参数0x80
为0x86
最后应用补丁、保存
修改字符边界部分,使用OD打开,运行至主模块,右键查找所有常量0x9F
找到cmp al, 0x9F
,双击跳转
每隔一个修改cmp al, 0xXX
为cmp al, 0xFE
修改完,复制所有修改到可执行文件,保存
字体修复部分,游戏字体可能在config/startup.xml
下font
相关位置,但本游戏修改并没有用,笔者更改了游戏主程序。使用WinHex打开游戏exe,搜索”俵俽 僑僔僢僋
“或”MS ゴシック”或16进制数值”826C827220835383568362834E
“,修改为”simhei
“(后面补16进制0),将出现的所有进行更改,最后保存即可
封包部分,cs2引擎支持免封包读取,将汉化脚本放至scene文件夹下,打包时将修改后的主程序和scene文件夹一并打包即可
方法2:gbk版,对话框名字不显示(可能要替换资源之类的,弱智笔者不会),可以使用UIF根据GalTransl里的替换字典(链接),全换成Shift_JIS能编码的字符,然后用UIF加载,对话框名字不翻译姑且能正常显示,VNTranslationTools可以参考cs2_uif分支(链接)。
《ラブラブル~lover able~》
这游戏是SMEE老作,封包格式ykc,引擎是yuka script(或yuka system),现在倒是有一个针对这个引擎的工具,但是这玩意貌似只能处理英文(使用Shift_JIS),又因为我短时间内没找到现有的更改此引擎文字编码的资料(加上瞎折腾失败),就偷了VNTranslationTools里的VNTextProxy,把SjisTunnelEncoding抄过来了(项目地址)
总体流程:把DATA01.ykc解包,删除除了story文件夹以外的脚本,翻译story里的csv,封包,patch原始包。用到的指令如下
yuka.exe unpack DATA01.ykc
yuka.exe pack DATA01CN
yuka.exe patch DATA01.ykc DATA01CN.ykc
VNTextProxy里的预编译proxydll貌似只有winmm.dll
能用,不能输入文字,而且还会占满一个CPU核,属于是真勉强能动水平
在Enigma Virtual Box打包的时候,将这些文件(游戏主程序,修改后的DATA01.ykc
,sjis_ext.bin
,winmm.dll
)打包进一个exe就不能让VNTextProxy正常加载。但是把除了游戏主程序之外的文件打包成一个封装,让打包的exe加载这个外部封包就正常,不知原理是什么。
最后,若想使用VNTextProxy的强制指定字体功能,貌似不能打包进封装,直接放在exe旁边就能正常加载。最后的补丁大概长这个样子:
贴一个csv插入的屎山片段
def process_csv_files(file_paths):
for file_path in file_paths:
f = open(file_path, encoding='utf8')
# read csv
reader = csv.reader(f)
# write
wfn = file_path.replace("JP", "CN")
wfndir = os.path.dirname(wfn)
if not os.path.isdir(wfndir):
os.makedirs(wfndir)
writer = csv.writer(open(wfn, 'w', encoding='utf8', newline=""))
for row in reader:
try:
if len(row[2].strip()) == 0:
writer.writerow(row)
continue
if row[0] == "ID":
writer.writerow(row)
continue
if row[0].startswith("N"):
if len(row) != 3:
print("W: {} len = {}".format(row[0], len(row)))
row.append(get_trans_name(row[2]))
writer.writerow(row)
elif row[0].startswith("L"):
if len(row) != 3:
print("W: {} len = {}".format(row[0], len(row)))
row.append(get_trans_msg(row[2]))
writer.writerow(row)
elif row[0].startswith("S"):
if len(row) != 3:
print("W: {} len = {}".format(row[0], len(row)))
row.append(get_trans_sw(row[2]))
writer.writerow(row)
else:
writer.writerow(row)
print("W: unknown prefix, row[0] = {}".format(row[0]))
except Exception as e:
writer.writerow(row)
continue
《同棲ラブラブル》
同上
《Pieces/揺り籠のカナリア》
引擎YU-RIS 0.5xx,漩涡社的特制引擎,有sc.ypf
,主要针对解包出来的scenario
脚本进行处理(明文),方法和工具主要参考Dir-A
佬的YU-RIS汉化演示实例(链接)
首先使用Replace_RangTable.exe
替换程序字符检测范围表(或按视频中更改),然后使用x64dbg打开,运行至主模块,搜索常数0x9F
,找到cmp xxx,9F
,点进去
根前面的字符边界检测类似,将81 9F E0 FC
更改为81 FE E0 FE
(隔位修改为0xFE
)
然后根据Dir-A的教程,需要运行至主模块,转至内存布局页面,全选,右键搜索匹配特征,搜索C1 E0 08 ?? ?? ?? ?? ?? ?? 99 E9
点进去后,将shl xxx
至cdq
上方指令使用nop
填充(右键二进制,使用NOP填充),并根据shl
操作的寄存器写入mov ax,9F00
(比如shl eax,8
->mov ax,9F00
;shl ecx,8
->mov cx,9F00
)
最后的免封包处理,需要让程序读取yscfg.ybn
加载配置,但本游戏不会读取在外面的yscfg.ybn
在当前模块中搜索跨模块调用的GetFileAttributes
,点进去找到函数比较短的(一共只有几行汇编的),在call
(00440511
)指令上加断点,重新运行至此
返回至调用函数,再点进上面的call
,即是函数入口点(这里为call GetFileAttributeA
上面的push eax
)
在函数入口点右键,查找引用,选定的地址
这里的程序在读取文件时又封装了一层,所以需要点进没个引用处,断下调用处上方的两个mov xx:[]xx,0
运行,直到看到yscfg.ybn
,将其改为mov byte ptr ss:[esp+C],3
至此,主程序修改完成,字体笔者偷懒使用Dir-A提供的HookFont
,不改的话默认是宋体。
接下来修改yscfg.ybn
,最后为标题名字字符串,向前数8个字节,修改紫色框二进制为01
,修改后引擎将会默认从外部文件读取(原理参考yscfg
分析)
下面处理人物名称不显示在人物名称栏的问题,本游戏脚本有加密,首先使用GARbro解包bn.ypf
,选择文件大小最大的yst00xxx.ybn
,拖到上YSTB_GuessXorKey.exe
打开,得到Key.txt
。然后使用YSTB_Xor.exe
得到解密的ysbin_dec
文件夹。
接下来将YSTL_Parse.exe
,ysbin_dec
文件夹放入一个新文件夹中,从原始加密的ysbin
中,复制除yst00xxx.ybn
的文件到ysbin_dec
中,最后将ysbin_dec
重命名为ysbin
,命令行执行YSTL_Parse.exe -json
得到ystl.json
;再运行YSTL_Parse.exe -make
得到有原始名字的scripts
文件夹。
scripts
文件夹中使用010 Editor或其他软件,搜索es.CHAR.NAME
,一般为userdefine\キャラ名定義.txt
(其他特殊情况参考教程)
使用extYbn
提取文字,根据翻译结果替换相应文字,再封回去,命令如下:
# extract
for %%a in (*.ybn) do extYbn.exe -e -ybn %%a -op-msg 108 -op-call 43 -txt %%a.txt -cp 932 -key 0x0
# insert
for %%a in (*.ybn) do extYbn.exe -p -ybn %%a -txt %%a.txt -op-msg 108 -op-call 43 -cp 936 -new-ybn %%a.new.ybn -key 0x0
最后新建一个ysbin
目录,将生成的キャラ名定義.txt.ybn.new.ybn
放进去,将YSTB_Xor.exe
和前面生成的Key.txt
放在一个目录下,执行YSTB_Xor.exe
加密回去。接下来通过ystl.json
文件找到キャラ名定義
脚本对应的原始文件名,这里Sequence
为274,所以原始文件名为yst00274.ybn
。
scenario
内文件修改时需要注意的是,由于使用gbk编码,\u266a
(♪
)、\u4337
(䌷
)、\u30fb
(・
)字符无法编码,需要删除或使用gbk中有的字符进行替代。
此外,在处理指令(\XX(xxxx))时,笔者使用的sjis编码,但是指令包含游戏目录下pac文件夹内的文件时需要使用gbk编码,否则会出现读不到文件的错误,但有部分\u30fb
(・
)无法被gbk编码,笔者处理时仅把\u30fb
(・
)使用sjis编码,其他使用gbk编码,具体参考以下代码(链接),笔者初步测试没出现崩溃,凑合能动水平。
最终打包结构如下图:
《ラブピカルポッピー!》
基本同《リトルプリンセスGO!》,BGI/Ethornell引擎,笔者懒了,直接VNTranslationTools,本作打包也是使用MoleBox,取消Relink,使用dll代理中的version.dll
;EVB也不能正确处理本作,原因未知。
VNTT会出现换行错误,用GALgameScriptTools封的没问题(看着可能是在虚拟机脚本后面附加的新文本)。本作引擎支持UTF-8编码,但是人物名字会出问号。最后使用VNTT偷的SjisTunnelEncoding结合上面的封包,暂时没发现换行错误,比纯用VNTT好点。这里使用Base64保存SjisTunnelEncoding输出的byte数组,在封包器中Base64解码得到原始byte数组写入虚拟机脚本。
下面贴一点用到的屎山
// SjisTunnelEncoding
foreach ((string k, string v) in data_dict)
{
var v2b = sjisTunnelEncoding.GetBytes(v);
out_dict[Convert.ToBase64String(e932.GetBytes(k))] = Convert.ToBase64String(v2b);
}
# BGIScriptRepacker.py
import base64
def transcode(uni):
return base64.b64decode(uni)
LiveMaker 游戏
基本就是pylivemaker一把梭,这里用到了一个我在M系镜像看到的佬做的字体(镜像链接),按照替换表替换,其他非Shift_JIS可编码字符特殊判断一下即可,最后把替换好的lsb
文件放至游戏可执行文件同一目录下(或使用EVB封包)。
基本流程:
# 提取游戏封包(.exe/.dat/.ext)
lmar x path_to_game_archive -o path_to_extract_folder
# 找到需要处理的lsb文件,一般为全十六进制数字如000018A8.lsb,提取文本
lmlsb extractcsv ...
lmlsb extractmenu ...
# 翻译csv,替换非Shitf_JIS字符
# 替换翻译到lsb文件
lmlsb insertcsv ...
lmlsb insertmenu ...
# (可选)修改游戏封包
lmpatch path_to_game_archive path_to_script.lsb
若引擎选择字体没用或失效,建议在WinXP或Win7下使用ntlea指定默认字体为Sarasa UI SC LiveMaker
可能可以解决
参考:
Dir-A的个人空间-Dir-A个人主页-哔哩哔哩视频 (bilibili.com)
Galgame 汉化破解初级教程:以 BGI 为例,从解包到测试|【汉化破解研讨室】|【游戏汉化交流区】 – 『澄空学园』 GalGame专题网 (sumisora.net)
「さくら、もゆ。」的空白字体列表——一次逆向问题定位过程实录 – (o・∇・o) (mmf.moe)
DC2PC汉化实战|【汉化破解研讨室】|【游戏汉化交流区】 – 『澄空学园』 GalGame专题网 (sumisora.net)
Galgame引擎、破解与资料大全 (ultrapre.github.io)
Dir-A/VN_Localization_Tutorials: Galgames汉化教程 (github.com)
CyanidEEEEE/Livemaker-chinese-tl: Livemaker中文汉化教程 (github.com)
M系镜像 – [机翻汉化v0.4]MSIZE(エムサイズ)全游戏作品机翻汉化补丁 (chromaso.net)
用到的工具/开源项目:
Software Protection, Software Licensing, Software Virtualization (enigmaprotector.com)
arcusmaximus/VNTranslationTools: Tools for translating visual novels (github.com)
xmoezzz/KrkrExtract: A tool that can extract and pack krkr2 and krkrz’s xp3 files (github.com)
regomne/chinesize: My chinesize tools, scripts and codes (github.com)
regomne/lneditor: [deprecated] A multiline editor for translators (github.com)
ysc3839/FontMod: Simple hook tool to change Win32 program font. (github.com)
AtomCrafty/yukatool: A collection of tools for the “Yuka System” visual novel engine (github.com)
Dir-A/YurisTools: Yu-Ris Engine Tools. | .ypf .ybn (github.com)
pmrowla/pylivemaker: Python package for manipulating LiveMaker game resources (github.com)
yanhua0518/GALgameScriptTools: A few tools for some engine’s script (github.com)
Views: 708