欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何获得当前运行模块在进程地址空间的位置

程序员文章站 2022-03-13 23:45:04
...

 


(w)WinMain的hInstanceExe参数实际值是一个内存基地址;系统将可执行文件的映像加载到进程地址空间中的这个位置。例如,系统打开可执行文件,并将它加载到地址0x00400000,则(w)WinMain的hInstanceExe参数值为0x00400000.

 

为了知道一个可执行文件或DLL文件被加载到进程地址空间的什么位置,可以使用GetModuleHandle函数来返回一个句柄/基地址

 

HMODULE GetModuleHandle(PCTSTR pszModule)


调用这个函数是,要传递一个以0为终止字符的字符串,它指定了已在主调进程的地址空间中加载的一个可执行文件或DLL文件的名称。如果系统找到了可执行文件或DLL文件名称,GetModuleHandle就会返回可执行文件/DLL文件映像加载到基地址。如果没有找到文件,系统将返回NULL。

GetModuleHandle的另一个用法是为pszModule参数传入NULL,这样就可以返回主调进程模块的基地址。如果我们的代码在一个DLL中,那么可利用两种方法来了解代码正在什么模块中运行。第一个办法是利用链接器提供的伪变量__ImageBase,它指向当前正在运行的模块的基地址。这是C语言运行库启动代码在调用我们的(w)WinMain函数时所做的事情

第二种方法是调用GetMoudleHandleEx,将GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS作为它的第一个参数,将当前函数的地址作为第二个参数。最后一个参数是一个指向HMODULE的指针,GetModuleHandleEx会用传入函数(即第二个参数)所在DLL的基地址来填写该指针。以下代码对这几种方法进行演示。

extern "C" const IMAGE_DOS_HEADER __ImageBase;
 
void DumpModule()
{
	HMODULE hMoudle = GetModuleHandle(NULL);
	_tprintf(TEXT("with GetModuleHandle(NULL) = 0x%x\r\n"),hMoudle);
 
	_tprintf(TEXT("with _ImageBase = 0x%x\r\n"),(HINSTANCE)&__ImageBase);
 
	hMoudle = NULL;
	GetModuleHandleEx(
		GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
		(PCTSTR)DumpModule,
		&hMoudle);
	_tprintf(TEXT("with GetModuleHandleEx = 0x%x\r\n"),hMoudle);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
	DumpModule();
	return 0;
}
 


如何获得当前运行模块在进程地址空间的位置