2017-09-23 154 views
3

我試圖獲取暫停寫字板的線程上下文。但是,不管我對代碼做什麼樣的變化,它會返回87GetThreadContext()返回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(); 
} 
+0

您是否嘗試過:'如果函數調用失敗,返回值是零。要獲得擴展的錯誤信息,請調用GetLastError.'? – Stefan

+0

*此結構的ContextFlags成員的值指定檢索線程上下文的哪些部分*,但您不初始化此成員。 – RbMm

+0

爭用條件'CreateProcess':_「...請注意,函數在進程完成初始化之前返回......」_ source:https://msdn.microsoft.com/en-us/library/windows/desktop /ms682425(v=vs.85).aspx –

回答

1

CONTEXT結構包含特定處理器的寄存器中的數據。所以它的定義取決於目標架構。對於x86amd64不同的CONTEXT的定義。

這裏存在32-64位問題64位Windows:

  • 64位應用程序可以通過調用 GetThreadContext
  • 64位應用程序得到任何線索的情況下64位可以得到32位上下文WOW64線程調用 Wow64GetThreadContext。請注意,在這種情況下,您需要使用 WOW64_CONTEXT
  • 32位應用程序只能得到的WOW64線程通過 呼叫GetThreadContext
  • 當32位應用程序嘗試獲取線程的上下文64位 應用32位文脈 - 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); 
    } 
+0

感謝您的回覆 - 我嘗試設置上下文標誌,並且不幸地得到了相同的結果。 –

+0

@ DennisFlores - 理解 - 你的過程是一個過程(64位窗口中的32位過程)。 * write.exe *是64位進程。他根本沒有32位上下文 – RbMm

+0

謝謝你,非常高質量的答案。 Stackoverflow永遠不會失望。我感到尷尬,我不知道記事本是x64 haha​​h –