【混合编程】VB6与VC++的合体编程(不使用DLL)
转载请注明出处:http://www.0xaa55.com/thread-445-1-1.html我觉得这应该是史无前例的。我是先驱者。。膜拜我吧
首先我来说一下原理:
VB6的IDE会把VB的工程编译成OBJ,然后用LINK完成链接。那么最后VB生成的OBJ去哪了呢?其实是被VB的IDE自动删除了。我们要做的就是截取VB还没完成链接的时候VB的IDE产生的OBJ文件,然后把它们和VC++产生的OBJ一起链接,以此来实现合体编程。这个的好处就是VB写界面方便而VC++能做到许多VB做不到的事,两者取长补短,互利共生。
首先打开VB6的IDE的文件夹。可以看到VB的LINK.EXE。VB就是用它完成链接的。
这个时候果断自己写一个LINK.EXE换掉这个原先的LINK.EXE!不过先备份旧的LINK.EXE,很简单,直接改名为LINK1.EXE就行了。
然后把自己写的LINK.EXE放进来。自己写的LINK.EXE有个特点,就是,它会卡住!这样我们就能趁它卡住的时候,找到工程文件里面的OBJ文件然后把它复制出来了。
那么我这里提供了一份我自己写的“假LINK.EXE”。压缩包里面有四个文件,两个批命令和两个EXE,这两个EXE一个是真LINK.EXE的备份,一个是假LINK.EXE的备份,双击GENEXE.BAT后就会自动把链接器换成真LINK.EXE,双击GENOBJ.BAT则会自动链接器换成假LINK.EXE。
下载地址:
下载后解压到你的VB的IDE的文件夹里面即可。
好,接下来准备编译得到OBJ。我准备了这么一个工程,它只有一个窗体和一个模块,我们要做的就是把这个模块换成VC++的OBJ,实现合体。
上图这个工程我会在后面提供下载。
我们要用VC++实现这个模块提供的函数!
那么先开始编译吧。
首先双击GENOBJ.BAT,换上假的链接器。
然后打开工程,文件->生成XXX.exe
只见它一卡,然后我们的假LINK就出来了。如下图所示:
没错!就是这样!我们现在就打开记事本把刚才的链接命令记下来。
看见了吧?这个是OBJ!我们看到了OBJ!
别急。创建OBJ文件夹。把得到的OBJ都丢进去。
好的,VB的IDE已经可以不鸟它了,接下来我们需要用VC++写一个代替modCOrCPP.obj的程序。
准备好了吗?
好,我们打开VC++,建立一个新的控制台程序。
讨厌预编译头,所以把它弄掉。
然后我们新建一个modCOrCPP.cpp,如下。
接下来就是写代码的部分了。这可是重点!
首先说一下就是VB的OBJ是个什么规律。
大家可以看到modCOrCPP只有四个函数:Sub VCPPSub()
End Sub
Function VCPPFunction() As Long
End Function
Sub VCPPSubWithParam(ByVal A As Long, ByVal B As Long)
End Sub
Function VCPPFuncWidthParam(ByVal A As Long, ByVal B As Long) As Long
End Function我们只要能用VC++实现这4个函数就行了。
我们用WinHex打开VB生成的modCOrCPP.obj,看最底部:
可以看出这个OBJ导出了四个符号:
?VCPPSub@modCOrCPP@@AAGXXZ
?VCPPFunction@modCOrCPP@@AAGXXZ
?VCPPSubWithParam@modCOrCPP@@AAGXXZ
?VCPPFuncWidthParam@modCOrCPP@@AAGXXZ
根据符号修饰我们会发现VB导出的这四个函数的原型其实用VC++是像下面这样的:class modCOrCPP
{
private:
void _stdcall VCPPSub(void);
void _stdcall VCPPFunction(void);
void _stdcall VCPPSubWithParam(void);
void _stdcall VCPPFuncWidthParam(void);
};没错,无论你怎么声明,它的原型都是【void _stdcall 类名::私有函数(void);】这种规律的,产生的符号也都是【?函数名@类名@@AAGXXZ】这样的。(我这里解释一下,结尾的“AAGXXZ”的意思是这个函数没有返回值,也没有参数列表,是一个类的私有成员函数,而且是_stdcall风格的)
这样我们怎样获取参数信息呢?只能通过裸函数了。
比如有个VB的函数,它的定义是Function foo() as Long那么它产生的符号翻译成VC++的函数原型就成了void _stdcall 类名::foo(void);
这个时候我们需要做的就是重新写一个函数,然后让这个类的导出函数跳转到这个函数,如下:static long bar(void)
{
return 233;//设置返回值
}
_declspec(naked)void 类名::foo()
{
_asm jmp bar;//直接跳走
}这样就行了。OBJ就能产生同样的符号了。
在VC6的界面下编译modCOrCPP.cpp->modCOrCPP.obj,然后我们在Debug、Release文件夹里面找到这个文件:modCOrCPP.obj,复制到VB的那堆OBJ里面,覆盖掉原先的OBJ文件,嗯,还记得之前打开过的记事本吧?
在这一整行链接器命令的前面加上一个“LINK ”,再把所有要链接的OBJ文件的文件路径去掉只保留文件名,在这整行命令的结尾按下回车,打个“@pause”,然后保存到你的OBJ文件夹,存为“BUILD.BAT文件”
还没完呢,接下来大家需要找到原先的VB的LINK.EXE和它所依赖的MSPDB60.DLL,把它们一起放到你的OBJ文件夹里面。
接下来双击BUILD.BAT,发现好像缺少了一些LIB。这个时候果断去VC++的Lib文件夹里面找到需要的LIB放到工程文件夹。
经过我的研究发现你需要把KERNEL32.LIB、USER32.LIB、LIBC.LIB、UUID.LIB、OLDNAMES.LIB这几个VC++的默认库全部放到你的OBJ文件夹。然后修改BUILD.BAT,在它的最前面LINK的后面加个空格,加上“KERNEL32.LIB USER32.LIB ”然后再次双击BUILD.BAT就会发现链接成功了。
打开EXE,点击上面的四个按钮,它们都正常运行啦~~赞一个
最后给出各种下载地址。
全部工程下载:**** Hidden Message ***** 以后就可以吧vb程序变成vc的了
看到了C 艹 :funk: 这样合体后的VC程序,是不是还是需要VB的运行库? 0x0208 发表于 2014-4-19 05:08
这样合体后的VC程序,是不是还是需要VB的运行库?
对。是不是觉得略操蛋了点儿 0xAA55 发表于 2014-4-19 18:36
对。是不是觉得略操蛋了点儿
忙活半天,它不还是VB。 0x0208 发表于 2014-4-20 02:38
忙活半天,它不还是VB。
你要这么说也行,但是你也可以说它是C、C艹 这个实在是有意思~~ 原来就是中断link啊。。。那能不能自己通过批处理或命令行直接调用c2来编译vb的代码呢? tangptr@126.com 发表于 2017-3-29 18:01
原来就是中断link啊。。。那能不能自己通过批处理或命令行直接调用c2来编译vb的代码呢? ...
那是中断c2,你要做啥? 0xAA55 发表于 2017-3-29 19:27
那是中断c2,你要做啥?
C2难道不是把vb代码编译到obj的玩意么。。。 谢谢分享 这个看不懂,但是觉得很高级
MARK,有时间研究研究 厉害:):):):):) 学习了,谢谢分享。 这个感觉听着有可行性,目前正适合我的需要 这个可以增加我装逼的词库量 膜拜,学习一下 下个文件就走:lol
页:
[1]
2