[Windows编程] 使用API函数GetProcAddress的注意事项

关于GetProcAddress返回错误代码为127的解决方案 关于GetProcAddress返回错误代码为127的解决方案 关于GetProcAddress返回错误代码为127的解决方案 运行期间显示地去加载DLL库,当LoadLibrary可以返回当前DLL模块的句柄时,而GetProcAddress取得函数的地址为空时。通过GetLastError去获取错误代码为127,很有可能是动态链接库工程里面函数声明的没有加extern “C”。 解决方案 只针对自己写的dll项目提供解决方案, 如果是拿的第三方的动态链接库出这样的问题,不在此解决方案中。 通常写dll工 阅读详情

Windows API 函数 GetProcAddress 被广泛用于取得函数指针地址。 例如:

 

typedef BOOL (WINAPI *pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);

 

pGPI = (pfnGetProductInfo) GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProductInfo");

 

注意函数定义typedef 中的WINAPI, 它指定了函数的调用协议, 这部分是非常必要而且关键的,写代码的时候需要注意。

 

比如你要想取得标准C++运行库(msvcrt.dll) 中的strcpy函数,函数定义就应该是:

typedef char * (__cdecl *pfnStrRChr)(const char *string, int c);


pSRS = (pfnStrRChR)GetProcAddress(hMSVCRT, "strrchr");

 

函数调用协议指定了函数参数的传递方式以及栈管理方式。如果你这里不指定调用协议,编译器会用默认的调用协议。 结果可能和DLL 函数原先指定协议的不同,函数被调用时会直接导致程序崩溃

 

比较主流的函数调用方式有 _cdecl , _stdcall, _fastcall, _thiscall

_cdecl 是C语言默认的函数调用协议:所有参数从右到左依次入栈,栈中的参数由调用者清除。

_stdcall 是Pascal 语言的默认的函数调用协议,所有参数从右到左依次入栈,栈中的参数由被调用的函数在返回后清除。 Windows API 全部采用 _stdcall 方式, 上面例子中的WINAPI 其实就是 ___stdcall

#define WINAPI __stdcall
__fastcall 是前两个(x86机器)或者4个(x64机器)参数由寄存器传递,其余参数还是通过堆栈传递。 栈中的参数由被调用的函数在返回后清除。Borland Delphi, C++ Builder 默认使用这种调用方式。

_thiscall 和_stdcall 类似, 只是_thiscall 把类的this指针放在某个特定的寄存器中,比如Visual C++放在ECX中, Borland C++放在EAX中。

 

经比较,几种调用协议存在挺大差异,所以GetProcAddress 得到的函数需要指定正确的调用协议。

 

--

使用汇编代码获取GetProcAddress函数地址的大致步骤(面试题系列) 1、首先通过FS寄存器获取到TEB的地址 2、在TEB偏移为0x30处的成员是PEB 3、PEB偏移为0xC处的成员是PEB_LDR_DATA结构体指针 4、PEB_LDR_DATA结构体偏移为0x1C处成员为InInitializationOrderModuleList,初始化模块链表,这个成员保存的是模块链表的头部地址。 5、通过InInitializationOrderModuleL 阅读详情

相关推荐

《C++避坑神器·十五》动态库只有dll文件,没有.lib文件时动态调用dll的中类和成员函数

换句话说,如果应用程序决定要调用 DLL 中的函数,则可以将 DLL 显式加载到进程的地址空间中,获取 DLL 中包含的函数的虚拟内存地址,然后使用此内存地址调用函数。该列表包含成员函数Add、Sub和构造函数calculate的虚拟内存地址,1,3,5后面一串乱码实际是构造函数,Add,Sub对应的函数名称,现在我们要用def文件来修正它。我们在自己的项目中新建一个“calculate.def”文件,并在“工程->设置->Link”中添加参数(/def:“.\calculate.def”),并编。

cs1395293598的博客 4003

[转载]使用API函数GetProcAddress注意事项

Windows API 函数 GetProcAddress 被广泛用于取得函数指针地址。 例如: typedef BOOL (WINAPI*pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); pGPI = (pfnGetProductInfo) GetProcAddress(GetModuleHandleW(L...

angbagangzhe065140的博客 115

使用API函数GetProcAddress注意事项

转自:点击打开链接 Windows API 函数 GetProcAddress 被广泛用于取得函数指针地址。 例如:   typedef BOOL (WINAPI *pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);   pGPI = (pfnGetProductInfo) GetProcAddress(Ge

ProgrammingRing的专栏 2262

动态载入DLL所需要的三个函数详解(LOADLIBRARY,GETPROCADDRESS,FREELIBRARY)

(仅供参考) 动态载入DLL所需要的三个函数详解(LOADLIBRARY,GETPROCADDRESS,FREELIBRARY) 动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 GetProcAddress函数动态获得 DLL 函数的入...

Charles_ke的博客 2011

动态windows api函数加载

免杀中如何隐藏 危险函数 过静态杀软

qq_60870726的博客 974

详细介绍GetProcAddress()

作用从指定的 DLL 模块中检索导出函数的地址,支持通过函数名或序号访问。该函数是动态链接的核心实现,广泛应用于插件系统、内存注入、免杀技术等领域。函数原型​参数hModule:DLL 模块的句柄,可通过或获取。lpProcName:函数名(LPCWSTR)或序号(低 16 位为序号,高 16 位为 0)。返回值成功时返回函数地址FARPROC类型)。失败时返回NULL,可通过 GetLastError获取错误代码(如126表示模块未找到)。

felicity_one的博客 1578

关于Windows API函数的简单编程

关于Windows API函数的简单编程

T2hunz1 1309

Windows API学习】GetProcAddress学习

显式链接到 DLL 的进程调用 GetProcAddress 来获取 DLL 导出函数的地址。 使用返回的函数指针调用 DLL 函数。 GetProcAddress 将(由 LoadLibrary、AfxLoadLibrary 或GetModuleHandle 返回的)DLL 模块句柄和要调用的函数名或函数的导出序号用作参数。 由于是通过指针调用 DLL 函数并且没有编译时类

dongyue786的专栏 852

maldev OPSEC 隐患剖析:为什么 GetProcAddress 会成为安全产品的关注焦点?

在 malware development(恶意软件开发,业内常简称 maldev)的学习与研究中,几乎每一个进程注入类样本都绕不开一个函数——GetProcAddress。它本身是完全合法的 Windows 动态 API 解析接口,却在安全产品的告警日志里"出镜率"极高。开源项目「GitHub 加速计划 / ma / maldev」收录了 DLL 注入、NTAPI 注入、直接/间接系统调用、线程

gitblog_00887的博客 826

根据函数名载入库函数GetProcAddress、dlsym)

根据函数名载入库函数GetProcAddress、dlsym)不废话上代码:#ifdef WIN32 #include <windows.h>typedef HINSTANCE HandleType; #define LoadLib(filename) LoadLibraryA(filename) #define UnLoadLib(handle) FreeLibrary(handle) #def

道法自然 4114
上一篇: [Windows编程] 监视DLL装载/卸载
下一篇: [Windows编程] SHLWAPI 和 CRT (C Runtime) 字符串处理函数的区别
西塞安全
博客等级 码龄20年 980粉丝 164原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值