我正在使用“CreateRemoteThread & WriteProcessMemory”技术将我的 dll 注入(inject)另一个进程。我的代码在 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;
}
最佳答案
问题在于您的 OpenProcess
调用。来自这里:http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx ,在 PROCESS_ALL_ACCESS
访问权限下列出:
Windows Server 2003 and Windows XP: The size of the PROCESS_ALL_ACCESS flag increased on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run on Windows Server 2003 or Windows XP, the PROCESS_ALL_ACCESS flag is too large and the function specifying this flag fails with ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for the operation. If PROCESS_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum operating system targeted by your application (for example, #define _WIN32_WINNT _WIN32_WINNT_WINXP). For more information, see Using the Windows Headers.
因此,可能是 PROCESS_VM_READ
和 PROCESS_VM_OPERATION
未设置,因此稍后出现无效句柄错误。我知道如果 OpenProcess
失败了,它真的应该返回一个错误代码 - 但事实并非如此 - 但如果这个标志真的溢出,我可以看到静默失败是如何发生的。
关于C++ WriteProcessMemory 错误 INVALID_HANDLE_VALUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25346826/