所以我正在学习一些测试可执行文件的dll注入内容。一旦我注入了我的dll,我就会尝试获取模块句柄,然后尝试获取模块的基地址(主exe)。
DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, WCHAR *lpszModuleName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessIdentifier);
DWORD dwModuleBaseAddress = 0;
if(hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32 = {0};
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if(Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if(wcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
{
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
}
while(Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
这就是我尝试这样做的方式。这是在我的dll被注入之后,但由于某种原因它似乎返回INVALID_HANDLE_VALUE。我从一个网站找到了这个功能并对其进行了一些修改,但它似乎仍然没有用。如果你有一个更清洁的方法来获得基地址,我会很高兴知道它。
现在使用以下行编辑问题:
if(wcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
它永远不会是0但是我正在寻找一个模块名称,我可以在调试器中看到我的exe,但是这种比较并不起作用。
这就是我调用函数的方法
HWND window = FindWindow(0, LPCWSTR("test"));
DWORD pID = 0;
GetWindowThreadProcessId(window, &pID);
base = dwGetModuleBaseAddress(pID, (WCHAR*)("test"));
答案 0 :(得分:0)
您正在使用为宽字符串设计的功能。
"test"
L"test"
第一行是常规的c字符串char数组。第二行使用L宏将字符串文字定义为宽字符字符串。
强制转换为WCHAR *并不能解决问题,您必须使用L宏定义它们,或者将函数切换为使用常规char数组。
这是我使用的函数的常规char数组版本
char* GetModuleBaseAddress(const char* modName, DWORD procId)
{
char* modBaseAddr{ nullptr };
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry{};
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_stricmp(modEntry.szModule, modName))
{
modBaseAddr = (char*)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}