用汇编代码调用没有参数信息的dll库函数! | 您所在的位置:网站首页 › c调用dll库函数 › 用汇编代码调用没有参数信息的dll库函数! |
![]() 1. 背景资料 通常开发者获取到的通用dll函数库都会有说明文件,里面对dll库中公开的函数都会有api接口说明,比如函数的名称,返回值,参数类型以及参数的数量. 但是有时开发者也会找到一些dll库函数,这些库函数只能获取到函数名称,而没有关于函数的参数信息. 这种dll一般是来自第三方的,或是偷来的(我的项目中就是属于此类,我知道这个dll函数的功能很不错,我就是想将它嵌入到我的程序中.)). 对于前者,具有资料完备API编程信息,我们可以在c++,vb或.NET平台中轻松编写调用接口来执行dll中的函数,而后者由于没有参数信息,想调用就不那么简单了. 通常系统自带的dll函数库都会有api说明,或者也可以通过某些工具来获取dll库中的函数描述信息. 可是一些第三方的dll函数可能不会将函数信息写到dll中,这样我们就不能够获取参数信息了,也就无法调用了,真的没办法吗?
2. 解决办法 即然没有参数信息就没有办法声明函数的调用接口,不过没关系. 我想到一种简单的方式:用汇编语言来直接调用. 首先要有完整的第三方程序,先看看第三方程序在汇编语言层面上是如何调用函数的(通过反汇编). 通过调试软件(如:windbg,od,softace等)将第三方的程序运行起来,然后在我们需要的那个dll模块函数上加断点,分析它的汇编码. 其实很简单的,如果函数需要参数,那就看看它是通过栈的方式传的参数还是通过寄存器来传的参数. 一般汇编语言中参数都是传的参数地址,而不是值.另外传递参数的规则也要弄清. 如果传参方式是栈方式传参数,还要区分是调用者清除栈还是被调用者清除栈. 比如下面代码是调用md5加密,我就是用栈方式传递两个指针参数给函数. mov eax,dword ptr [cb] //传入待加密字符串地址 push eax //参数2 入栈 mov eax,dword ptr [result] //反回值字符串地址 push eax //参数1 入栈 call pFun //执行函数 结果result里就是我们加密后的结果了. 上面代码使用的是调用者清除栈方式,而清除栈方式是被调用者清除栈(通过反汇编可以发现指定函数里是使用哪种清栈方式.): 如果需要我们清除栈,那就在上面代码的最后写 add esp,8 代表释放两个指针参数的空间8个字节. 关于函数清栈方式参见我的另一篇随笔:函数的可变数目参数 与 栈
3. 如何加载dll与函数地址 我使用win32 api 来加载dll库与函数地址,使用方式: HINSTANCE dll = LoadLibrary(L"d:\\*******.dll"); FARPROC pFun = GetProcAddress(dll,"要调用的函数名称"); _asm { mov eax,dword ptr [cb] push eax mov eax,dword ptr [result] push eax call pFun } 4. 注意事项 需要特别注意的是,对于(传入的/返回的)参数指针指向的数据区域大小需要多次试验,因为有时从汇编中很难发现局部变量的长度,所以尽量将我们声明的变量地址空间多一些. 还有就是dll函数的清栈方式,要仔细观察反汇编的结果,看看它用的是哪种调用方式,这样才能保障栈平横,不至于缓冲区溢出. |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |