注入的 DLL 不正确 HMODULE
Injected DLL not correct HMODULE
所以我正在将一个 DLL 注入到一个程序中。我可以在 Process Explorer 的帮助下验证 DLL 是否已注入。注入后,我从进程中循环所有模块,比较名称和 return 注入的 dll 作为 HMODULE。
然后我使用 GetProcAddress() 这个 HMODULE 来在它里面找到一个外部函数,但是由于某些原因这不能正常工作。
HMODULE dllAddress = getModuleAddressFromProc(pid, "NewDll.dll");
externCreateThread createThread = (externCreateThread)GetProcAddress(dllAddress, "createThread");
当我断点并检查 dllAddress 时,它说:
当我使用 LoadLibrary 在当前程序中加载 DLL 并将其用作 HMODULE 时,它确实有效。
HMODULE dllAddress = LoadLibrary(L"C:\NewDll.dll");
externCreateThread createThread = (externCreateThread)GetProcAddress(dllAddress, "createThread");
检查 dll 地址的断点:
HMODULES 列表中的 returned HMODULE 与 LoadLibrary 中的 HMODULE 不同。虽然指针地址是一样的
列出进程中的所有模块是使用 Microsoft 提供的代码完成的。我对其进行了一些改动以用于字符串比较,但这不会影响 HMODULE 类型。
HMODULE getModuleAddressFromProc(DWORD pid, string moduleName) {
HMODULE hMods[1024];
DWORD cbNeeded;
HMODULE output;
unsigned int i;
HANDLE newHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (EnumProcessModules(newHandle, hMods, sizeof(hMods), &cbNeeded)) {
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(newHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
string s2 = charToString(szModName);
if (s2.find(moduleName) != string::npos) {
output = hMods[i];
break;
}
}
}
}
return output;
}
您可以获取另一个进程中加载的 DLL 的 HMODULE
,但您不能从您的进程中使用它来获取该 HMODULE
的过程的地址。
这是因为 Windows 中的每个进程都有自己的内存 space。因此,在不同进程中加载的同一个 DLL 的 HMODULE
值几乎肯定每次都不同。因此,一旦您在另一个进程中获得 DLL 的 HMODULE
并使用它调用 GetProcAddress(..)
,Windows 就会在您的应用程序的内存中查找,而不是在其他进程的内存中查找。由于 HMODULE
在您的应用程序中无效 GetProcAddress(..)
将失败。
如果你想在另一个进程的上下文中调用函数,你必须使用某种 interprocess communication。为此,您必须在另一个进程中有一个线程 运行 来处理这些 IPC(我想 createThread
应该这样做)。
为此,您可以使用注入的 DLL 的 DllMain(..)
函数来执行一些代码(例如调用函数 createThread(..)
):
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
createThread(..);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return (TRUE);
}
在以下人员的帮助下成功运行:
RectangleEquals -> Answer
所以我正在将一个 DLL 注入到一个程序中。我可以在 Process Explorer 的帮助下验证 DLL 是否已注入。注入后,我从进程中循环所有模块,比较名称和 return 注入的 dll 作为 HMODULE。
然后我使用 GetProcAddress() 这个 HMODULE 来在它里面找到一个外部函数,但是由于某些原因这不能正常工作。
HMODULE dllAddress = getModuleAddressFromProc(pid, "NewDll.dll");
externCreateThread createThread = (externCreateThread)GetProcAddress(dllAddress, "createThread");
当我断点并检查 dllAddress 时,它说:
当我使用 LoadLibrary 在当前程序中加载 DLL 并将其用作 HMODULE 时,它确实有效。
HMODULE dllAddress = LoadLibrary(L"C:\NewDll.dll");
externCreateThread createThread = (externCreateThread)GetProcAddress(dllAddress, "createThread");
检查 dll 地址的断点:
HMODULES 列表中的 returned HMODULE 与 LoadLibrary 中的 HMODULE 不同。虽然指针地址是一样的
列出进程中的所有模块是使用 Microsoft 提供的代码完成的。我对其进行了一些改动以用于字符串比较,但这不会影响 HMODULE 类型。
HMODULE getModuleAddressFromProc(DWORD pid, string moduleName) {
HMODULE hMods[1024];
DWORD cbNeeded;
HMODULE output;
unsigned int i;
HANDLE newHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (EnumProcessModules(newHandle, hMods, sizeof(hMods), &cbNeeded)) {
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(newHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
string s2 = charToString(szModName);
if (s2.find(moduleName) != string::npos) {
output = hMods[i];
break;
}
}
}
}
return output;
}
您可以获取另一个进程中加载的 DLL 的 HMODULE
,但您不能从您的进程中使用它来获取该 HMODULE
的过程的地址。
这是因为 Windows 中的每个进程都有自己的内存 space。因此,在不同进程中加载的同一个 DLL 的 HMODULE
值几乎肯定每次都不同。因此,一旦您在另一个进程中获得 DLL 的 HMODULE
并使用它调用 GetProcAddress(..)
,Windows 就会在您的应用程序的内存中查找,而不是在其他进程的内存中查找。由于 HMODULE
在您的应用程序中无效 GetProcAddress(..)
将失败。
如果你想在另一个进程的上下文中调用函数,你必须使用某种 interprocess communication。为此,您必须在另一个进程中有一个线程 运行 来处理这些 IPC(我想 createThread
应该这样做)。
为此,您可以使用注入的 DLL 的 DllMain(..)
函数来执行一些代码(例如调用函数 createThread(..)
):
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
createThread(..);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return (TRUE);
}
在以下人员的帮助下成功运行:
RectangleEquals -> Answer