返回列表 回复 发帖

VB动态调用外部函数的新思路.无汇编,纯代码实现

VB动态调用外部函数的新思路.无汇编,纯代码实现

好了,是该写点技术性得到东西了..免得被FlowerCode和炉子误会成……

这个是研究了2个小时的成果,当然,想法是前一天晚上躺在床上的时候想到的。
起因是看到了此版面上的另一篇帖子“ VB动态调用外部函数的方法” http://www.vbgood.com/viewthread.php?tid=68852&extra=page%3D1
接着联想到了以前看到的帖子《VB真是想不到系列之三:VB指针葵花宝典之函数指针》。最后,突发奇想。。。于是有了这个可以说是目前最简单的vb动态调用api的方法。你甚至不需要知道任何汇编知识。

另外特别申明1下,如果以前已经有人发过类似的东西,纯属巧合……因为这个想法太简单了,我觉得以前应该有人想出来过

废话结束,讲一下用到的api:

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
用来得到目标api的函数地址

Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
                                                     ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
用来打开和关闭进程句柄

Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, _
用来写内存,当然也可以用CopyMemory,但个人更喜欢用这个

CallWindowProc呢?抱歉,没有用到。。。就这6个api

程序的核心只有8行代码,可调用绝大多数api。
我只测试了Beep,MessageBoxA,ReadProcessMemory这三个函数,其中,ReadProcessMemory是把结果返回在参数里的,也调用成功。
又因为我没有测试所有的api,所以说这个方法可以调用绝大多数api,但我不保证可以调用所有的。

这个方法的好处是,你可以放一个textbox,运行的时候在里面输入函数库,函数名,以及他的参数,实现真正意义上的动态调用api
也不增加额外开销,代码的时间开销是O(1),在常数时间内执行,所以没有效率问题。

这里先发个测试程序,留个悬念,晚上发思路、原理&源代码。不过我想你看了测试程序应该就已经明白了道理了~

[ 本帖最后由 reker 于 2008-5-7 12:05 编辑 ]
附件: 您所在的用户组无法下载或查看附件
2

评分次数

200字节。。。额。。
发帖只发精品,回帖只回废话。
MyBlog
IMTab.cn
http://www.freevbcode.com/code/APIByName.zip
一般来说都是这么实现的,汇编知识用的也不多,就是把那几个多余参数 pop 掉,自己要调用的函数地址压栈,然后就可以 Call 了。
原帖由 FlowerCode 于 2008-5-7 11:59 发表
http://www.freevbcode.com/code/APIByName.zip
一般来说都是这么实现的,汇编知识用的也不多,就是把那几个多余参数 pop 掉,自己要调用的函数地址压栈,然后就可以 Call 了。
我的没那么复杂,一个很白痴的方法,只是没有人想到而已....可以说几乎不需要懂汇编知识
我实现起来没有用到pop,push之类的东西,晚上发源代码,看到了说不定你会笑起来。。。
200字节。。。额。。
发帖只发精品,回帖只回废话。
MyBlog
IMTab.cn
  1. Private Declare Function EbExecuteLine Lib "vba6.dll" _
  2.         (ByVal pStringToExec As Long, ByVal Unknown1 As Long, _
  3.         ByVal Unknown2 As Long, ByVal fCheckOnly As Long) As Long
复制代码
这方法在没 VB6 IDE 的电脑上不能用的。很早以前玩过。
原帖由 FlowerCode 于 2008-5-7 12:06 发表
Private Declare Function EbExecuteLine Lib "vba6.dll" _
        (ByVal pStringToExec As Long, ByVal Unknown1 As Long, _
        ByVal Unknown2 As Long, ByVal fCheckOnly As Long) As Lo ...
我不用这个实现
之所以用这个,是让你可以在textbox里面输入一个函数,然后利用EbExecuteLine 进行真正的动态执行,但是EbExecuteLine 在我电脑上编译以后就会导致程序崩溃,不知道什么原因,ide里面正常。

不用EbExecuteLine 的话,就要把代码写死在程序里面了,就像vc的函数指针那样,要预先写好参数个数和类型
200字节。。。额。。
发帖只发精品,回帖只回废话。
MyBlog
IMTab.cn

回复 #5 reker 的帖子

哦... jmp 啊...
原帖由 icesboy 于 2008-5-7 21:35 发表
哦... jmp 啊...
bingo~答对了,就改动5个字节,完了...
不存在参数问题,可以支持任意多个参数,支持返回值.
200字节。。。额。。
发帖只发精品,回帖只回废话。
MyBlog
IMTab.cn
顶一下,不错
用CallByName简单到点了,同志们。我做的一个系统就是,将功能名称写道数据库的表中,慢慢的调用,还可以动态增加功能按钮和菜单,只需要改变数据中参数设定就OK了。
我曾经下载一个DLL,用这个DLL可以在VBS里调用API
返回列表