获取模块的基地址有如下几种方法:
1. 模块句柄就是模块基地址(或称模块加载地址),直接将模块句柄转换为模块基地址
2. 根据模块中的地址得到模块句柄,模块句柄就是基地址
GetModuleHandleEx
3. 根据模块中的地址得到这个地址所属模块的基地址
但是 SymGetModuleInfoW64 总是运行失败
4. 使用 VirtualQueryEx 函数
5. 根据进程句柄和模块句柄得到模块的基地址
GetModuleInformation
代码如下:
#include "stdafx.h"
#include <Windows.h>
#include <Psapi.h>
#include <dbghelp.h>
#include <string>
#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "Dbghelp.lib")
int _tmain(int argc, _TCHAR* argv[])
{
// 1.
printf("模块句柄就是模块基地址 : 0x%X\n", ::GetModuleHandle(L"kernel32.dll"));
// 2.
HMODULE hMoudle = nullptr;
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&GetCurrentProcess, &hMoudle);
printf("GetModuleHandleEx : 0x%X\n", hMoudle);
// 3.
IMAGEHLP_MODULEW64 im = {0};
im.SizeOfStruct = sizeof(im);
if (::SymGetModuleInfoW64(::GetCurrentProcess(), (DWORD64)&GetCurrentProcess, &im))
{
printf("SymGetModuleInfoW64 : 0x%X\n", im.BaseOfImage);
}
else
{
printf("SymGetModuleInfoW64 failed, LastError : %d\n", ::GetLastError());
}
// 4.
MEMORY_BASIC_INFORMATION mbi;
if (::VirtualQueryEx(::GetCurrentProcess(), (LPCVOID)&GetCurrentProcess, &mbi, sizeof(mbi)) != 0)
{
printf("VirtualQueryEx : 0x%X\n", mbi.AllocationBase);
}
else
{
printf("VirtualQueryEx failed, LastError : %d\n", ::GetLastError());
}
// 5.
MODULEINFO moduleInfo;
::GetModuleInformation(::GetCurrentProcess(), ::GetModuleHandle(L"kernel32.dll"), &moduleInfo, sizeof(moduleInfo));
printf("GetModuleInformation:0x%X\n", moduleInfo.lpBaseOfDll);
getchar();
return 0;
}