WELCOME TO INFOCHEATS.NET

INFOCHEATS is a community-driven platform focused on free game cheats, cheat development, and verified commercial software for a wide range of popular games. We provide a large collection of free cheats shared by the community. All public releases are checked for malicious code to reduce the risk of viruses, malware, or unwanted software before users interact with them.

Alongside free content, INFOCHEATS hosts an active marketplace with many independent sellers offering commercial cheats. Each product is discussed openly, with user feedback, reviews, and real usage experience available to help you make informed decisions before purchasing.

Whether you are looking for free cheats, exploring paid solutions, comparing sellers, or studying how cheats are developed and tested, INFOCHEATS brings everything together in one place — transparently and community-driven.

Question [Crash] Kernel Thread Hijacking — PsGetContextThread STATUS_UNSUCCESSFUL

byte_corvus

Newbie
Newbie
Newbie
Newbie
Status
Offline
Joined
Mar 3, 2026
Messages
546
Reaction score
7
Anyone currently digging into thread hijacking from the kernel has probably hit this wall. You're trying to snag a thread from a usermode process, you call KeSuspendThread, everything looks green, and then PsGetContextThread spits back STATUS_UNSUCCESSFUL.

The problem usually comes down to how Windows handles context retrieval under the hood. When you call PsGetContextThread, it relies on KeInsertQueueApc for specific architectures and states. If the thread isn't in a state where it can accept an APC—specifically if the ApcQueueable flag is unset or there is already a competing APC pending—it will fail every single time.

Code:
NTSTATUS DbgRegisters(HANDLE ThreadId)
{
  CONTEXT ctx = { 0 };
  ctx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
  PETHREAD pThread;
  NTSTATUS status = PsLookupThreadByThreadId(ThreadId, &pThread);
  
  if (NT_SUCCESS(status))
  {
    KeSuspendThread(pThread);

    // This returns STATUS_UNSUCCESSFUL if KeInsertQueueApc fails internally
    status = PsGetContextThread(pThread, &ctx, KernelMode);
    
    if (NT_SUCCESS(status))
    {
      DbgPrint("RIP = %I64X\n", ctx.Rip);
      DbgPrint("RAX = %I64X\n", ctx.Rax);
    }
    
    KeResumeThread(pThread);
  }
  
  if (pThread)
    ObDereferenceObject(pThread);
    
  return status;
}

Technical Breakdown of the Failure:
  1. ApcQueueable Flag: Check the status of the thread. If the thread is terminating or in a state where Thread->ApcQueueable is false, you can forget about getting the context this way.
  2. Existing APCs: If an APC is already inserted or the queue is locked/disallowed, KeInsertQueueApc returns false, which PsGetContextThread maps directly to STATUS_UNSUCCESSFUL.
  3. Thread State: Hijacking a thread that is in a non-alertable wait or a transition state often causes this. Suspension alone isn't always enough to guarantee the queue is open.

If you're using this for a manual mapper or an internal engine hijack, remember that modern anti-cheats often flag KeSuspendThread patterns immediately. Relying on the standard kernel API for context manipulation is basically begging for a manual ban if you don't handle the edge cases of the ETHREAD state.

Seen this trigger specifically on certain protected processes or is it a general logic flaw in the ETHREAD handling? Drop your logs below.
 
Top