C++ WriteProcessMemory error INVALID_HANDLE_VALUE

C++ WriteProcessMemory error INVALID_HANDLE_VALUE

本文关键字:HANDLE VALUE INVALID WriteProcessMemory error C++      更新时间:2023-10-16

我正在使用"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::DoHooktpProcessId NULL");
        return FALSE;
    }
    ::GetFullPathNameA(szDLLHookName, MAX_PATH, szDllHookPath, NULL);
    if (::PathFileExists((CString)szDllHookPath) == FALSE){
        __OutputDebug("CHookDLL::DoHooktPathFileExists FALSE");
        return FALSE;
    }
    // enable SeDebugPrivilege
    if (!SetPrivilege(m_hTokenSetPrivilege, SE_DEBUG_NAME, TRUE))
    {
        __OutputDebug("CHookDLL::DoHooktSetPrivilege FAILED");
        // close token handle
        CloseHandle(m_hTokenSetPrivilege);
        return FALSE;
    }
    m_hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (m_hProcess == NULL){
        __OutputDebug("CHookDLL::DoHooktOpenProcess FALSE: %d", GetLastError());
        return FALSE;
    }
    LoadLibAddy = (LPVOID)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
    if (LoadLibAddy == NULL){
        __OutputDebug("CHookDLL::DoHooktGetProcAddress 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::DoHooktVirtualAllocEx NULL");
        return FALSE;
    }
        // this line is return FALSE
    if (WriteProcessMemory(m_hProcess, RemoteString, szDllHookPath, strlen(szDllHookPath) + 1, NULL) == FALSE)
    {
        __OutputDebug("CHookDLL::DoHooktWriteProcessMemory 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::DoHooktCreateRemoteThread 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和Windows XP: PROCESS_ALL_ACCESS标志的大小在Windows Server 2008和Windows Vista中增加。如果为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_READPROCESS_VM_OPERATION没有被设置,因此稍后会出现无效句柄错误。我知道,如果OpenProcess失败,它应该返回一个错误代码-它不是-但如果这个标志真的溢出,我可以看到一个无声的失败是如何发生的。

相关文章: