C++ WriteProcessMemory 错误 INVALID_HANDLE_VALUE

标签 c++ winapi

我正在使用“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_READPROCESS_VM_OPERATION 未设置,因此稍后出现无效句柄错误。我知道如果 OpenProcess 失败了,它真的应该返回一个错误代码 - 但事实并非如此 - 但如果这个标志真的溢出,我可以看到静默失败是如何发生的。

关于C++ WriteProcessMemory 错误 INVALID_HANDLE_VALUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25346826/

相关文章:

c++ - TCHAR 数组在反斜杠后追加 w

c++ - 如何在 GDI+ 中使用库存对象

windows - 谁改变时间?

c++ - AdjustWindowRect 文档

c++ - 找出构成给定数字所需的最少位数

c++ - 对象的链表?

c++ - Qt 5.1.1 和 OpenGL - 渲染速度

C++(以某种方式)将结构限制为父 union 大小

C# PostMessage 语法,试图将 WM_CHAR 发布到另一个应用程序窗口

c++ win32 在哪里画米