2010-10-12 6 views
7

Enumero todos los hilos en un proceso a través de la función CreateToolhelp32Snapshot. Me gustaría obtener información de pila básica para cada hilo. Más específicamente, me gustaría obtener la dirección del fondo de la pila y, si es posible, me gustaría obtener la dirección actual de la pila. Básicamente esta es la información que se muestra con el comando ~*k en WinDbg. Entonces, ¿cómo puedo obtener la información de la pila desde la ID del hilo o HANDLE?¿Cómo obtener la información de la pila de subprocesos en Windows?

Respuesta

8

(Las definiciones pueden encontrarse here.)

para obtener los límites de pila:

THREAD_BASIC_INFORMATION basicInfo; 
NT_TIB tib; 

// Get TEB address 
NtQueryInformationThread(YOUR_THREAD_HANDLE, ThreadBasicInformation, &basicInfo, sizeof(THREAD_BASIC_INFORMATION), NULL); 
// Read TIB 
NtReadVirtualMemory(YOUR_PROCESS_HANDLE, basicInfo.TebBaseAddress, &tib, sizeof(NT_TIB), NULL); 
// Check tib.StackBase and tib.StackLimit 

para obtener el valor de esp, simplemente use GetThreadContext.

+0

, gracias wj32! Echaré un vistazo al enlace que proporcionaste. – user473750

0

Según lo que sé, Toolhelp funciona al hacer una copia de la información básica sobre montones, módulos, procesos y subprocesos. Esto no incluye el bloque TEB que contiene la dirección inferior de la pila. Creo que es necesario utilizar otro API, la API del motor depurador, que ofrece functions to examine the stacks

1

Una forma más fácil sin tener que involucrar el Kit de controladores de Windows es tan así:

NT_TIB* tib = (NT_TIB*)__readfsdword(0x18); 
size_t* stackBottom = (size_t*)tib->StackLimit; 
size_t* stackTop = (size_t*)tib->StackBase; 
1

__readfsdword() sólo funciona para el subproceso actual. Entonces, la variante con NtQueryInformationThread() es más flexible.

añadido algunas declaraciones que no son detectados en ntdll.h:

typedef enum _THREADINFOCLASS { 
    ThreadBasicInformation = 0, 
} THREADINFOCLASS; 

typedef LONG KPRIORITY; 

typedef struct _CLIENT_ID { 
    HANDLE UniqueProcess; 
    HANDLE UniqueThread; 
} CLIENT_ID; 
typedef CLIENT_ID *PCLIENT_ID; 

typedef struct _THREAD_BASIC_INFORMATION 
{ 
    NTSTATUS    ExitStatus; 
    PVOID     TebBaseAddress; 
    CLIENT_ID    ClientId; 
    KAFFINITY    AffinityMask; 
    KPRIORITY    Priority; 
    KPRIORITY    BasePriority; 
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; 
Cuestiones relacionadas