既然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
文件没增加一个字节,资源段仍然处在最后位置,可以用资源编辑工具继续编辑而无需担心。