J'énumère tous les threads d'un processus via la fonction CreateToolhelp32Snapshot
. Je voudrais obtenir des informations de base sur la pile pour chaque fil. Plus précisément, j'aimerais obtenir l'adresse du bas de la pile et, si possible, j'aimerais obtenir l'adresse actuelle de la pile. Fondamentalement, ce sont les informations affichées avec la commande ~*k
dans WinDbg. Alors, comment puis-je obtenir les informations de la pile à partir de l'ID du thread ou HANDLE?Comment obtenir des informations sur la pile de threads sous Windows?
7
A
Répondre
8
(Les définitions sont here.)
Pour obtenir des limites de la pile:
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
Pour obtenir la valeur de esp
, utilisez simplement GetThreadContext
.
0
Autant que je sache, Toolhelp fonctionne en faisant une copie des informations de base sur les tas, les modules, les processus et les threads. Cela n'inclut pas le bloc TEB qui contient l'adresse de la pile inférieure. Je pense que vous avez besoin d'utiliser une autre API, l'API du moteur de débogage, qui offre functions to examine the stacks
1
Un moyen plus facile sans avoir à impliquer le Windows Driver Kit est comme si:
NT_TIB* tib = (NT_TIB*)__readfsdword(0x18);
size_t* stackBottom = (size_t*)tib->StackLimit;
size_t* stackTop = (size_t*)tib->StackBase;
1
__readfsdword() ne fonctionne que pour le thread courant. Ainsi, la variante avec NtQueryInformationThread() est plus flexible.
Ajout de quelques déclarations qui sont manqués dans 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;
Merci wj32! Je vais regarder le lien que vous avez fourni. – user473750