首页
社区
课程
招聘
[原创]masm32开发包与VC6.0之间存在的Bug的体现及解决办法
发表于: 2018-2-8 23:29 6096

[原创]masm32开发包与VC6.0之间存在的Bug的体现及解决办法

2018-2-8 23:29
6096

概览:本文做了个Demo测试小程序来体现masm32开发包的库与VC6.0存在的一些不兼容的问题,如下即为所描述的问题及列举的对应的解决办法:

1、在RadASM环境下连接VC6.0生成的.obj时,找不到_main符号的问题及解决办法。

2、VC6.0对GetEnvironmentStrings这个函数的ASCII版本和UNICODE版本的宏替换与masm32的不一致的问题及解决办法。


一、Bug的触发:

创建VC6.0工程,声明和定义ShowHello()函数,然后编译生成.obj目标文件:



创建RadASM控制台工程。由于VC6.0编译好的代码都会被生成在.obj里面,所以就能在RadASM工程直接调用.obj里面的函数。将编译好的StdAfx.obj扔到RadASM工程文件夹下,并添加到RadASM工程里面。然后就可以调用了,以下就是调用ShowHell()这个函数。

编译可通过,但是连接的时候报了两个错误:


二、错误一:

提示缺少_main符号,为什么会缺少_main符号?是因为在VC6.0生成的.obj会把LIBCD.LIB一块连接进去(LIBCD.LIB在VC6.0安装目录的VC98下的LIB文件夹里面)。在 LIBCD.LIB中有一个crt0.obj,这个crt0.obj就是VC6的入口代码,我们用IDA打开LIBCD.LIB查看:

双击这个crt0.obj进去后发现,就会看到的即是VC6.0的入口代码:

入口代码做完一些初始化工作后,就调用了main函数

由于连接了LIBCD.LIB,而LIBCD.LIB又有入口函数被连接,而拷贝到RadASM工程下的StdAfx.obj并没有入口函数的定义,于是就报错第一个错误:缺少_main符号。


解决办法一:将RadASM的程序入口改为main:

再连接,第一个错误解决了!


解决办法二:直接定一个的空函数,使RadASM连接时能检测到_main符号:

这个方法同样可以解决第一个错误!


三、错误二:

缺少一个函数定义:__imp__GetEnvironmentStrings

       首先,在VC6.0下我们看看GetEnvironmentStrings这个函数在何时被调用。通过栈回溯定位到VC的mainCRTStartup,然后往下就会看到:是mainCRTStartup调用了这个函数:

关键点:在RadASM连接时会报错,是由于识别不出.obj下的这个函数,即masm32对这个声明的与VC6.0声明的不一致。


问题的体现:

1、我们先看masm32对ASCII与UNICODE版本的实现。打开masm32的include目录,找到kernel32.inc

打开并定位到GetEnvironmentStrings这个函数:

masm32调用该函数时如果是ASCII版,则用GetEnvironmentStringsA宏替换,如果是UNICODE版,则用GetEnvironmentStringsW宏替换。


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

上传的附件:
收藏
免费 1
支持
分享
最新回复 (17)
雪    币: 4942
活跃值: (4663)
能力值: ( LV10,RANK:171 )
在线值:
发帖
回帖
粉丝
2
学习了,谢谢分享
2018-2-9 21:41
0
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2018-2-9 23:10
0
雪    币: 6976
活跃值: (1482)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
4
这个解决思路不太对吧,  套路不是应该VC这边编译不要带默认库吗?
2018-2-11 08:50
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5

最后于 2018-2-14 18:03 被小钟编辑 ,原因:
2018-2-11 12:39
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
JoenChen 这个解决思路不太对吧, 套路不是应该VC这边编译不要带默认库吗?
问题的本质,是VC的库与masm32库对这个API声明不一致导致,所以可通过修改两者其一库声明来解决问题,解决办法多种,楼主所说VC编译这边也是可行的
2018-2-11 13:47
0
雪    币: 88
活跃值: (431)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
目前自己倒是在看fasm
2018-2-13 00:56
0
雪    币: 77
活跃值: (72)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
写的很好,但有个问题不解,crt0.c中的main是三个参数的
#ifdef  WPRFLAG
                        __winitenv  =  _wenviron;
                        mainret  =  wmain(__argc,  __wargv,  _wenviron);
#else    /*  WPRFLAG  */
                        __initenv  =  _environ;
                        mainret  =  main(__argc,  __argv,  _environ);
#endif    /*  WPRFLAG  */
但标准的是以下两个
int  main(void)
int  main(int  argc,  char  *agrv[])
链接的时候如何对应,看了看ctr0.c中的内容,有
int  __cdecl  main(int,  char  **,  char  **);                          /*generated  by  compiler*/
是这个编译器产生的三个参数是main调用了我们提供的符合标准的main吗?
如果是的话,链接符号_main有两个,不会因重复导致冲突吗?
求解答
2018-2-13 10:50
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9

最后于 2018-2-14 18:01 被小钟编辑 ,原因:
2018-2-14 17:46
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10

最后于 2018-2-14 18:01 被小钟编辑 ,原因:
2018-2-14 17:48
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
JerryOne 写的很好,但有个问题不解,crt0.c中的main是三个参数的 #ifdef WPRFLAG __winitenv = _wenviron; ma ...
本文所提供方案不是嵌套一层main调用吧,汇编调用VC提供的obj,汇编这边没声明main符号所以link时识别不出,手动加进去可解决此问题,三个参数的main是标准  不带参数main同样可行
2018-2-14 18:21
0
雪    币: 77
活跃值: (72)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
小钟 本文所提供方案不是嵌套一层main调用吧,汇编调用VC提供的obj,汇编这边没声明main符号所以link时识别不出,手动加进去可解决此问题,三个参数的main是标准 不带参数main同样可行
to    小钟
我的疑惑不是_main符号link时识别问题
我的问题是crt0.obj中已经包含_main强符号(三个参数的main函数),我们提供的(无参数或两个参数)main函数也将产生_main强符号,这不会产生冲突吗
另外,看crt0.c代码,mainCRTStartup调用的是由编译器自动生成的带三个参数的main函数,而我们提供的(无参数或两个参数)main函数是由谁调用的呢
2018-2-16 21:28
0
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
JerryOne to 小钟 我的疑惑不是_main符号link时识别问题 我的问题是crt0.obj中已经包含_main强符号(三个参数的main函数),我们提供的(无参数或两个参数)main函数也将产生_ma ...
你搞错了c语言符号和c++符号  main是c语言符号  导出后在就是_main  链接器没法判断有几个参数的,  可变参数函数的原理就在如此
2018-2-19 17:33
0
雪    币: 1233
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不错,谢谢分享啦
2018-2-23 21:05
0
雪    币: 714
活跃值: (82)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
15
之前还碰到过VS中无法在汇编代码中调用c写的函数和C库函数,不知楼主遇见过吗?
2018-2-25 17:32
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
也许是你环境没配好吧
2018-2-28 19:30
0
雪    币: 32
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
也许是你环境没配好吧
2018-2-28 19:31
0
雪    币: 714
活跃值: (82)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
18
小钟 也许是你环境没配好吧
环境我配过,现在可以在VS中调用Irvine32和C代码中调用汇编函数以及纯汇编代码,但是我说的“在汇编代码中调用c写的函数和C库函数”这个问题我没解决,还请指教
2018-3-6 12:28
0
游客
登录 | 注册 方可回帖
返回
//