论坛风格切换切换到宽版
  • 20183阅读
  • 29回复

Noise Ninja 汉化乱码的解决 [复制链接]

上一主题 下一主题
离线海子
 

发帖
348
金钱
280
威望
28
只看楼主 倒序阅读 0 发表于: 2009-07-24
Noise Ninja 汉化遇到乱码问题。此软件由 QT 开发,以下修改方法可能通用。
首先要做的事是找到导致乱码的原因,缩小范围,对症下药。
试过修改字体的语系以及要翻译字符串的编码方式等等常见的解决乱码方法,都没有效果。
那么只好对字符串的处理过程进行跟踪,看看是在哪个环节上出了问题。
由于其需翻译内容全是非标,那么就以程序显示界面上的 &File 这个字符串进行跟踪。
用 Ollydbg 载入程序后先查找到 &File 下断,记下字符串所在地址 006852D8。

[attachmentid=26146]

然后用步过 F8 和步入 F7 相互配合进行跟踪。这个过程需要极大的耐心。操作过程中注意寄存器的变化,
特别是出现 ASCII "&File" 的时候。原则是先用 F8 步过大体看看,再用 F7 步入进行跟踪。在可疑的地
方下断以便跟踪。在经过 004D74A8 CALL NoiseNin.004D58E0 后我们发现,寄存器中的 ASCII "&File"
消失了,这个地址很可疑,进入看看。

[attachmentid=26147]

小心按 F8 步过,发现一个循环对字符串进行了处理,看来十有八九找到地方了。

[attachmentid=26148]

既然我们怀疑这是处理字符串的地方,那么肯定不单单处理 &File 这一个。那么就在这个调用的末尾下断,
然后 F9 执行看看寄存器有没有什么变化。

[attachmentid=26149]

如上图中所示,Unicode ,我们的猜想基本已经被证实,而且就是那个循环进行的处理,那么问题就出在这个循环上。
为了最终证实,对字符串的处理结果手动修改一下看看运行结果。EAX 中的 Unicode 字符串是由 EBX 传过来的,
那么就在地址 004D593F 8BC3 MOV EAX,EBX 下断。重新加载程序,临时禁止 004D593F 断点,启用 00492075
断点。

[attachmentid=26150]

按 F9 执行,再启用 004D593F 断点,按 F9 执行。程序被断下来了,在 EBX 上鼠标右击,查看地址的数据。

[attachmentid=26151]

数据中显示的是 Unicode ,但由于英文 UTF-8 和 Unicode 是一样的,在这里我们还需要进行排除。
&File Unicode 字节长度是 10 ,那么需要 5 个中文字。就用“文文文文文”来试试。用编码查询工具查出
“文文文文文”Unicode 编码是 87658765876587658765 ,选择 &File 并编辑二进制。

[attachmentid=26152]

[attachmentid=26153]

[attachmentid=26154]

临时禁用所有断点,按 F9 执行。

[attachmentid=26155]

很幸运,就是 Unicode 。但是为什么在程序中直接修改 &File 运行则显示乱码呢?

[attachmentid=26156]

[attachmentid=26157]

这一次再来跟踪一遍 &File 已经汉化为 文件(&F) 的程序。先运行到 00492075 ,再开启 004D593F 断点并执行到
那里。

[attachmentid=26158]

查看 EBX 的数据,看到了吧,问题很明显,Noise Ninja 在这里转码出现了错误。本应该转成
CEC4 BCFE 2800 2600 4600 2900 而程序却转成 CE00 C400 BC00 FE00 2800 2600 4600 2900 ,也就是双字节字符
转错了。那个转码循环只是在 ASCI 码字符串的每个字节后面插入 00 来转的,英文字母这样转不会出错,但中文
就完全不对了。
问题找到了,那就来着手解决,要实现正确的转码,需要用到 MultiByteToWideChar 这个函数,先说说此函数各个
参数的含义。

[attachmentid=26159]

第一个参数 CodePage :代码页,简体中文取 3A8 ,也就是 936 。
第二个参数 Options :选项,一般取 0 值。
第三个参数 StringToMap :ANSI 字符串的地址。
第四个参数 StringSize :ANSI 字符串的长度,如果用 -1, 就表示是用 0 作为结束符的字符串。
第五个参数 WideCharBuf :转码后的字符串保存地址。取字符串长度时为 Null 。
第六个个参数 WideBufSize :注意是字符串的长度,也就是一个中文字是 1 ,而不是字符串的字节长度。用于
取得字符串长度时为零。在这里我曾经走过弯路,刚开始用的是软件本身提供的长度,后来才发现,软件提供的
长度是字节长度,而不是字符长度,导致显示的中文后面有乱码。

在修改代码过程中,共用了两次 MultiByteToWideChar ,第一次用它来获得字符串的字符长度,第二次则是转码。
由于是在程序代码间隙里找的空间,一个间隙往往不能一次放下所有代码,所以我的代码看上去有好多跳转,但那
并不是必须的。因此下面我只写出必要的代码,你可以根据实际情况灵活运用。
下图是修改前的代码:

[attachmentid=26160]

下图是修改后的两次调用 MultiByteToWideChar 代码,之所以用 Call 是为了省却维护堆栈平衡的麻烦。

[attachmentid=26161]

使用第一次 MultiByteToWideChar 获得字符串字符长度,其长度值保存到 EAX 中,其中寄存器要根据实际情况
来设定,比如说我这里字符串地址是在 EDI ,而你的程序可能是在 EBX :

PUSH 0
PUSH 0
PUSH -1
PUSH EDI
PUSH 0
PUSH 3A8
CALL MultiByteToWideChar
RETN

第二次使用 MultiByteToWideChar 进行转码,寄存器的使用也是根据实际情况而定,转换后的字符串保存在 EBX:

PUSH ESI
PUSH EBX
PUSH -1
PUSH EDI
PUSH 0
PUSH 3A8
CALL MultiByteToWideChar
RETN

再来看看最后一张图,两个 Call 之间怎么有一个 DEC EAX ,这是因为获得的字符串长度比实际长度长 1 ,所以
这里减 1 。

看看实际运行效果。

[attachmentid=26162]

文章中错误之处还请指正。

小图 | 大图 图片

  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
  • Noise Ninja 汉化乱码的解决|Windows 软件汉化 - 汉化新世纪论坛
宇宙经过120亿年的漫长进化才有一个独一无二的你存在这个世界上,其概率如此之小,已无法用数字来描述...
离线赵斯聪

发帖
249
金钱
20
威望
2
只看该作者 1 发表于: 2009-07-24
Hmm... 这样至少可以解决编译为适用于 Windows 的 EXE 文件存在的问题(因为 QT 库是为跨平台编译设计的,所以似乎并不调用任何 Win API 函数),不过这应该也足够了,毕竟这里没人汉化 UNIX 的程序……
明眼人做明眼事,固步自封是要挨打的;怎样抉择才算珍爱生命,我想人人都应该知道。为正受凌辱而浑然不觉的人们默哀……
离线samuel1991

发帖
746
金钱
150
威望
15
只看该作者 2 发表于: 2009-07-24
QUOTE(赵斯聪 @ 2009年 07月 24日 17时 59分) [snapback]361212[/snapback]

Hmm... 这样至少可以解决编译为适用于 Windows 的 EXE 文件存在的问题(因为 QT 库是为跨平台编译设计的,所以似乎并不调用任何 Win API 函数),不过这应该也足够了,毕竟这里没人汉化 UNIX 的程序……


這是因為 UNIX,蘋果電腦的用戶少吧。

知道多一點總是比較好,儘管我現在還不是很看得懂海子的教程。。。。(牽涉到反編匯,OllyDBG 的東西,我一點常識也沒有)
离线赵斯聪

发帖
249
金钱
20
威望
2
只看该作者 3 发表于: 2009-07-24
QUOTE
牽涉到反編匯,OllyDBG 的東西,我一點常識也沒有

其实我对编程和汇编根本就一窍不通,只不过知道几个概念罢了……
明眼人做明眼事,固步自封是要挨打的;怎样抉择才算珍爱生命,我想人人都应该知道。为正受凌辱而浑然不觉的人们默哀……
离线大牛

发帖
3299
金钱
1760
威望
176
只看该作者 4 发表于: 2009-07-24
好文,慢慢消化中
天为什么这么黑, 因为牛在天上飞。
牛为什么飞天上, 因为我在地上吹!
汉化 摄影 音响CAD→→清风工作室
离线wozhangjia

发帖
16
金钱
0
威望
0
只看该作者 5 发表于: 2009-07-31
离线wanfu

发帖
2666
金钱
11510
威望
1151
只看该作者 6 发表于: 2009-07-31
刚看到,好文,学习了,已添加到教学中。其实汉化最难的就是字体乱码或偏大偏小的处理。
离线pyf_3721

发帖
390
金钱
9870
威望
987
只看该作者 7 发表于: 2009-08-01
用户被禁言,该主题自动屏蔽!
离线pyf_3721

发帖
390
金钱
9870
威望
987
只看该作者 8 发表于: 2009-08-02
用户被禁言,该主题自动屏蔽!
离线qiuqiuye

发帖
153
金钱
90
威望
9
只看该作者 9 发表于: 2009-08-03
看来反汇编的水平在一定程度上能彰显汉化水平啊,学习了