干货 – 如何逆向解决QT程序汉化中的乱码问题

114次阅读

共计 2457 个字符,预计需要花费 7 分钟才能阅读完成。

作者:逆向驿站原文链接 https://mp.weixin.qq.com/s/aG…
一款 QT 开发的国外软件,大概率是没有做中文支持的,所以你汉化中,不论怎么设置编码都一定是乱码。面对这个问题,你去互联网上找答案,答案却大多是复制粘贴的开发中解决乱码的文章,可是我们是要逆向中解决,于是吾爱破解、汉化新世纪等找过来,盘搜搜个遍,发现基本不是资源过期就是驴唇不对马嘴的抄袭贴,所以我来发一篇干货
准备
【环境和工具】

win7/xp 虚拟机环境
pdf2any 原版安装程序(qt 开发的国外程序,不支持中文,无源码)
ollydbg
Radialix 3
010editor
qt-win-opensource-4.8.2-mingw.exe(相当于 QT 库支持,核心部件)
qt-creator-opensource-windows-x86-3.3.0.exe(相当于编辑器而已)
MinGW.rar(编译调试环境)
最后三个是 QT 开发环境,搭建起来有利于学习,当然如果你不想玩 QT 开发那其实只用装第一个就行了,里面有 QT 各种库函数的源码,遇到相应程序浏览源码即可

【学习层次】

生搬硬套,能解决大部分 QT 汉化中乱码问题
搞懂搞透,举一反三

详解视频
干货视频,放出来尽可以去传播,但是不要干那种修改我版权说是自己视频的事,那就 low 了!
https://v.qq.com/x/page/o0825…

实战图文
一. 某 QT 程序汉化中遇乱码
QT 开发的国外软件, 若是没有特意做中文支持,不论怎么搞,都是乱码例如汉化下图中的标题 registration

乱码
二. 逆向分析寻找原因
1.OD 中定位标题字符串
程序载入 OD,定位 ”registration”, 并查看,程序中都有那些位置会调用这个字符串,如图
发现有三个地方调用了这个字符串地址,全部下断点
2. 运行观察
断点下好后,运行程序,观察调用字符串的逻辑流程,发现下的三个断点中有两个在程序启动会被调用,调用的目的分别是作为两个 QT 库函数的参数,如下图

3. 正向查阅相关函数源码
这里多说一句,玩逆向不只光玩逆向,一直强调逆向是一种思维,逆向破解的逆向就是开发,活用开发资料,逆向破解中往往事半功倍。安装 QT 后就可以看 QT 各种库函数的源码和资料,如果你想更深入的了解,给吃透的话,最好的方式莫过于自己开发,自己逆向分析。开始寻找目标函数源码,everything 搜两个函数类命,QCoreApplication 和 QMetaObject, 如下图

打开源码,阅读相关函数,源码如下
QCoreApplication::translate 函数定义,发现核心参数就是这个枚举类型,当枚举类型为 0 的时候中文是乱码,当是 1 的时候中文没问题

QMetaObjcet::tr 函数实现,发现这个函数的实质其实是以枚举类型参数为 0 去调用 QCoreApplication::translate

4. 逆向中验证上面的正向源码
从新载入 OD,重新运行,根据上面正向查阅的源码资料观察相应的两个库函数在逆向中的体现,如下图

可见,两个函数其实最终调用的都是第一个函数,而核心关键点就是枚举类型参数的值,那么我们在第一个库函数入口【6A2B5818】下断点动态运行一下,堆栈中观察参数的变化,如下动图

5. 总结所有线索

标题字符串 Registration 被函数 QCoreApplication::translate 作为参数
标题字符串 Registration 被函数 QMetaObeject::tr 作为参数
两个函数核心都是 QCoreApplication 函数
QCoreApplication 控制中文乱码核心参数是枚举类型,值 0 乱码,1 是 utf- 8 支持中文
QMetaObeject::tr 调用的 QCoreApplication::translate 关键枚举类型是 0,所以标题最后是不支持中文的,导致一汉化产生乱码

三、修改 QT 库 QTCore4.dll 解决问题
其实上面的分析如果已经完全搞懂了,其实就已经知道怎么解决了,而且解决方法有很多,但是都并不能保证所有程序的通用性,毕竟一个开发一个样,这次他用这个库函数,没准下次他用另外一个,所以吃透后,具体问题具体分析才是任何武功中的“无招胜有招”!针对于这个案例,解决的思路就至少有以下三种

程序领空修改,让其调用的 QMetaObeject::tr 更换为 QMetaObeject::trUtf8(阅读源码就会发现有这个函数,为什么此案例他没调用这个,因为是国外软件,他压根没想支持中文,所以他用的是 tr 而不是 trutf8), 这样修改的好处,可以相对保证汉化者的劳动成果,毕竟修改的地方可能会多,而且只在程序领空修改,但通用性差,换个程序百分百没用
修改库函数 QMetaObeject::tr, 让他调用 QCoreApplication::translate 时,枚举参数设置成 1,也就是压根用逆向的方式把 QMetaObeject::tr 函数改成了 QMetaObeject::trUtf8, 好处通用性较强。
修改 QCoreApplication::translate 内部逻辑,让枚举类型为 0 时,也按为 1 的流程逻辑走(最常见的爆破套路),有点通用性很强,极大程度适用很多 QT 程序汉化乱码问题

后两种方法都是修改 QT 库函数,所以最终体现是修改了 QTcore4.dll 这个文件,方法分别如下
方法 1

方法 2
修改后,生成新的 qtcore4.dll 文件,替换原版 qtcore4.dll 就会发现,再去汉化此软件,乱码问题已经解决了。我们依然以汉化题目为示例,OD 中修改数据(如果你是大量汉化工作就别用 OD 了否则累死哦),注意要是 utf- 8 的内存编码形式,关于编码常识可以在公众号内回复“编码”阅读,也可以点此链接 编码常识,修改标题 registration 为“测试”,“测试”的 utf- 8 内存编码模式 16 进制数据是 E6 B5 8B E8 AF 95,转换方法如下,有兴趣的也可以自己写工具
notepad++ 写入内容,转码

010editor 查看 16 进制内容

OD 改字符串
乱码解决

正文完
 0