2010-10-12 9 views
7

Tôi liệt kê tất cả các luồng trong một quy trình thông qua hàm CreateToolhelp32Snapshot. Tôi muốn nhận được một số thông tin stack cơ bản cho mỗi thread. Cụ thể hơn, tôi muốn nhận địa chỉ dưới cùng của ngăn xếp và nếu có thể, tôi muốn nhận địa chỉ hàng đầu hiện tại. Về cơ bản đây là thông tin được hiển thị với lệnh ~*k trong WinDbg. Vì vậy, làm thế nào tôi có thể có được thông tin ngăn xếp từ ID của thread hoặc HANDLE?Cách nhận thông tin ngăn xếp luồng trên Windows?

Trả lời

8

(Các định nghĩa có thể được tìm thấy here.)

Để có được chồng ranh giới:

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 

Để có được giá trị của esp, chỉ cần sử dụng GetThreadContext.

+0

Cảm ơn wj32! Tôi sẽ xem xét liên kết bạn đã cung cấp. – user473750

0

Như tôi biết, Toolhelp hoạt động bằng cách tạo bản sao thông tin cơ bản về đống, mô-đun, quy trình và chuỗi. Điều này không bao gồm khối TEB chứa địa chỉ dưới cùng của ngăn xếp. Tôi nghĩ rằng bạn cần phải sử dụng API khác, động cơ debugger API, trong đó cung cấp functions to examine the stacks

1

Một cách dễ dàng hơn mà không cần phải liên quan đến việc điều khiển Kit Windows là như vậy:

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

__readfsdword() chỉ hoạt động cho thread hiện hành. Vì vậy, biến thể với NtQueryInformationThread() linh hoạt hơn.

thêm một số tờ khai được bỏ qua trong 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;