葫芦娃很厉害 发表于 2019-1-11 12:51

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

本帖最后由 葫芦娃很厉害 于 2019-1-18 19:28 编辑

前言
“一款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汉化中乱码问题
[*]搞懂搞透,举一反三

实战图文
一.某QT程序汉化中遇乱码
[*]QT开发的国外软件
[*]不论怎么搞,都是乱码
[*]例如汉化下图中的标题registration



二.逆向分析寻找原因1.OD中定位标题字符串程序载入OD,定位"registration",并查看,程序中都有那些位置会调用这个字符串,如图

发现有三个地方调用了这个字符串地址,全部下断点

2.运行观察断点下好后,运行程序,观察调用字符串的逻辑流程,发现下的三个断点中有两个在程序启动会被调用,调用的目的分别是作为两个QT库函数的参数,如下图


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

乱码解决


附件链接
https://pan.baidu.com/s/1EV9RB-WTj2oQWz8gJ8dKNw
提取码: p5rs

葫芦娃很厉害 发表于 2019-2-3 18:32

qyouqme 发表于 2019-2-3 17:24
楼主列出的是QT4有交叉引用的字串乱码问题。
请问下QT5没有交叉引用的字串截断的问题如何解决呢?能否给个 ...

回头研究研究,我也是偶遇这个问题,发现上网一查都是驴唇不对马嘴的抄袭文,我才自己搞了搞,平常也没专门搞过QT,那截断的是长度问题吧?file内存中4个字节,而utf-8 一个汉字就会占3个字节4个字节顶多存一个汉字啊,你找个长点的英文试试,看看是不是按这个来的

qyouqme 发表于 2019-2-3 18:44

葫芦娃很厉害 发表于 2019-2-3 18:32
回头研究研究,我也是偶遇这个问题,发现上网一查都是驴唇不对马嘴的抄袭文,我才自己搞了搞,平常也没专 ...

是长度的问题
关键在于没有交叉引用的情况下无法找到调用该字符串的地方就无法修改读取字串的长度值
实际操作中有交叉引用的字串在调用的前后很近的地方有的有长度值,改这个值可以完全显示

Hmily 发表于 2019-1-18 18:31

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

这下面这张图片盗链了。

葫芦娃很厉害 发表于 2019-1-18 19:30

Hmily 发表于 2019-1-18 18:31
这下面这张图片盗链了。

盗链也修改过了,谢谢了,厉害了管理员,技术与人品都好的人很可怕!

葫芦娃很厉害 发表于 2019-1-19 09:19

https://www.52pojie.cn/thread-179442-1-1.html
QT程序汉化乱码修改教程
去那片找方法但是看不了的,这里可以解决,

92013 发表于 2019-1-21 15:31

辛苦了,楼主!

adoudou 发表于 2019-2-3 08:39

干货万岁!感谢哦!

qyouqme 发表于 2019-2-3 17:24

楼主列出的是QT4有交叉引用的字串乱码问题。
请问下QT5没有交叉引用的字串截断的问题如何解决呢?能否给个思路?
QT5不会乱码但是会截断,比如QT5中硬编码的字符串,“File”汉化成“文件”后在软件界面仅显示“文”。
有交叉引用的字串可以挪移,没有交叉引用的字串就没辙了。

zxlkfx2018 发表于 2019-2-10 20:10

辛苦了,楼主!
页: [1] 2 3
查看完整版本: 【干货】如何逆向解决QT程序汉化中的乱码问题