调用GetModuleHandle可以得到当前进程(exe)的模块加载到内存的基地址,但在DLL调用这个函数依然得到是exe的基地址,因此需要编程实现获取当前调用源地模块基地址。
/*函数:GetCurrentModule
功能:获取模块自身的基地址,如果在DLL内使用,就是那个dll的模块基地址,如果在exe内调用,
则是这个exe的基地址(实际上可以说GetModuleHandle(NULL)),在DLL内无法准确获取DLL
实例句柄(模块基地址),例如入口函数不是在DLLMAIN。
返回值:模块基地址,HMODULE,其实是个DWORD的地址值
*/
HMODULE __stdcall GetCurrentModule(VOID);
/*函数:GetCurrentModule
功能:获取模块自身的基地址,如果在DLL内使用,就是那个dll的模块基地址,如果在exe内调用,
则是这个exe的基地址(实际上可以说GetModuleHandle(NULL))
返回值:模块基地址,HMODULE,其实是个DWORD的地址值
*/
HMODULE __stdcall GetCurrentModule(VOID){
/*没有使用宏判断windows的版本*/
MEMORY_BASIC_INFORMATION membinfo;
static int ibase=0;//这里要是静态变量,否则失败
VirtualQuery(&ibase,&membinfo,sizeof(membinfo));
return (HMODULE)(DWORD)membinfo.AllocationBase; //可转换为IMAGE_DOS_HEADER(内存中的),本来就是
}
注意:上面的ibase需要声明为static,否则调用VirtualQuery会出错。因为VirtualQuery 无法计算局部栈地址,声明为static 使得变量的地址为当前模块的全局变量,也就是说ibase的地址在dll内是可见的(在整个进程内同样也是)。 然后通过MEMORY_BASIC_INFORMATION::AllocationBase得到模块加载的基地址,也就是模块句柄-HMODULE