首页
社区
课程
招聘
[原创]修复在win8.1下无法安装并正常运行VC6的问题
发表于: 2017-6-17 15:30 4247

[原创]修复在win8.1下无法安装并正常运行VC6的问题

2017-6-17 15:30
4247

安装

首先,安装等待很久的问题参考之前发布的这个帖子http://bbs.pediy.com/thread-178928.htm。操作完了,不要解除OD的附加,下面还会用到。

然后,安装程序将文件复制完毕后,会出现无法退出程序,CPU利用率奇高不下的问题。

这时暂停运行,F8让程序单步走。走到类似下面的代码处:

CALL RegDeleteKey还是Value

CMP EDI,ESI ;需要修改这里的EDI为非零值,否则将无限循环 或者直接设置JE后的语句为新的IP

JE ......

POP XX

POP XX

RET

简单说就是安装程序中,安装完成本地文件后,设置安装信息的注册表时RegDeleteKey/Value删除注册表的键或者值失败了会陷入无限循环,需要跳过(win8.1下VB6的安装也会遇到这个问题)。

运行

安装完成后,默认是无法运行的,网上给的办法是改名MSDEV.EXE。但是改名了就无法加载PYG的VAX破解了。所以觉得不完美,也不知道改名能过的原理。之前调试研究过一次,没研究出来。昨天晚饭前花时间再去研究了一次,终于知道为什么了。

OD调试启动运行MSDEV.EXE,一路F8单步走,会在某个CALL之后VC崩溃。所以在这个CALL处下断点(下次调试中命中该断点时F7步入再F8),取消之前的断点。这样往复,会带你逐层深入到真正的出错的地方。发现是在这里崩溃的:

(好像是在DEVSHL.DLL中)

50030AE7       E8 00020000     call    <jmp.&MFC42.#CStringList::Find_2765>


F7进去后发现是在这里崩溃的

(mfc42.dll中)

0018ED20   00278010  |s1 = "devedit"

0018ED24   00278290  \s2 = "devprj"

6D4F7C28       FF15 0CA15A6D   call    dword ptr [<&msvcrt._mbscmp>]

也就是在调用导入表函数msvcrt.dll的_mbscmp。F7进去后看到进入了一片不像常规函数的区域,而且再一路F8继续运行下去就是未知指令了。这里肯定有问题。OD转到msvcrt._mbscmp的代码处看到是

770316B0 msvcrt._mbscmp        8BFF            mov     edi, edi

明显刚才CALL进去的不是这里,指令都不一样。

怀疑是mfc42.dll的导入表函数 [<&msvcrt._mbscmp>]未被正确设置。

重新调试,回到MSDEV.EXE的入口点,数据窗口中查看mfc42.dll的导入函数

6E8DA100 >76EB25C0  msvcrt._mbsupr

6E8DA104 >76E4AC50  msvcrt._mbspbrk

6E8DA108 >76E517C0  msvcrt._mbschr

6E8DA10C >00030000                              ;导入函数msvcrt._mbscmp的位置

6E8DA110 >76E3C5A0  msvcrt.realloc

6E8DA114 >76E46710  msvcrt.fclose

6E8DA118 >76E42D40  msvcrt.fflush

发现导入表就msvcrt._mbscmp这个位置被设置成了莫明的地址。周围其他都正常,手动将该地址的值恢复成msvcrt._mbscmp的真正地址,F9继续运行,VC真的就跑起来了。

那么是谁这么干的呢。我们继续探索,怀疑是mfc42.dll自己如果检查到是MSDEV.EXE,就改掉自己的msvcrt._mbscmp的值。

mfc42.dll的Dll入口函数处下断,发现他的msvcrt._mbscmp已经被修改了,说明不是自己改的。

那么我们在ntdll的PE加载器上下断,在mfc42.dll被映射到内存后,在他的导入表被填充前对他的导入表 [<&msvcrt._mbscmp>]的位置下写入时中断的硬件断点。继续运行发现,第一次中断时,

0x6D140000

C:\Windows\SysWOW64\mfc42.dll 6D140000 0012F000

mfc42.dll:6D24A10C db 0B0h ; 

mfc42.dll:6D24A10D db  16h

mfc42.dll:6D24A10E db    3

mfc42.dll:6D24A10F db  77h ; w

该位置被设置成了正确的值,这个调用来自ntdll内部,接着再继续运行,发现再次命中断点。这次是来自

C:\Windows\SysWOW64\apphelp.dll 71610000 000A0000

的_SepIatPatch函数,顾名思义就是什么导入表补丁的意思。

查看apphelp.dll的文件属性 他是“应用程序兼容性客户端库 ”,

就是他搞的鬼,真相终于水落石出了。

猜测微软在这个库中,应该内部标记了哪些程序是存在兼容性问题的程序,而对存在兼容性问题的程序进行可能的补丁修复。

MSDEV.EXE就在存在兼容性问题的程序之列。但是这里修复的是_mbscmp函数,ANSI本地语言多字节字符串比较函数。

由于某些有意或者无意的原因,该地址没被设置到正确的修复函数上。可能微软后面也发现问题了,但是想反正VC6都支持过期了,所以就得管了。

就和NSA工具漏洞一样,微软其实早就知道了这个问题,针对XP的修复补丁可能早就做好了(从后面发布的XP修复补丁的内部文件的签名日期可知该补丁2017年1月份就做好了,而3月份才NSA工具泄露,四月份才WannaCry爆发,阴谋论可能觉得是微软发布的这次病毒爆发(不然为什么还没查出来谁发布的),借机让大家认识到之前系统的不安全,win10的安全,间接推广win10新系统),但就是不到必要时就是不会放出来,对失去支持得系统及软件,都懒得管。

修复:

知道问题所在了,现在我们着手修复一下吧,为了不改变原始文件我们利用DLL劫持技术来完成工作,这里利用version.dll,因为这个文件会被VC6加载。

核心代码就是恢复mfc42.dll的导入表函数[<&msvcrt._mbscmp>]的函数地址为正确值。

详细见附件吧,完毕。

附件1是代码

附件2是成品文件,会优先加载MSDEV.EXE目录下的version.org.dll作为原始version.dll,这样做是为了让YPG的VAX补丁(名字也是version.dll,请先改名为version.org.dll再解压成品文件到VC6的程序目录)也可被顺利加载。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
2
谭书又能多卖几本了?(逃
2017-6-17 21:35
0
雪    币: 4531
活跃值: (5159)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
就算是专业的编程人员,有些时候出于某种目的也还是会有需要用到VC6的时候,如Internet  Download  Manager也还是用VC6开发的
2017-6-17 21:47
0
雪    币: 2058
活跃值: (1666)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
受教了,一直在用6  ,
2017-6-18 10:51
0
雪    币: 3739
活跃值: (3877)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
感谢分享!
2017-6-19 10:13
0
游客
登录 | 注册 方可回帖
返回
//