首页
社区
课程
招聘
[原创]让VC7系列生成VC6支持PDB格式,以便VC6IDE可以调试
发表于: 2009-9-18 13:10 10181

[原创]让VC7系列生成VC6支持PDB格式,以便VC6IDE可以调试

2009-9-18 13:10
10181

让VC7系列生成VC6支持PDB格式,以便VC6IDE可以调试
morning.ye 2009-9-18

我们知道 阅读VC7系列的 atl/mfc 源代码可以看到,VC7似乎具备生成 vc6 pdb文件的能力,其中参数分别是
cl.exe:        /Zvc6
link.exe: /debugtype:vc6

但是,很遗憾,如果我们把这个参数加上,它们纷纷表示,不认识.
当然,到底是否支持,调试一下才知道,通过分析,发现只是前端接口关掉了,不接受这些参数,但是内部实现确实支持的.
OK,patch它们.

准备工作:
拷贝一份vc2002/2003bin目录到vc6bin目录,把vc6的改名,vc2003toolkit也可以
从PSDK/DDK2003等地方拷贝 mspdb60.dll,版本号应该是6.2

开始修改
1.1修改编译前端
分别用od加载c1.dll,c1xx.dll,搜索字符串 mspdb60.dll,在前方不远处有一个比较,记下这个全局变量的地址,在 LoadPE里转成 offset,并将原来的0改成1
c1.dll 在偏移10678a11处,将原来的0改成1
c1xx.dll 在偏移1058D3B1处,将原来的0改成1
1.2修改编译后端:c2略麻烦一点,不过调试类似,
c2.dll 在偏移1070744C处,将原来的1D改成3D

2.修改连接器
link.exe
0042A4DC      8A98 60010000 mov     bl, byte ptr [eax+160]
0042A4E2      84DB          test    bl, bl
0042A4E4  |.  56            push    esi
0042A4E5  |.  57            push    edi
0042A4E6      74 0B         je      short link.0042A4F3
0042A4E8  |.  BF AC3C4000   mov     edi, link.00403CAC                   ;  mspdb60.dll
0042A4ED  |.  897C24 0C     mov     dword ptr [esp+C], edi
0042A4F1  |.  EB 0C         jmp     short link.0042A4FF
0042A4F3  |>  C74424 0C A03>mov     dword ptr [esp+C], link.00403CA0     ;  mspdb71.dll
0042A4FB  |.  8B7C24 0C     mov     edi, dword ptr [esp+C]
0042A4FF  |>  57            push    edi                                  ; /FileName
0042A500  |.  FF15 A4104000 call    dword ptr [<&KERNEL32.LoadLibraryA>] ; \LoadLibraryA

改成
0042A4DC      B3 01         mov     bl, 1                                                        //把原来的判断改成赋值
0042A4DE      8898 60010000 mov     byte ptr [eax+160], bl                        //
0042A4E4  |.  56            push    esi
0042A4E5  |.  57            push    edi
0042A4E6      90            nop                                                                                //不再跳转,其实跳转也没关系,因为后面我们会替换这个名字
0042A4E7      90            nop
0042A4E8  |.  BF AC3C4000   mov     edi, link.00403CAC                         ;  mspdb60.dll
0042A4ED  |.  897C24 0C     mov     dword ptr [esp+C], edi
0042A4F1  |.  EB 0C         jmp     short link.0042A4FF
0042A4F3  |>  C74424 0C A03>mov     dword ptr [esp+C], link.00403CA0           ;  mspdb71.dll
0042A4FB  |.  8B7C24 0C     mov     edi, dword ptr [esp+C]
0042A4FF  |>  57            push    edi                                        ; /FileName
0042A500  |.  FF15 A4104000 call    dword ptr [<&KERNEL32.LoadLibraryA>]       ; \LoadLibraryA

3.用16进制编译器打开 c1.dll,c1xx.dll,c2.dll,cl.exe,link.exe
搜索 pdb71.dll 全部改成 pdb60.dll

4.在link.exe中把 ?Open@PDB@@SAHPBD0KPAJQADPAPAU1@@Z 改成 ?Open@PDB@@SAHPAD0KPAJQADPAPAU1@@Z
因为 pdb60.dll 把参数声明为 char*,而pdb71.dll把参数声明为 const char*,这导致修改符不同

5.从PSDK/DDK任何能找到 mspdb60.dll的地方把 6.2 版的mspdb60.dll 拷贝进去

OK,一切搞定,现在新建一个console工程,编译debug配置,可以看到 生成的文件内部已经是 NB10 标记的 PDB 文件了,开始调试,不再提示没有符号文件,可以正常显示变量等信息.

附件已上传,是基于VC7.1SP1修改的,不打算自己挨个改一遍的朋友,找个VC2003bin目录拷贝后,用压缩包里的文件覆盖一下就OK了.


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
1.
如果提示找不到 ftol2

源代码中加上
extern "C" long _cdecl _ftol(double x);
long _cdecl _ftol2(double x){return _ftol(x);}

2.
关掉 /GZ,避免提示找不到 _SEH_epilog , _SEH_prolog
如果不关掉,可以从 PSDK2003 中拷贝sehprolg.obj,添加到工程
2009-9-18 13:15
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
现在,可以继续使用 VC6这个轻快的IDE,配合VAX的书写代码提示,然后用VC7.1这个更标准的编译器编译了
还可以再拷贝一个 vcpkg,从而自动切换编译平台生成 i386/amd64 的目标文件

enjoy it!
2009-9-18 13:16
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
顶!很好的参考
2009-9-18 13:21
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
5
LZ今日发了不少VC相关的好文,等着加精吧
2009-9-18 20:15
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
附件已上传,适合懒人解压覆盖..
2009-9-18 22:19
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
试用了。确实可以调试了。
不过编译过程中,出来N多的警告:warning LNK4231: /TMP incompatible。。。。。

不知道什么原因啊?

我是VC6SP6,bin, include, lib全部换成了VC++2003 TOOLKIT的。
另外,替换了LZ的文件后,需要用msvcr70.dll,本来是用的msvcr71.dll。
2009-9-26 17:08
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
刚才看了一下,因为 mspdb60.dll 是连接到 msvcr70.dll的,所以,加了这个mspdb60.dll ,还需要 msvcr70.dll,不过从XP开始,系统已经自带这个dll了.

建议你使用 VC6的lib,这样才能保证不会连接到早期系统不存在的函数啊.

由于这个mspdb60.dll 只能识别早期 VC7.0和更早期的VC6之类的生成的obj中的提示信息,所以,如果你使用新版VC生成的obj/lib,那么其中的信息是会忽略的,警告是 warning LNK4231: /TMP incompatible 什么的(当然,你用这个修改版编译器生成的obj/lib不存在这个问题,因为本身是通过 mspdb60.dll 生成的).如果你不调试进入lib的领空,连接到新版VC生成的obj/lib也没关系.如果打算用新版VC的ATL,MFC,你可以用这个修改后的编译器重建一次,这样,调试时会比较方便.
2009-9-27 20:59
0
游客
登录 | 注册 方可回帖
返回
//