库中调用GetModuleHandle(NULL)返回的是进程的实例句柄,而非本dll的

获取进程基地址时GetModuleHandle只返回进程的,如果想获取当前库的需使用GetModuleHandleEx

今天本想获取加载的dll的基地址,调用GetModuleHandle()时总是得不到正确的结果,细看了下<<windows核心编程>>,里面说如果在DLL中执行GetModuleHandle (NULL),返回的是可执行文件基地址。获取DLL自身基地址需用GetModuleHandleEx (…);实测了下,果然…

注意:exe项目和dll项目均为Unicode字符集,和wprintf相关
dll项目代码
头文件声明

API_DECLSPEC void printLibraryModule();

源文件函数实体

void API_DECLSPEC printLibraryModule()
{
    HMODULE hModEx = NULL;
    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCTSTR)printLibraryModule, &hModEx); //获一个函数地址

    wprintf(TEXT("Library With GetModuleHandleEx =0x%x\r\n"), hModEx);
    FreeLibrary(hModEx);

    HMODULE hMod = GetModuleHandle(NULL);
    if (!hMod)
    {
        DWORD dw = GetLastError();
    }
    else
        wprintf(TEXT("With GetModuleHandle(NULL)=0x%x\r\n"), hMod);
    FreeLibrary(hMod);
}

然后建个控制台程序,部分借用网友代码

#include "../printModule/printLibraryModule.h"

void printModule()
{
    HMODULE hMod = NULL;
    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCTSTR)printModule, &hMod); //获一个函数地址

    wprintf(TEXT("With GetModuleHandleEx =0x%x\r\n"), hMod);
    FreeLibrary(hMod);
}

int main(int argc, char* argv[])
{
    HMODULE hMod = GetModuleHandle(NULL);
    if (!hMod)
    {
        DWORD dw = GetLastError();
    }
    else
    wprintf(TEXT("With GetModuleHandle(NULL)=0x%x\r\n"), hMod);
    FreeLibrary(hMod);
    
    printModule();
    printLibraryModule();
    return 0;
}

然后得出的结果:
在这里插入图片描述
所以调用GetModuleHandle还是GetModuleHandleEx自已心里要清楚,特别是dll注入等场合。
另外,网友还整理了几条相关规律:
1、HMODULE 和 HINSTANCE 只有在16运行环境上才有区别,其它环境相同,均为线程基地址。遇到了直接转换
2、GetModuleHandle (NULL) 多次调用引用次数不增加,无论调多少次一次FreeLibrary()就行。
3、GetModuleHandleEx(dwFlags, lpModuleName, phModule)
dwFlags:
如果是0,则当调用该函数时,模块的引用计数自动增加,调用者在使用完模块句柄后,必须调用一次FreeLibrary
如果是GET_MODULE_HANDLE_EX_FLAG_PIN,则模块一直映射在调用该函数的进程中,直到该进程结束,不管调用多少次FreeLibrary
如果是GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,则同GetModuleHandle相同,不增加引用计数
如果是GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,则lpModuleName是模块中的一个地址

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值