windows核心编程-DLL是否被装入在合适的地址空间

本文介绍了一个检查DLL文件是否被加载到其首选基地址的方法。通过使用Windows API函数和内存读取技术,验证了DLL文件在进程地址空间中的实际加载位置是否符合其自身定义的最佳加载位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

windows里面所有的exe程序,dll程序,lib程序,sys....都遵循PE结构

即数据和指令按照一定顺序存放在文件中,这种格式叫做PE格式


1、DLL文件装入进程地址空间后,是否是装入到dll文件规定的最合适的地址

#include<windows.h>
#include<tchar.h>
#include<TlHelp32.h>

#define ID 2520

//这段代码直接在MSDN中拷贝的
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

LPFN_ISWOW64PROCESS fnIsWow64Process;

BOOL IsWow64(HANDLE hProcess) //稍微修改了下,判断是不是64位的程序
{
	BOOL bIsWow64 = FALSE;

	//IsWow64Process is not available on all supported versions of Windows.
	//Use GetModuleHandle to get a handle to the DLL that contains the function
	//and GetProcAddress to get a pointer to the function if available.

	fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
		GetModuleHandle(TEXT("kernel32")), "IsWow64Process");

	if (NULL != fnIsWow64Process)
	{
		if (!fnIsWow64Process(hProcess, &bIsWow64))
		{
			//handle error
		}
	}
	return bIsWow64;
}

//判断是否装入在合适的位置
PVOID GetModulePreferredBaseAddr(DWORD dwProcessId, PVOID pvModuleRemote) {

	PVOID pvModulePreferredBaseAddr = NULL;
	IMAGE_DOS_HEADER idh;
	IMAGE_NT_HEADERS inth;

	// Read the remote module's DOS header
	Toolhelp32ReadProcessMemory(dwProcessId,
		pvModuleRemote, &idh, sizeof(idh), NULL); //pvModuleRemote起始地址

	// Verify the DOS image header
	if (idh.e_magic == IMAGE_DOS_SIGNATURE) {
		// Read the remote module's NT header
		Toolhelp32ReadProcessMemory(dwProcessId,
			(PBYTE)pvModuleRemote + idh.e_lfanew, &inth, sizeof(inth), NULL); //e_lfanew偏移量

		// Verify the NT image header
		if (inth.Signature == IMAGE_NT_SIGNATURE) {
			// This is valid NT header, get the image's preferred base address
			pvModulePreferredBaseAddr = (PVOID)inth.OptionalHeader.ImageBase;
		}
	}
	return(pvModulePreferredBaseAddr); //返回进程最合适的地址
}

int _tmain()
{
	DWORD nFlags = 0;

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,ID);
//	BOOL Is32 = IsWow64(hProcess);   //判断是否位32 位的程序

	//	_tprintf(L"Is 32 Process!\n");
		nFlags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32;
	
	HANDLE hSnapshot = CreateToolhelp32Snapshot(nFlags, ID);

	MODULEENTRY32 me = {0};
	me.dwSize = sizeof(me);
	Module32First(hSnapshot,&me);
	do{
		
		PVOID pPre = GetModulePreferredBaseAddr(
			ID,me.modBaseAddr);
		//me.modBaseAddr:是现在这个模块或者说dll在进程地址空间中的地址
		//pPre获得的是,dll模块装入进程空间的最佳地址

		if (pPre!=me.modBaseAddr) //如果没有装入合适的位置,输出
			_tprintf(L"hModule=%0x,BaseAddr=%0x,ModSize=%0x,pPre=%0x,\n%s\n", me.hModule, me.modBaseAddr,
						me.modBaseSize,pPre, me.szModule);


	} while (Module32Next(hSnapshot, &me));

	_gettchar();

	CloseHandle(hProcess);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值