首页
社区
课程
招聘
[原创]让Hex Workshop V6.0.1.4603支持中文路径
发表于: 2010-6-26 13:18 10402

[原创]让Hex Workshop V6.0.1.4603支持中文路径

2010-6-26 13:18
10402

近日空闲的时候将Hex Workshop v5升成了v6,结果发现它的右键菜单不支持中文路径,造成桌面上的文件无法用右键菜单打开,很是不方便,于是有了给v6动一下手术的想法。首先用上IDA和OD两个法宝,很快确定问题在以下两处位置的代码:

获取并传递文件名的过程:
.text:004862E0                 lea     edx, [ebp+824h+var_838]
.text:004862E3                 push    edx
.text:004862E4                 lea     ecx, [ebp+824h+var_890] ; 读取右键菜单通过临时文件传入的多字节文件名
.text:004862E7                 call    ?ReadString@CStdioFile@@UAEHAAV?$CStringT@_WV?$StrTraitMFC@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@@Z ; CStdioFile::ReadString(ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &)
.text:004862EC                 cmp     eax, ebx
.text:004862EE                 jz      short loc_48632A
.text:004862F0                 lea     ecx, [ebp+824h+var_838]
.text:004862F3                 call    sub_476130
.text:004862F8                 lea     ecx, [ebp+824h+var_838]
.text:004862FB                 call    sub_476220
.text:00486300                 mov     ecx, [ebp+824h+var_838]
.text:00486303                 lea     edx, [ebp+824h+var_824]
.text:00486306
.text:00486306 loc_486306:                             ; CODE XREF: sub_4861D0+145 j
.text:00486306                 movzx   eax, word ptr [ecx]
.text:00486309                 mov     [edx], ax
.text:0048630C                 add     ecx, 2
.text:0048630F                 add     edx, 2
.text:00486312                 cmp     ax, bx
.text:00486315                 jnz     short loc_486306
.text:00486317                 mov     eax, [ebp+824h+var_83C]
.text:0048631A                 push    ebx
.text:0048631B                 push    ebx
.text:0048631C                 push    eax
.text:0048631D                 lea     ecx, [ebp+824h+var_824]
.text:00486320                 push    ecx
.text:00486321                 mov     ecx, edi
.text:00486323                 call    sub_484850      ; 传入 UNICODE 格式文件名到打开文件过程
.text:00486328                 jmp     short loc_4862E0

打开文件的过程,由调用CreateFileW可以知道文件名必须是UNICODE格式。
.text:00548222 loc_548222:                             ; CODE XREF: sub_548140+C4 j
.text:00548222                 push    0               ; hTemplateFile
.text:00548224                 push    80h             ; dwFlagsAndAttributes
.text:00548229                 push    3               ; dwCreationDisposition
.text:0054822B                 push    0               ; lpSecurityAttributes
.text:0054822D                 push    3               ; dwShareMode
.text:0054822F                 push    80000000h       ; dwDesiredAccess
.text:00548234                 lea     ecx, [esp+838h+FileName]
.text:00548238                 push    ecx             ; lpFileName
.text:00548239                 call    ds:CreateFileW  ; 打开 UNICODE 文件名的文件
.text:0054823F                 cmp     eax, 0FFFFFFFFh
.text:00548242                 jz      short loc_548257
.text:00548244                 push    eax             ; hObject
.text:00548245                 call    ds:CloseHandle
.text:0054824B                 mov     eax, 1
.text:00548250                 add     esp, 820h

通过上面的两段代码,可以知道Hex Workshop使用了CStdioFile::ReadString读取临时文件传入的多字节文件路径。CStdioFile读取ANSI文本数据时按char类型读取,在_MSBC下可以直接填充到CString,在UNICODE环境下要先将char转换成宽字符WCHAR,然后再填充到CString,即一个汉字的两个char将变成两个UNICODE字符WCHAR。因此CStudioFile在_MSBC环境下读取任何ANSI文本数据都没问题,在UNICODE环境下读取ANSI文本中的中文时就会显示乱码,但原来的汉字信息并没有丢失。知道了原因就好解决了,在text段发现还有100多字节的空间,于是添加下面的补丁代码:

跳转到补丁代码:
.text:004862E0 loc_4862E0:                             ; CODE XREF: sub_4861D0+158 j
.text:004862E0                 lea     edx, [ebp+824h+lpWideCharStr]
.text:004862E3                 push    edx
.text:004862E4                 lea     ecx, [ebp+824h+var_890]
.text:004862E7                 call    ?ReadString@CStdioFile@@UAEHAAV?$CStringT@_WV?$StrTraitMFC@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@@Z ; CStdioFile::ReadString(ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &)
.text:004862EC                 cmp     eax, ebx
.text:004862EE                 jmp     loc_68AF88      ; 跳转到补丁代码
.text:004862F3 ; ---------------------------------------------------------------------------
.text:004862F3
.text:004862F3 loc_4862F3:                             ; CODE XREF: sub_4861D0+204E2B j
.text:004862F3                 call    sub_476130
.text:004862F8                 lea     ecx, [ebp+824h+lpWideCharStr]
.text:004862FB                 call    sub_476220
.text:00486300                 mov     ecx, [ebp+824h+lpWideCharStr]
.text:00486303                 lea     edx, [ebp+824h+var_824]
.text:00486306
.text:00486306 loc_486306:                             ; CODE XREF: sub_4861D0+145 j
.text:00486306                 movzx   eax, word ptr [ecx]
.text:00486309                 mov     [edx], ax
.text:0048630C                 add     ecx, 2
.text:0048630F                 add     edx, 2
.text:00486312                 cmp     ax, bx
.text:00486315                 jnz     short loc_486306
.text:00486317                 mov     eax, [ebp+824h+var_83C]
.text:0048631A                 push    ebx
.text:0048631B                 push    ebx
.text:0048631C                 push    eax
.text:0048631D                 lea     ecx, [ebp+824h+var_824]
.text:00486320                 push    ecx
.text:00486321                 mov     ecx, edi
.text:00486323                 call    sub_484850

补丁代码:
.text:0068AF88 loc_68AF88:                             ; CODE XREF: sub_4861D0+11E j
.text:0068AF88                 jz      loc_48632A
.text:0068AF8E                 push    520h            ; uBytes
.text:0068AF93                 push    40h             ; uFlags
.text:0068AF95                 call    ds:LocalAlloc      ;分配内存
.text:0068AF9B                 cmp     eax, ebx
.text:0068AF9D                 jz      short loc_68AFF8
.text:0068AF9F                 push    eax        ;保存分配的内存指针
.text:0068AFA0                 mov     ecx, [ebp+824h+lpWideCharStr]    ;将WCHAR转换成多字节
.text:0068AFA3                 mov     edx, eax
.text:0068AFA5
.text:0068AFA5 loc_68AFA5:                             ; CODE XREF: sub_4861D0+204DE3 j
.text:0068AFA5                 movzx   eax, word ptr [ecx]
.text:0068AFA8                 mov     [edx], al
.text:0068AFAA                 add     ecx, 2
.text:0068AFAD                 add     edx, 1
.text:0068AFB0                 cmp     ax, bx
.text:0068AFB3                 jnz     short loc_68AFA5
.text:0068AFB5                 pop     eax  
.text:0068AFB6                 push    eax
.text:0068AFB7                 sub     edx, eax       ;计算字符串长度
.text:0068AFB9                 push    edx             ; cchWideChar
.text:0068AFBA                 mov     edx, [ebp+824h+lpWideCharStr]
.text:0068AFBD                 push    edx             ; lpWideCharStr
.text:0068AFBE                 push    0FFFFFFFFh      ; cbMultiByte
.text:0068AFC0                 push    eax             ; lpMultiByteStr
.text:0068AFC1                 push    0               ; dwFlags
.text:0068AFC3                 push    0FDE9h          ; CodePage
.text:0068AFC8                 call    ds:MultiByteToWideChar    ;转换成UNICODE到原来的字符串内存池
.text:0068AFCE                 jmp     short loc_68AFF0
.text:0068AFCE ; END OF FUNCTION CHUNK FOR sub_4861D0
.text:0068AFCE ; ---------------------------------------------------------------------------
.text:0068AFD0                 dd 8 dup(0)
.text:0068AFF0 ; ---------------------------------------------------------------------------
.text:0068AFF0 ; START OF FUNCTION CHUNK FOR sub_4861D0
.text:0068AFF0
.text:0068AFF0 loc_68AFF0:                             ; CODE XREF: sub_4861D0+204DFE j
.text:0068AFF0                 pop     eax
.text:0068AFF1                 push    eax             ; hMem
.text:0068AFF2                 call    ds:LocalFree     ;释放申请的内存
.text:0068AFF8
.text:0068AFF8 loc_68AFF8:                             ; CODE XREF: sub_4861D0+204DCD j
.text:0068AFF8                 lea     ecx, [ebp+824h+lpWideCharStr]  恢复原位置代码
.text:0068AFFB                 jmp     loc_4862F3    ;返回原跳转处
.text:0068AFFB ; END OF FUNCTION CHUNK FOR sub_4861D0
.text:0068AFFB _text           ends.text:0068AFF0 ; START OF FUNCTION CHUNK FOR sub_4861D0

再用神奇F5看看,相应的代码从:
   while ( CStdioFile__ReadString(&v50) )
      {
        sub_476130(&v50);
        sub_476220(&v50);
        v5 = v50;
        v4 = &v55;
        do
        {
          v6 = *(_WORD *)v5;
          *(_WORD *)v4 = *(_WORD *)v5;
          v5 += 2;
          v4 += 2;
        }
        while ( v6 );
        sub_484850(&v55, v49, 0, 0);
      }

变成了:
      while ( CStdioFile__ReadString(&lpWideCharStr) )
      {
        //对应补丁代码
        v29 = LocalAlloc(0x40u, 0x520u);
        if ( v29 )
        {
          v34 = (int)v29;
          v31 = lpWideCharStr;
          v30 = v29;
          do
          {
            v32 = *v31;
            *(_BYTE *)v30 = *v31;
            ++v31;
            ++v30;
          }
          while ( v32 );
          MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)v34, -1, lpWideCharStr, (int)((char *)v30 - v34));
          LocalFree((HLOCAL)v34);
        }
        sub_476130();
        sub_476220(&lpWideCharStr);
        v6 = lpWideCharStr;
        v5 = &v59;
        do
        {
          v4 = *v6;
          *(_WORD *)v5 = *v6;
          ++v6;
          v5 += 2;
        }
        while ( v4 );
        sub_484850(&v59, v53, 0, 0);
      }

     经测试,在XP SP3平台运行效果良好。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 86
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
非常不错  楼主很强大
2010-6-27 18:51
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
请教一下一些韩文无法正常显示如何解决?
2010-7-11 15:16
0
雪    币: 291
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
分析的光划。
顺便将查看中文乱码的问题也解决一下
2010-7-13 17:46
0
雪    币: 213
活跃值: (507)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
Hex Workshop V6 是UNICODE编码的,但处理时有问题,所以汉字不能正常显示。如果有看雪的网友需要,我可以传上来。
上传的附件:
2010-7-13 20:16
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
呵呵,肯定有需要的,希望楼主上传能显示中文的版本
2010-7-14 10:10
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我的系统跟楼主一样的呀,怎么我还是不能打开桌面上的文件?
2010-7-14 10:20
0
雪    币: 8826
活跃值: (3063)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
楼主传上能显示中文的版本来呀
2010-10-10 14:31
0
雪    币: 578
活跃值: (808)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
不错,好强大,学习学习
2010-10-24 18:05
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
11
支持上传可以显示中文的版本
2010-10-26 21:51
0
雪    币: 191
活跃值: (345)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
12
既然修复了,就发上来大家共享下喽.呵呵
2010-11-2 14:41
0
游客
登录 | 注册 方可回帖
返回
//