Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос PsGetContextThread возвращает STATUS_UNSUCCESSFUL при хайджекинге потока

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
566
Реакции
14
Траблы с PsGetContextThread:
Пытаюсь реализовать классический Thread Hijacking из драйвера для инжекта в юзермод процесс. Логика стандартная: находим поток, вешаем саспенд, но на этапе получения контекста через PsGetContextThread ловлю стабильный STATUS_UNSUCCESSFUL.

Самое забавное, что KeSuspendThread и KeResumeThread отрабатывают без нареканий. По логам и анализу ядра ошибка вылетает, когда KeInsertQueueApc внутри функции дает осечку. Обычно это происходит, если у потока сброшен флаг ApcQueueable или в очереди уже висит аналогичный APC.

Код:
Expand Collapse Copy
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);
    
    // Тут стабильно прилетает 0xC0000001
    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;
}

Что может быть не так:
  1. Поток находится в специфическом состоянии, когда доставка APC невозможна (например, он уже в процессе терминации).
  2. Потоки некоторых системных процессов или под защитой античитов могут иметь свои нюансы с доставкой APC.
  3. Пробовал играться с флагами ContextFlags, но результат тот же.
  4. IRQL на уровне PASSIVE_LEVEL, так что тут проблем быть не должно.

Кто сталкивался с таким поведением системы при разработке своего софта? Можно, конечно, лезть в оффсеты KTHREAD и парсить стек вручную, но хотелось бы понять, почему штатный метод из состава ядра шлет меня лесом.

Есть идеи, как это пофиксить или обойти без лишних костылей?
 
Назад
Сверху Снизу