C ++ WriteProcessMemory错误INVALID_HANDLE_VALUE

时间:2014-08-17 06:32:02

标签: c++ winapi

我正在使用" 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;
}

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_READPROCESS_VM_OPERATION可能未设置,因此稍后会出现无效句柄错误。我知道OpenProcess如果失败则应该返回错误代码 - 而不是 - 但如果这个标志真的溢出,我可以看到如何发生静默失败。