论坛风格切换切换到宽版
  • 15704阅读
  • 24回复

哪位帮助解决一下乱码问题 [复制链接]

上一主题 下一主题
离线wanfu

发帖
2734
金钱
12170
威望
1217
只看该作者 10 发表于: 2006-09-27
restools确实也是编程高手,谢谢!可惜我不懂编程。等我完全汉化完毕后也送给你一份。各位注意你们的汉化新世纪信箱。

不过有个建议,多出一个文件中总觉得别扭,可不可以将该段程序作为一个标准子程序,用类似于 Resoure Hacker 加到原文件中去呢?就像HTML文件被加到exe文件中一样,然后修改改动过的文件的调用地址。
离线

发帖
8854
金钱
161
威望
17
只看该作者 11 发表于: 2006-09-27
QUOTE(wanfu @ 2006年 09月 27日 17时 08分) [snapback]307618[/snapback]

restools确实也是编程高手,谢谢!可惜我不懂编程。等我完全汉化完毕后也送给你一份。各位注意你们的汉化新世纪信箱。

不过有个建议,多出一个文件中总觉得别扭,可不可以将该段程序作为一个标准子程序,用类似于 Resoure Hacker 加到原文件中去呢?就像HTML文件被加到exe文件中一样,然后修改改动过的文件的调用地址。

理论上应该可以的,但这样岂非更加提高了编程技术方面的门槛?
<a href="http://teach.hanzify.org/index.php?Go=Show::422-1074355200" target="_blank"><!--coloro:red--><span style="color:red"><!--/coloro-->正大光明赚钱求存,阳谋有私继续汉化</a><br /><a href="http://bbs.hanzify.org/index.php?showtopic=20135" target="_blank">新手提问必看</a><br />Exescope只是汉化辅助工具<br /><a href="http://teach.hanzify.org" target="_blank">看教学啊看教学!</a><br />你先动手,我再帮你!<!--colorc--></span><!--/colorc--><br /><img src="http://teach.hanzify.org/Images/hhteach.gif" border="0" alt="图像" /><br />多做补丁版,少做安装版...
离线tracky

发帖
1807
金钱
10
威望
1
只看该作者 12 发表于: 2006-09-28
QUOTE(restools @ 2006年 09月 27日 12时 29分) [snapback]307598[/snapback]

QUOTE(cao_cong @ 2006年 09月 27日 09时 32分) [snapback]307577[/snapback]
restools 兄这个方法好!比直接在程序中写补丁代码简单多了,学习!我看了你改的主程序,应该是用LordPE添加了你DLL中的导出函数,把一个调用SendMessageW的地方改成调用你的函数。严重学习!


你说的没错,就是这样搞,这样一来,任何人只需要学会一点点 OllyDBG 的东西,能找到软件功能实现的重点位置,改一下地址,立刻就可以把剩下的工作花在自己能够掌握的编程技术上,可以说你几乎可以不用接触ASM那种让人头晕的代码,无论你用的 VC++,Delphi,VB,C#…… 只要能写出 DLL 的编程软件,你就能够实现自己来为软件打补丁。



OD 会用一点点,就是还不会找到软件功能实现的重点位置!

QUOTE(wanfu @ 2006年 09月 27日 17时 08分) [snapback]307618[/snapback]

restools确实也是编程高手,谢谢!可惜我不懂编程。等我完全汉化完毕后也送给你一份。各位注意你们的汉化新世纪信箱。

不过有个建议,多出一个文件中总觉得别扭,可不可以将该段程序作为一个标准子程序,用类似于 Resoure Hacker 加到原文件中去呢?就像HTML文件被加到exe文件中一样,然后修改改动过的文件的调用地址。



可不可以也送我一份看看?
╭∩╮(︶︿︶)╭∩╮
离线cao_cong

发帖
403
金钱
40
威望
4
只看该作者 13 发表于: 2006-09-28
再来一个打过补丁的。本来想用LordPE直接添加程序中没有的函数WideCharToMultiByte和SendMessageA的,看了一下程序中有LoadLibraryA和GetProcAddress这两个函数,想想还是用这两个函数来获取WideCharToMultiByte和SendMessageA函数地址吧。因为调用的都是系统函数,我就不考虑用FreeLibrary来释放了。原本想直接抄restools兄的DLL文件中的代码来补丁的,不过堆栈平衡实在不大好处理,反而耗了我很多时间。最后干脆直接写了。我在程序的最后添加了一个大小为400H的区段用来写代码,主要是在程序中找不到够写代码的空间了。
贴上用于OllyDBG的写补丁代码插件NonaWrite的代码,我在里面都加了注释,应该容易理解。在程序中添加一个区段后就可以用OD载入,再用NonaWrite插件把这些代码直接写到程序中保存就行了:
CODE

;变量:
;temp1:用来存放用GetProcAddress获取的WideCharToMultiByte函数地址。
;偏移:00039639,VA:0043B039

;temp2:用来存放用GetProcAddress获取的SendMessageA函数地址。
;偏移:0003963E,VA:0043B03E

;temp3:用来保存调用SendMessageW时的句柄。
;偏移:00039643,VA:0043B043

;temp4:用来保存要转换的字串地址。
;偏移:00039648,VA:0043B048

;temp5:分配200字节用来作为转换字串的缓冲区
;偏移:00039660,VA:0043B060
;结束偏移:00039860,VA:0043B260

;常量:
;const1:用来存放字串KERNEL32.dll。
;偏移:39600,RVA:00032C70,VA:0043B000

;const2:用来存放字串WideCharToMultiByte。
;偏移:3960D,VA:0043B00D

;const3:用来存放字串USER32.dll。
;偏移:39621,VA:0043B021

;const4:用来存放字串SendMessageA。
;偏移:3962C,VA:0043B02C

;其他:
;LoadLibraryA:
;VA:40105C

;GetProcAddress:
;VA:401060

;原程序中还要在418508处改一下:
;0x418508:
;call 43B270                              ;改成这个

;补丁代码:开始地址为0043B270
;获取WideCharToMultiByte和SendMessageA函数:
0x43B270:
pushad
mov eax,[esp+24]                      ;temp3,保存前面修改SendMessageW时的句柄
mov dword ptr [0043B043],eax
mov eax,[esp+30]                      ;temp4,保存要转换的字串地址
mov dword ptr [0043B048],eax
cmp dword ptr [0043B039],0      ;判断是否已获取了要用的函数
jnz 43B2ab                                ;out1
push 0043B000                         ;const1
call dword ptr[40105C]               ;调用LoadLibraryA
push 0043B00D                         ;const2
push eax
call dword ptr[401060]               ;调用GetProcAddress
mov dword ptr [0043B039],eax   ;保存WideCharToMultiByte函数地址到temp1
;out1
cmp dword ptr [0043B03E],0
jnz 43B2d1                               ;out2
push 0043B021                         ;const3
call dword ptr[40105C]               ;调用LoadLibraryA
push 0043B02C                         ;const4
push eax
call dword ptr[401060]               ;调用GetProcAddress
mov dword ptr [0043B03E],eax   ;保存SendMessageA函数地址到temp2
;out2,开始转换
push    0                                  ; lpUsedDefaultChar
push    0                                  ; lpDefaultChar
push    200                               ; cchMultiByte
push    0043B060                      ; temp5,lpMultiByteStr
push    -1                                 ; cchWideChar
push    dword ptr [0043B048]     ; temp4,lpWideCharStr
push    0                                  ; dwFlags
push    4E4                               ; CodePage
call    dword ptr[0043B039]         ;调用WideCharToMultiByte
mov    eax,0043B060
push    eax                               ; lParam
push    0                                  ; wParam
push    180                               ; Message = LB_ADDSTRING
push    dword ptr [0043B043]     ; hWnd
call    dword ptr[0043B03E]        ;调用SendMessageA
popad
ret 10

附件是修改过的主程序:
[attachmentid=21672]

附件: LOOMConfig.rar (72 K) 下载次数:146
离线wanfu

发帖
2734
金钱
12170
威望
1217
只看该作者 14 发表于: 2006-09-28
谢谢cao_cong最后大作,确实高明,采用了。
我也试了restools的方法,按照你cao_cong在8楼的方法,成功了。

另外,你提到的NonaWrite插件在你的汉化版本里好像没有?(我已在看雪论坛中找到)
离线restools

发帖
2848
金钱
1430
威望
143
只看该作者 15 发表于: 2006-09-28
非常不错啊,我也学了一把,可以不用添加函数引用。因为我一直的第一反应都是在 ImportTable中添加函数引用的。
我的BLOG:   http://restools.hanzify.org (Inno Setup 增强版, 插件 发布站点)
离线restools

发帖
2848
金钱
1430
威望
143
只看该作者 16 发表于: 2006-09-29
既然cc兄作了相当完美的解决方案出来,那我就借用一下,再把它处理的完善已点,以下的修改

CODE


;变量:
;首先,文件没有扩展任何实际大小,所有代码,常量都在文件的空隙中存放,至于变量,大部分使用的是虚的空间。这样做是因为文件实际上是没有足够实际空间的。
;先把文件的text段虚拟大小用尽也就是2F00,这不影响原来的程序结构的,据测试,好像改不改都可以用,不过还是按规矩修改了
;再把文件的data段虚拟大小用尽也就是3000,这不影响原来的程序结构的,据测试,好像改不改都可以用,不过还是按规矩修改了
;开放text的写入功能,使变量可以写入

;temp1:用来存放用GetProcAddress获取的WideCharToMultiByte函数地址。 ---把text段虚拟空间扩展到2F000,变量运行时放到虚的位置,就是文件中并不存在的位置
;VA:42FE28

;temp2:用来存放用GetProcAddress获取的SendMessageA函数地址。---同上
;VA:42FE2E

;temp3:用来保存调用SendMessageW时的句柄。---同上
;VA:42FE34

;temp4:用来保存要转换的字串地址。---同上
;VA:42FE3A

;temp5:分配190字节用来作为转换字串的缓冲区 ---放到 Data 段空闲位置,大部分是虚的,文件没有实位置
;VA:432E60 --使用靠在后面扩展的虚拟空间,因为这个段大多数会有数据写入,前面已经分配的虚拟空间不太安全
;0x190 就是 400 个字节,对于这个程序,我想应该足够了

;常量:
;const1:用来存放字串KERNEL32.dll。---------------------------原程序已有该字串,借用,省去空间
;VA:42F602

;const2:用来存放字串WideCharToMultiByte。---放到 text 段空闲位置 ,文件实位置
;VA:42FDE0

;const3:用来存放字串USER32.dll。---------------------------原程序已有该字串,借用,省去空间
;VA:42F6D4

;const4:用来存放字串SendMessageA。---放到 text 段空闲位置 ,文件实位置
;VA:42FDF4

;其他:
;LoadLibraryA:
;VA:40105C

;GetProcAddress:
;VA:401060

;原程序中还要在418508处改一下:
;0x418508:
;call 42FD3E                            ;改成这个

;补丁代码:开始地址为0042FD3E
;获取WideCharToMultiByte和SendMessageA函数:
0x42FD3E:
pushad
mov eax,[esp+24]                    ;temp3,保存前面修改SendMessageW时的句柄, ListBox 句柄
mov dword ptr [42FE34],eax
mov eax,[esp+30]                    ;temp4,保存要转换的字串地址, 错误字符串的地址,准备用来修复
mov dword ptr [42FE3A],eax
cmp dword ptr [42FE28],0            ;temp1,WideCharToMultiByte判断是否已获取了要用的函数,如果有跳转,不再获取
jnz 42FD7C                          ;out1
push 42F602                         ;const1
call dword ptr[40105C]              ;调用LoadLibraryA
push 42FDE0                         ;const2
push eax
call dword ptr[401060]              ;调用GetProcAddress
mov dword ptr [42FE28],eax          ;保存WideCharToMultiByte函数地址到 temp1
;out1
cmp dword ptr [42FE2E],0            ;temp2,判断是否已获取了要用的函数,如果有跳转,不再获取
jnz 43FDA2                          ;out2
push 42F6D4                         ;const3,字串USER32.dll
call dword ptr[40105C]              ;调用LoadLibraryA
push 42FDF4                         ;const4,字串SendMessageA
push eax
call dword ptr[401060]              ;调用GetProcAddress
mov dword ptr [42FE2E],eax          ;保存SendMessageA函数地址到temp2
;out2,开始转换
push    0                        ; lpUsedDefaultChar
push    0                        ; lpDefaultChar
push    190                         ; cchMultiByte
push    432E60                      ; temp5,lpMultiByteStr
push    -1                          ; cchWideChar
push    dword ptr [42FE3A]          ; temp4,lpWideCharStr
push    0                        ; dwFlags
push    4E4                         ; CodePage
call    dword ptr[42FE28]        ; temp1,调用WideCharToMultiByte
mov    eax,432E60                ; 输出正确的 ANSI 字符串
push    eax                         ; lParam
push    0                        ; wParam
push    180                         ; Message = LB_ADDSTRING
push    dword ptr [42FE34]          ; temp3,hWnd
call    dword ptr [42FE2E]          ; 调用SendMessageA
popad
ret 10




文件没增加一个字节,资源段仍然处在最后位置,可以用资源编辑工具继续编辑而无需担心。
附件: LOOMConfig.rar (72 K) 下载次数:134
我的BLOG:   http://restools.hanzify.org (Inno Setup 增强版, 插件 发布站点)
离线shoooo
发帖
61
金钱
0
威望
0
只看该作者 17 发表于: 2006-09-29
只有学习了
离线cao_cong

发帖
403
金钱
40
威望
4
只看该作者 18 发表于: 2006-09-29
restools兄这个更好,学习!
离线wxz8
发帖
344
金钱
10
威望
1
只看该作者 19 发表于: 2006-09-29
强贴必留名,学习了。