原本以为是很普通的软件汉化工程,实际做下来却发现远比想象中的复杂。
因为探索的思路和解决方法十分有趣,也具有一定的参考性,因此写下此文做一个记录。
目标程序: Windows X86_64 Qt5.15.5 Lua5.2
初见端倪
照例先对源程序进行分析,找出字符串所在及相关信息。
分析后发现是常规结构,便打开passolo对exe本体提取非标字符串进行汉化。
但是在汉化时发现部分字符串无法提取,经文件搜索后发现在lua脚本之中。
而这些字符串则在lua脚本的配置文件之中,明文存储,直接修改保存。
不出意外是要出意外了,中文的部分出现乱码了。而经过十六进制层面的编码比对和测试后,
得知该编码应该是Latin1
,而这个编码则完全不包含汉字字符。
因此到这里,我们遇到的第一个问题则是解决Lua脚本的字符集问题。
逆向崎路
因为在exe本体中的字符可以正常汉化,所以我们可以确认软件的默认字符集是没问题的。
这样,就自然会怀疑到lua模块是否对编码有特殊设置,因此便开始从lua部分入手。
此时,基于经验,笔者尝试通过转义字符,强制编码等方式来试图越过读取lua文件时的编码设置
可不幸的是该软件所使用的lua版本为5.2,是尚未支持utf8库及\u等转义字符的最后一个版本,就这样,在文件内部的方法就被堵死了。
于是转回lua编码,我尝试对lua模块进行分析,lua模块采用luaR加密,使用unluac
可以轻松还原出源代码
但在解密并对lua代码进行分析后,没发现任何有关编码的部分。即lua模块上应该是没有文章做了。
老本行
只有风暴才能击倒大树,既然如此,那就端出我们的老三样吧。
掏出x64dbg,通过异常和窗口句柄捕捉断点尝试寻找逻辑,无果。
再通过ce下内存断点,定位堆栈,通过函数调用关系及可疑模块的调用次数来找到相关逻辑中的可疑函数。
随后再进入ida,对该函数进行分析:
在简单分析调用逻辑后,笔者对QString,fromAscii_helper等一系列会经手字符串转码的函数进行了分析捕获和转发尝试,但由于内部程序结构复杂,导致效果十分不理想。
于是笔者决定转换思维,从下层入手,在程序将QString赋值给Label Text时进行篡改,这样既能避开各种奇怪的编码问题也不用担心对程序造成损害。
于是按照该思路,我们一路找到了这个函数QLabel::setText
那么事不宜迟,打开SharpDLLProxy,生成目标文件及中转代码:
同时获取原函数地址,分析出入参,进行Hook转发
经测试,成功替换目标字符串同时正常显示,问题解决。
总结
综上,解决该项目的技术手段较为常见,但由于内部组件的不标准编写及内外模块的复杂耦合给分析阶段带来了一定的难度,
同时为了更好的处理qt相关内容编码,同时得在Hook Dll中引入外部的QT依赖,而这也给处理步骤带来了一定的困扰。
因此以后读者如果遇到此类问题,也可以尝试从上游或者下游捕获拦截,说不定能得到意想之外的结果。
感谢您的阅读。