GetThreadContext()返回87

时间:2017-09-23 13:37:22

标签: c++ winapi

我试图获取暂停写字板的线程上下文。但是,无论我对代码做了什么更改,它都会返回87.

STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
CONTEXT ctx;

if (CreateProcess(L"C:\\Windows\\write.exe", NULL, NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
{
    cout << "-> Success <-" << endl;
}

else
{
    cout << GetLastError();
}

if (GetThreadContext(pi.hThread, &ctx))
{
    cout << "-> Success <-" << endl;
}

else
{
    cout << GetLastError();
}

1 个答案:

答案 0 :(得分:2)

CONTEXT结构包含特定于处理器的寄存器数据。所以它的定义取决于目标架构。对 x86 amd64 说明不同的CONTEXT定义。

在64位窗口中存在32-64位问题:

  • 64位应用程序可以通过调用获得任何线程的64位上下文 GetThreadContext
  • 64位应用程序可以通过调用获取 WOW64 线程的32位上下文 Wow64GetThreadContext。注意在这种情况下你需要使用 WOW64_CONTEXT
  • 32位应用程序只能获取 WOW64 线程的32位上下文 致电GetThreadContext
  • 当32位应用程序尝试获取64位线程的上下文时 应用程序 - GetThreadContext始终失败 ERROR_INVALID_PARAMETER

所以基于你的错误,我可以说你在64位窗口上运行。这里 write.exe 是64位进程,你的代码是32位。在这种情况下你无法得到上下文。

另外,作为一般说明,我们始终必须ContextFlags成员ctx。这是强制性的:

  

该函数根据的值检索选择性上下文    ContextFlags 上下文结构的成员。

所以当 ContextFlags 未定义时 - GetThreadContext返回未定义的结果

所以代码必须是下一个:

    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi ;

    if (CreateProcess(L"C:\\Windows\\write.exe", NULL, NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
    {
        union {
            CONTEXT ctx;
#ifdef _WIN64
            WOW64_CONTEXT wow_ctx;
#endif
        };

        BOOL fOk = FALSE;
        BOOL Wow;
#ifdef _WIN64
        if (IsWow64Process(pi.hProcess, &Wow))
        {
            if (Wow)
            {
                wow_ctx.ContextFlags = WOW64_CONTEXT_DEBUG_REGISTERS|WOW64_CONTEXT_CONTROL|WOW64_CONTEXT_INTEGER;
                fOk = Wow64GetThreadContext(pi.hThread, &wow_ctx);
            }
            else
            {
                ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS|CONTEXT_INTEGER|CONTEXT_CONTROL;
                fOk = GetThreadContext(pi.hThread, &ctx);
            }
        }
#else
        BOOL MyWow;
        if (IsWow64Process(NtCurrentProcess(), &MyWow) && IsWow64Process(pi.hProcess, &Wow))
        {
            if ((MyWow != 0) ^ (Wow != 0))
            {
                //32-bit app can not got context of 64-bit app
                SetLastError(ERROR_GEN_FAILURE);
            }
            else
            {
                ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS|CONTEXT_INTEGER|CONTEXT_CONTROL;
                fOk = GetThreadContext(pi.hThread, &ctx);
            }
        }

        if (!fOk)
        {
            DbgPrint("error=%u\n", GetLastError());
        }
#endif
        ResumeThread(pi.hThread);
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }