三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Kirikiri引擎逆向工程深度解析:脚本解密与资源破解完整技术指南

Kirikiri引擎逆向工程深度解析:脚本解密与资源破解完整技术指南

Kirikiri引擎逆向工程深度解析:脚本解密与资源破解完整技术指南

【免费下载链接】KirikiriToolsTools for the Kirikiri visual novel engine项目地址: https://gitcode.com/gh_mirrors/ki/KirikiriTools

KirikiriTools是一款专为Kirikiri视觉小说引擎设计的开源逆向工程工具集,提供了脚本解密、存档破解和资源打包等核心技术功能。这款工具集解决了游戏本地化、mod开发和资源提取中的关键技术难题,通过深入分析引擎内部机制,实现了非侵入式的破解方案,为技术开发者和逆向工程爱好者提供了完整的解决方案。

项目概述与技术定位

Kirikiri引擎作为日本视觉小说游戏的主流开发平台,广泛采用多层资源保护机制来防止非授权访问。这些保护措施包括脚本文件混淆、存档文件加密和运行时验证,给游戏本地化、修改和逆向工程带来了显著挑战。

KirikiriTools通过三个核心模块解决了这些技术难题:

  1. KirikiriDescrambler:处理脚本解密,支持三种加密模式的精确还原
  2. KirikiriUnencryptedArchive:实现内存注入与API钩子技术,绕过运行时保护
  3. Xp3Pack:创建与破解DLL兼容的未加密存档

核心技术挑战与解决方案

脚本加密机制的深度分析

Kirikiri引擎使用三种主要脚本加密模式,每种模式采用不同的混淆算法。加密脚本文件具有特定的签名模式,以FE FE开头,后跟模式标识符和FF FE标识。

模式0解密算法实现位于KirikiriDescrambler/Descrambler.cs:

private static byte[] DescrambleMode0(BinaryReader reader) { byte[] data = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); for (int i = 0; i < data.Length; i += 2) { if (data[i + 1] == 0 && data[i] < 0x20) continue; data[i + 1] ^= (byte)(data[i] & 0xFE); data[i] ^= 1; } return data; }

这种算法设计的关键在于准确识别UTF-16编码特性,确保解密后的文本保持正确的字符编码格式。模式2处理则涉及zlib解压缩流程,需要正确处理压缩头信息。

运行时保护机制的智能绕过

KirikiriUnencryptedArchive模块采用先进的DLL注入技术,通过修改游戏进程内存来绕过保护机制。核心实现位于KirikiriUnencryptedArchive/main.cpp和KirikiriUnencryptedArchive/Patcher.cpp。

签名检查绕过机制通过定位虚拟函数表并替换关键函数指针实现:

bool Patcher::PatchSignatureCheck(HMODULE hModule) { void** pVerifierVTable = CompilerHelper::FindVTable(hModule, CompilerType::Msvc, "KrkrSign::VerifierImpl"); if (pVerifierVTable == nullptr) return false; Debugger::Log(L"Patching KrkrSign::VerifierImpl"); MemoryUtil::WritePointer(pVerifierVTable + 4, CustomGetSignatureVerificationResult); return true; }

架构设计与实现原理

内存注入与钩子技术架构

KirikiriTools采用非侵入式设计哲学,通过DLL注入实现运行时修改而不修改原始游戏文件。DLL入口点初始化逻辑实现了智能的资源访问重定向:

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) { Proxy::Init(); Debugger::RegisterDllLoadHandler( [](const wchar_t* pwszDllPath, HMODULE hDll) { if (Debugger::FindExport(hDll, "V2Link") != nullptr) Patcher::PatchSignatureCheck(hDll); } ); Kirikiri::Init( [] { CompilerHelper::Init(); Patcher::PatchXP3StreamCreation(); Patcher::PatchAutoPathExports(); Patcher::PatchStorageMediaRegistration(); } ); } return TRUE; }

存储媒体重定向系统

Patcher模块实现了智能的文件访问重定向机制,支持多层路径解析。此架构支持多种资源访问模式:

  1. 未加密的松散文件优先
  2. 未加密的XP3存档文件
  3. 原始加密文件的回退机制

存储媒体重定向实现位于KirikiriUnencryptedArchive/Patcher.cpp:

tTJSBinaryStream* Patcher::CustomStorageMediaOpen(iTVPStorageMedia* pMedia, const ttstr& name, tjs_uint32 flags) { static wstring folderPath = Path::GetModuleFolderPath(nullptr); const wchar_t* pFilePath = wcschr(name.c_str(), L'/') + 1; wstring looseFilePath = Path::Combine( Path::Combine(folderPath, L"unencrypted"), StringUtil::Replace<wchar_t>(pFilePath, L'/', L'\\')); wstring unencryptedXp3Path = Path::Combine(folderPath, L"unencrypted.xp3"); vector<wstring> urls = { Kirikiri::FilePathToUrl(looseFilePath) }; if (GetFileAttributes(unencryptedXp3Path.c_str()) != INVALID_FILE_ATTRIBUTES) { wstring unencryptedXp3Url = Kirikiri::FilePathToUrl(unencryptedXp3Path); urls.push_back(unencryptedXp3Url + L">" + pFilePath); const wchar_t* pFileName = wcsrchr(name.c_str(), L'/') + 1; if (pFileName != pFilePath) urls.push_back(unencryptedXp3Url + L">" + pFileName); } for (wstring& url : urls) { if (Kirikiri::TVPIsExistentStorageNoSearchNoNormalize(url.c_str())) { ttstr mediaName; pMedia->GetName(mediaName); Debugger::Log(L"Redirecting %s://%s to %s", mediaName.c_str(), name.c_str(), url.c_str()); void* pComStream = Kirikiri::TVPCreateIStream(url.c_str(), flags); return Kirikiri::TVPCreateBinaryStreamAdapter(pComStream); } } return OriginalStorageMediaOpenpMedia; }

实际应用场景与工作流

游戏本地化完整工作流

  1. 脚本提取阶段:使用KirikiriDescrambler批量解密游戏脚本
  2. 翻译处理阶段:在解密后的文本上进行本地化工作
  3. 资源打包阶段:使用Xp3Pack创建翻译补丁
  4. 部署测试阶段:配合KirikiriUnencryptedArchive进行集成测试

XP3存档打包技术实现

Xp3Pack工具的核心创新在于生成与破解DLL兼容的未加密存档。关键技术点包括文件表哈希置零策略和智能压缩决策算法:

private void WriteChecksumChunk() { BeginChunk(ChunkType.Checksum); _writer.Write(0); // Checksum (设置为0作为未加密标记) EndChunk(); }

智能压缩决策算法根据文件类型自动判断是否压缩:

string extension = Path.GetExtension(filePath); bool compressed = extension != ".mpg"; // MPG文件不压缩以保持兼容性

性能优化与稳定性保障

编译器兼容性设计

项目通过KirikiriUnencryptedArchive/CompilerSpecific/目录实现了对多种编译器的支持:

  • MSVC编译器:通过RTTI信息定位vtable
  • Borland编译器:通过特定内存模式识别
  • 跨编译器适配器:确保API钩子在不同环境下的稳定性

内存操作工具类位于Common/MemoryUtil.h:

class MemoryUtil { public: static void* FindByte(const void* pStart, int length, BYTE value); static void** FindAlignedPointer(const void* pStart, int length, void* value); static void* FindData(const void* pHaystack, int haystackLength, const void* pNeedle, int needleLength); static void WritePointer(void** ptr, void* value); };

调试信息输出系统

项目集成了完整的调试日志系统,通过DebugView工具可实时监控。调试信息输出位于KirikiriUnencryptedArchive/Debugger.cpp:

Debugger::Log(L"Hooking storage media \"%s\"", mediaName.c_str()); Debugger::Log(L"Redirecting %s://%s to %s", mediaName.c_str(), name.c_str(), url.c_str());

扩展性与社区生态

模块化架构设计

KirikiriTools采用模块化设计,便于社区贡献和技术扩展:

  • Common模块:提供基础工具类和内存操作函数
  • Detours模块:实现API钩子和函数拦截功能
  • Kirikiri模块:封装引擎特定接口和功能

错误处理与稳定性机制

项目实现了完善的错误处理机制:

  • 加密签名验证失败时的优雅降级
  • 内存操作失败的安全回滚
  • 资源访问异常的容错处理

技术总结与未来展望

KirikiriTools通过深入分析Kirikiri引擎的内部机制,提供了完整的技术解决方案。从脚本解密算法到内存注入技术,从存档打包到运行时重定向,每个模块都体现了对引擎架构的深刻理解。

技术优势总结

  1. 非侵入式设计:不修改原始游戏文件,通过内存注入实现运行时修改
  2. 多层兼容性:支持多种Kirikiri引擎变体和编译器版本
  3. 智能资源管理:自动识别加密状态,智能路径解析和重定向
  4. 完整工具链:提供从解密到打包的完整工作流

未来技术发展方向

  1. 更多加密变体支持:扩展对新型加密算法的识别和解密能力
  2. 图形化界面开发:降低技术门槛,扩大用户群体
  3. 自动化测试框架:确保不同游戏版本的兼容性和稳定性
  4. 云服务集成:提供在线解密和打包服务

社区贡献指南

项目采用清晰的接口定义和文档规范,便于社区参与:

  • 统一的错误处理规范
  • 完善的测试用例框架
  • 模块化的架构设计

KirikiriTools不仅解决了实际的技术难题,更为游戏本地化、mod开发和逆向工程领域提供了宝贵的技术参考。通过平衡功能性与稳定性,在提供强大功能的同时确保游戏的正常运行,这款工具集成为了Kirikiri引擎资源处理的标杆解决方案。

【免费下载链接】KirikiriToolsTools for the Kirikiri visual novel engine项目地址: https://gitcode.com/gh_mirrors/ki/KirikiriTools

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表