狠狠厥烂KiriKiriZ Cxdec拆包

逆向工程cxdec
浏览数 - 484发布于 - 2025-09-10 - 12:32

0x0 参考资料

巨佬:https://space.bilibili.com/685540771

巨佬:https://github.com/YuriSizuku

0x1 背景

大概从2021年开始,部分KiriKiriZ引擎的galgame无法使用Garbro或者KrkrExtract一键拆包了,并且修改游戏的exe还会有如下弹窗:

image原因是wamsoft给KiriKiriZ加了个Cxdec,游戏运行的时候会往下面这个路径释放一个DLL:C:\Users{用户名}\AppData\Local\Temp\krkr_{随机12位字符}_{随机8位字符}_{随机5位字符},路径的生成在如下位置:

image脚本要读取文件 -> 把对应的文件名送给cxdec计算hash -> 用hash去XP3封包里面找文件

0x2 方法

  • 运行时dump,也是我最早采用的:KirikiriToolsKrkrDump均可,但是工作量太大了,需要把整个游戏所有分支全部跑一遍,无法自动化处理。

  • hook cxdec,最近采用的方法: KrkrExtractForCxdecV2提取出所有文件(hash名称)-> 暴力扫描每个文件的签名(krkrz的脚本基本上都是ks.scn,文件签名为PSB)-> FreeMote解压PSB -> 解析json,提取出所有的文件名 -> 用krkr_hxv4_dumphash hook住cxdec那个DLL,往里面灌文件名得到对应的hash -> 对照映射表还原文件名。

  • 动态替换tjs2脚本,将要采用的方法:KirikiriTools不仅能dump文件,也能注入文件 把下面的代码保存为appconfig.tjs,放在unencrypted文件夹内就能让引擎自己吐文件:

    text
    KAGLoadScript("KAGEnvPlayer.tjs");
    var scn_list = KAGEnvPlayer.internalGetSceneFileList("!scnlist.txt");
    for (var i = 0; i < scn_list.count; ++i) {
    	try
    	{
    	Scripts.evalStorage(scn_list[i] + ".scn");
    	}
    	catch{}
    }
    System.exit();
    

    拿到scn以后可以用这个脚本解析生成新的tjs去提取别的文件,例如:

    text
    try
    {
    Scripts.evalStorage("uts001_001.ogg");
    }
    catch{}
    
    try
    {
    Scripts.evalStorage("uts001_002.ogg");
    }
    catch{}
    
    try
    {
    Scripts.evalStorage("uts001_003.ogg");
    }
    catch{}
    
    try
    {
    Scripts.evalStorage("uts001_004.ogg");
    }
    catch{}
    System.exit();
    

现在主打一个露头就秒

重新编辑于 - 2025-09-11 - 23:44

3 条回复

2778995958
发布于 2025-09-10 - 19:21 (编辑于 2025-09-10 - 21:12)

linuxdo那邊要驗證,這邊來回一下感謝大佬的思路

我在做立繪,所以很難拿全部立繪檔,看了一下這思路

dump一次遊戲拿到角色pbd檔,一般tlg立繪是檔名+圖id.tlg

pbd有圖id,檔名就是pbd底線前綴,可以一下子搞全立繪tlg檔了

pbd大約這樣,layer_id是圖id,appconfig.tjs用utf-16

javascript
#layer_type	name	left	top	width	height	type	opacity	visible	layer_id	group_layer_id
				3117	4409					
0	op1	885	230	1063	4106	13	255	1	2115	
0	眉d	1469	669	236	82	13	255	1	2113	2010
0	眉c2	1467	697	211	162	13	255	1	2108	2010
0	眉c	1467	697	211	162	13	255	1	2103	2010
0	眉b	1469	669	236	82	13	255	1	2098	2010
0	眉a	1466	679	226	98	13	255	1	2048	2010
...
javascript
...
try { Scripts.evalStorage("tyozc01_l_2255.tlg"); }
catch{}
try { Scripts.evalStorage("tyozc01_l_2256.tlg"); }
catch{}
try { Scripts.evalStorage("tyozc01_l_2257.tlg"); }
catch{}
try { Scripts.evalStorage("tyozc01_l_586.tlg"); }
catch{}
System.exit();
bfloat16
发布于 2025-09-10 - 21:49
回复 @2778995958#1

linuxdo那邊要驗證,這邊來回一下感謝大佬的思路 我在做立繪,所以很難拿全部立繪檔,看了一下這思路 dump一次遊戲拿到角色pbd檔,一般tlg立繪是檔名+圖id.tlg pbd有圖id,檔名就是pbd底線前綴,可以一下子搞全立繪tlg檔了 pbd大約這樣,layer\_id是圖id,appco...

tjs不一定要utf-16,utf-8-sig也是可以的

反正第一次先dump出所有的scn,用freemote解压成json就能解析出需要的东西了

2778995958
发布于 2025-09-10 - 23:08 (编辑于 2025-09-10 - 23:35)
回复 @bfloat16#2

有日文的檔名我試過是不能導的,會出來error,用utf-16可以導出日文檔名

我不用scn去導是因為裸體立繪不會在遊戲中出現,所以劇本不會有,有些沒鑑賞的遊戲就根本不會看到

加上略看了一眼scn的json,對於立繪那種tlg要id不能用這方法

還是用基本法運行一次遊戲拿pbd檔再補全tlg,只要遊戲一條線也能看到全角色就能有全pbd(應該沒那麼衰吧)

(。>︿<。) 已经一滴回复都不剩了哦~