吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6590|回复: 32
收起左侧

[原创] 解决vb6和delphi7在win10下输入中文乱码问题

  [复制链接]
苏紫方璇 发表于 2021-8-30 15:43
本帖最后由 苏紫方璇 于 2021-8-30 22:35 编辑

最近遇到一个问题,在win10下,部分vb6或者delphi7写的使用A函数控件的程序,TextBox输入中文总是乱码,而复制粘贴则正常。
在网上查找发现,目前通用的办法是删除美式键盘即可解决。
测试一下确实如此,但是,删除后会改变切换输入法的习惯,为了极个别老古董程序改习惯还是不太舒服的。于是就大致看了一下问题所在。
在网上搜索发现,输入法最后会发送一个WM_IME_CHAR的消息,其中包含了输入的文本。
既然是多字节的A类控件,断SendMessageA即可在输入汉字后触发断点。
程序断在user32中,向上查找发现部分流程。
代码如下

[Asm] 纯文本查看 复制代码
76801D16   .  33C0          xor eax,eax
76801D18   .  50            push eax
76801D19   .  50            push eax
76801D1A   .  68 00080000   push 0x800
76801D1F   .  51            push ecx
76801D20   .  3945 14       cmp dword ptr ss:[ebp+0x14],eax
76801D23   .  0F84 DE000000 je user32.76801E07
76801D29   .  8B35 F4128576 mov esi,dword ptr ds:[0x768512F4]        ;  imm32.ImmGetCompositionStringA
76801D2F   .  8BCE          mov ecx,esi
76801D31   .  FF15 4C408576 call dword ptr ds:[0x7685404C]           ;  user32.767EEEA0
76801D37   .  FFD6          call esi
76801D39   .  8BF0          mov esi,eax
76801D3B   .  85F6          test esi,esi
76801D3D   .  0F84 64010000 je user32.76801EA7
76801D43   .  8D4E 01       lea ecx,dword ptr ds:[esi+0x1]
76801D46   .  51            push ecx                                 ; /dwBytes = 0x0
76801D47   .  6A 08         push 0x8                                 ; |dwFlags = HEAP_ZERO_MEMORY
76801D49   .  FF35 F0198576 push dword ptr ds:[0x768519F0]           ; |hHeap = 00430000
76801D4F   .  FF15 60378576 call dword ptr ds:[<&ntdll.RtlAllocateHe>; \RtlAllocateHeap
76801D55   .  894424 1C     mov dword ptr ss:[esp+0x1C],eax
76801D59   .  85C0          test eax,eax
76801D5B   .  0F84 46010000 je user32.76801EA7
76801D61   .  56            push esi
76801D62   .  8B35 F4128576 mov esi,dword ptr ds:[0x768512F4]        ;  imm32.ImmGetCompositionStringA
76801D68   .  8BCE          mov ecx,esi
76801D6A   .  50            push eax
76801D6B   .  68 00080000   push 0x800
76801D70   .  FF7424 30     push dword ptr ss:[esp+0x30]
76801D74   .  FF15 4C408576 call dword ptr ds:[0x7685404C]           ;  user32.767EEEA0
76801D7A   .  FFD6          call esi
76801D7C   .  8B4424 1C     mov eax,dword ptr ss:[esp+0x1C]
76801D80   .  8A08          mov cl,byte ptr ds:[eax]
76801D82   .  84C9          test cl,cl
76801D84   .  0F84 0A010000 je user32.76801E94
76801D8A   .  8B7C24 14     mov edi,dword ptr ss:[esp+0x14]
76801D8E   .  33F6          xor esi,esi
76801D90   .  46            inc esi
76801D91   .  8BD8          mov ebx,eax
76801D93   >  64:A1 1800000>mov eax,dword ptr fs:[0x18]
76801D99   .  8B90 DC0F0000 mov edx,dword ptr ds:[eax+0xFDC]
76801D9F   .  85D2          test edx,edx
76801DA1   .  79 02         jns short user32.76801DA5
76801DA3   .  03C2          add eax,edx
76801DA5   >  0FB780 980800>movzx eax,word ptr ds:[eax+0x898]
76801DAC   .  8D53 01       lea edx,dword ptr ds:[ebx+0x1]
76801DAF   .  51            push ecx
76801DB0   .  50            push eax
76801DB1   .  895424 30     mov dword ptr ss:[esp+0x30],edx
76801DB5   .  FF15 78338576 call dword ptr ds:[<&api-ms-win-core-loc>;  KernelBa.IsDBCSLeadByteEx
76801DBB   .  85C0          test eax,eax
76801DBD   .  74 29         je short user32.76801DE8
76801DBF   .  8B4424 28     mov eax,dword ptr ss:[esp+0x28]
76801DC3   .  8A00          mov al,byte ptr ds:[eax]
76801DC5   .  84C0          test al,al
76801DC7   .  74 1C         je short user32.76801DE5
76801DC9   .  0FB60B        movzx ecx,byte ptr ds:[ebx]
76801DCC   .  56            push esi                                 ; /lParam = 0x2BF1E94
76801DCD   .  C1E1 08       shl ecx,0x8                              ; |
76801DD0   .  0FB6C0        movzx eax,al                             ; |
76801DD3   .  0BC8          or ecx,eax                               ; |
76801DD5   .  51            push ecx                                 ; |wParam = 0x0
76801DD6   .  68 86020000   push 0x286                               ; |Message = WM_IME_CHAR
76801DDB   .  57            push edi                                 ; |hWnd = 0x767CDDB0
76801DDC   .  E8 DF02FDFF   call user32.SendMessageA                 ; \SendMessageA
76801DE1   .  8B5C24 28     mov ebx,dword ptr ss:[esp+0x28]
76801DE5   >  43            inc ebx
76801DE6   .  EB 14         jmp short user32.76801DFC
76801DE8   >  0FB603        movzx eax,byte ptr ds:[ebx]
76801DEB   .  56            push esi                                 ; /lParam = 0x2BF1E94
76801DEC   .  50            push eax                                 ; |wParam = 0x0
76801DED   .  68 86020000   push 0x286                               ; |Message = WM_IME_CHAR
76801DF2   .  57            push edi                                 ; |hWnd = 0x767CDDB0
76801DF3   .  E8 C802FDFF   call user32.SendMessageA                 ; \SendMessageA     <<============断在这里
76801DF8   .  8B5C24 28     mov ebx,dword ptr ss:[esp+0x28]
76801DFC   >  8A0B          mov cl,byte ptr ds:[ebx]
76801DFE   .  84C9          test cl,cl
76801E00   .^ 75 91         jnz short user32.76801D93


系统调用ImmGetCompositionStringA获取输入法输入的字符,这里正常没错,之后通过程序TEB定位到程序的代码页,
使用IsDBCSLeadByteEx确定是否是中文,是就走第一个send,发送多字节,不是就走第二个(即断下位置),发送单字节。
问题就出现在这里了,获取到的代码页为1252,并非中文的936,导致IsDBCSLeadByteEx认为不是中文,走了第二个send。
之后测试在程序断在入口点时,将1252改为936,程序正常输入中文了。

代码页定位:TEB-->0xFDC(WowTebOffset),加上偏移后得到TEB64-->(0x800+0x98)Win32ClientInfo.CodePage( win32k!tagCLIENTINFO结构体)

最后,改下pe文件或者整个dll加载进去,把代码页改了齐活。

免费评分

参与人数 15威望 +1 吾爱币 +38 热心值 +13 收起 理由
l2430478 + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
liuzqm + 1 + 1 我很赞同!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
willgoon + 1 + 1 我很赞同!
yan182 + 1 + 1 我很赞同!
阳光好青年 + 1 + 1 今日最佳。
zhczf + 1 我很赞同!
suadzh + 1 + 1 谢谢@Thanks!
朱朱你堕落了 + 3 + 1 用心讨论,共获提升!
冥界3大法王 + 1 膜拜
yirenjieqian + 1 热心回复!
笙若 + 1 + 1 谢谢@Thanks!
bjxiaoyao + 2 + 1 我很赞同!
antclt + 1 + 1 我很赞同!
马云爱逛京东 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 苏紫方璇 发表于 2021-8-30 17:54
flyingdancex 发表于 2021-8-30 16:57
意思是要改系统user32.dll文件里的IsDBCSLeadByteEx,还是,唉~!还是没看明白...

改代码页就可以了,之所以没出成品,因为我无法定位修改的位置,不同的系统位置不一样
头像被屏蔽
白鱼啊 发表于 2022-4-19 16:23
antclt 发表于 2021-8-30 16:12
flyingdancex 发表于 2021-8-30 16:57
意思是要改系统user32.dll文件里的IsDBCSLeadByteEx,还是,唉~!还是没看明白...

点评

改代码页就可以了,之所以没出成品,因为我无法定位修改的位置,不同的系统位置不一样  详情 回复 发表于 2021-8-30 17:54
bjxiaoyao 发表于 2021-8-30 18:13
学习了,原来系统问题还可以这样分析,这才是从根源上解决问题。虽然最难,但是最彻底。
阿迪服饰 发表于 2021-8-30 20:03
可以很强大
阿迪服饰 发表于 2021-8-30 20:03
可以很强
suadzh 发表于 2021-8-30 22:05
苏紫方璇YYDS
lovehfs 发表于 2021-8-30 22:33
值得试一下
Sky_M 发表于 2021-8-31 09:18
虽然没用,先留着以后用
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 15:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表