【发布时间】:2014-10-10 09:27:00
【问题描述】:
我正在使用“CreateRemoteThread & WriteProcessMemory”技术将我的 dll 注入另一个进程。我的代码在 Windows 7,8 上运行良好,但 WriteProcessMemory 函数在 Windows XP(VirtualBox 机器)上运行时总是返回 FALSE(GetLastError = 6 - INVALID_HANDLE_VALUE)。你不能帮帮我吗? 以下是主要代码:
BOOL CHookDLL::DoHook(const DWORD dwProcessId, const CHAR* szDLLHookName)
{
CHAR szDllHookPath[1024] = "";
HANDLE hRemoteThread = NULL;
HMODULE hLib = 0;
LPVOID RemoteString = NULL;
LPVOID LoadLibAddy = NULL;
if (dwProcessId == NULL){
__OutputDebug("CHookDLL::DoHook\tpProcessId NULL");
return FALSE;
}
::GetFullPathNameA(szDLLHookName, MAX_PATH, szDllHookPath, NULL);
if (::PathFileExists((CString)szDllHookPath) == FALSE){
__OutputDebug("CHookDLL::DoHook\tPathFileExists FALSE");
return FALSE;
}
// enable SeDebugPrivilege
if (!SetPrivilege(m_hTokenSetPrivilege, SE_DEBUG_NAME, TRUE))
{
__OutputDebug("CHookDLL::DoHook\tSetPrivilege FAILED");
// close token handle
CloseHandle(m_hTokenSetPrivilege);
return FALSE;
}
m_hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (m_hProcess == NULL){
__OutputDebug("CHookDLL::DoHook\tOpenProcess FALSE: %d", GetLastError());
return FALSE;
}
LoadLibAddy = (LPVOID)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if (LoadLibAddy == NULL){
__OutputDebug("CHookDLL::DoHook\tGetProcAddress NULL");
return FALSE;
}
// Allocate space in the process for our DLL
RemoteString = (LPVOID)VirtualAllocEx(m_hProcess, NULL, strlen(szDllHookPath) + 1,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (RemoteString == NULL){
__OutputDebug("CHookDLL::DoHook\tVirtualAllocEx NULL");
return FALSE;
}
// this line is return FALSE
if (WriteProcessMemory(m_hProcess, RemoteString, szDllHookPath, strlen(szDllHookPath) + 1, NULL) == FALSE)
{
__OutputDebug("CHookDLL::DoHook\tWriteProcessMemory FALSE: %d", GetLastError());
return FALSE;
}
hRemoteThread = ::CreateRemoteThread(m_hProcess, NULL, NULL,
(LPTHREAD_START_ROUTINE)LoadLibAddy,
(LPVOID)RemoteString, NULL, NULL);
::WaitForSingleObject(hRemoteThread, INFINITE);
// Get handle of the loaded module
::GetExitCodeThread(hRemoteThread, &m_hLibModule);
if (m_hLibModule == NULL){
__OutputDebug("CHookDLL::DoHook\tCreateRemoteThread NULL");
return FALSE;
}
// Clean up
::CloseHandle(hRemoteThread);
::VirtualFreeEx(m_hProcess, RemoteString,
strlen(szDllHookPath) + 1, MEM_RELEASE);
__OutputDebug("Hook OK");
return TRUE;
}
// Common function Output Debug String
static INT __OutputDebug(const CHAR* format, ...)
{
#ifndef DEBUG
return -1;
#endif // DEBUG
if (format[0] == 0) return -1;
CHAR szDebug[1024] = "";
va_list arglist;
va_start(arglist, format);
vsprintf_s(szDebug,format, arglist);
va_end(arglist);
strcat_s(szDebug, "\n");
OutputDebugStringA(szDebug);
return 1;
}
【问题讨论】:
-
您已经验证句柄有效。所以你可能已经破坏了错误报告,摸索 GetLastError() 是一个非常常见的问题。我们看不到 __OutputDebug,请确保它不是宏。
-
谢谢你的评论。 __OutputDebug 只是调用 API OutputDebugString 的常用函数。我只想解决为什么 WriteProcessMemory 返回 FALSE。你觉得呢?请给我你的想法。谢谢你。
-
我在问题页脚中有 __OutputDebug 的邮政编码。
-
好吧,不是这样。在“m_hProcess”上设置一个数据断点,这样你就可以看到它被覆盖了,这就是我能想到的。