我正在使用" CreateRemoteThread& WriteProcessMemory的"将我的dll注入另一个进程的技巧。我的代码在Windows 7,8上工作正常,但是当在Windows XP(VirtualBox机器)上运行时,WriteProcessMemory函数总是返回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;
}
答案 0 :(得分:2)
问题出在OpenProcess
来电。从这里开始:http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx,列在PROCESS_ALL_ACCESS
访问权限
Windows Server 2003和Windows XP:在Windows Server 2008和Windows Vista上,PROCESS_ALL_ACCESS标志的大小增加。如果为Windows Server 2008和Windows Vista编译的应用程序在Windows Server 2003或Windows XP上运行,则PROCESS_ALL_ACCESS标志太大,并且指定此标志的函数将失败并显示ERROR_ACCESS_DENIED。要避免此问题,请指定操作所需的最小访问权限集。如果必须使用PROCESS_ALL_ACCESS,请将_WIN32_WINNT设置为应用程序所针对的最小操作系统(例如,#define _WIN32_WINNT _WIN32_WINNT_WINXP)。有关更多信息,请参阅使用Windows标头。
因此,PROCESS_VM_READ
和PROCESS_VM_OPERATION
可能未设置,因此稍后会出现无效句柄错误。我知道OpenProcess
如果失败则应该返回错误代码 - 而不是 - 但如果这个标志真的溢出,我可以看到如何发生静默失败。