首页
社区
课程
招聘
[求助]如何判断一个线程的状态
发表于: 2019-9-4 09:48 4605

[求助]如何判断一个线程的状态

2019-9-4 09:48
4605
像pchunter中可以看到各个线程的状态。
之前一直以为在teb中可以查到,但是查资料,看书都没有找到比较好的方法。
有谁可以告知一下吗

PS:6楼上了一份代码。
虽然成功实现了判断出线程的状态。但是还是不知道pchunter是怎么查出之前的线程的“终止”状态的。。。
(遍历时无法遍历出之前已经终止的线程,暂时靠GetExitCodeThread查询有没有终止)

[注意]看雪招聘,专注安全领域的专业人才平台!

最后于 2019-9-5 18:22 被Lixinist编辑 ,原因:
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
zx_838741
为你点赞~
2021-4-27 20:37
最新回复 (5)
雪    币: 4006
活跃值: (756)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
GetExitCodeThread ? 如果状态不是STILL_ACTIVE就是等待?
2019-9-4 09:55
0
雪    币: 9934
活跃值: (2554)
能力值: ( LV6,RANK:87 )
在线值:
发帖
回帖
粉丝
3
放学打我不 GetExitCodeThread ? 如果状态不是STILL_ACTIVE就是等待?
这个貌似只能判断线程死亡了没有,
2019-9-4 10:07
1
雪    币: 9626
活跃值: (1848)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
4
ZwQueryInformationThread
2019-9-4 10:38
1
雪    币: 12862
活跃值: (9282)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
5
https://github.com/adrianyy/EACReversing/blob/20fea8ae5f783394e13aad1a1b358f787db7fe71/EasyAntiCheat.sys/systemthread.c#L241

 不谢
2019-9-4 11:21
1
雪    币: 9934
活跃值: (2554)
能力值: ( LV6,RANK:87 )
在线值:
发帖
回帖
粉丝
6
上一份代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include <iostream>
#include <Windows.h>
 
#define NT_SUCCESS(Status)                 ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS                     ((NTSTATUS)0x00000000)
#define SystemProcessesAndThreadsInformation   5 // 功能号
#define NTAPI                              __stdcall
 
typedef LONG KPRIORITY;
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _VM_COUNTERS
{
    SIZE_T      PeakVirtualSize;
    SIZE_T      VirtualSize;
    ULONG       PageFaultCount;
    SIZE_T      PeakWorkingSetSize;
    SIZE_T      WorkingSetSize;
    SIZE_T      QuotaPeakPagedPoolUsage;
    SIZE_T      QuotaPagedPoolUsage;
    SIZE_T      QuotaPeakNonPagedPoolUsage;
    SIZE_T      QuotaNonPagedPoolUsage;
    SIZE_T      PagefileUsage;
    SIZE_T      PeakPagefileUsage;
} VM_COUNTERS;
typedef struct _CLIENT_ID
{
    DWORD        UniqueProcess;
    DWORD        UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef enum _THREAD_STATE
{
    StateInitialized,// 初始化状态
    StateReady,// 准备状态
    StateRunning,// 运行状态
    StateStandby,// 
    StateTerminated,//关闭
    StateWait,// 等待
    StateTransition,// 切换???
    StateUnknown
}THREAD_STATE;
typedef enum _KWAIT_REASON
{
    Executive,
    FreePage,
    PageIn,
    PoolAllocation,
    DelayExecution,
    Suspended,
    UserRequest,
    WrExecutive,
    WrFreePage,
    WrPageIn,
    WrPoolAllocation,
    WrDelayExecution,
    WrSuspended,
    WrUserRequest,
    WrEventPair,
    WrQueue,
    WrLpcReceive,
    WrLpcReply,
    WrVirtualMemory,
    WrPageOut,
    WrRendezvous,
    Spare2,
    Spare3,
    Spare4,
    Spare5,
    Spare6,
    WrKernel,
    MaximumWaitReason
}KWAIT_REASON;
typedef struct _SYSTEM_THREAD_INFORMATION
{
    LARGE_INTEGER   KernelTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   CreateTime;
    ULONG           WaitTime;
    PVOID           StartAddress;
    CLIENT_ID       ClientId;
    KPRIORITY       Priority;
    KPRIORITY       BasePriority;
    ULONG           ContextSwitchCount;
    LONG            State;// 状态,是THREAD_STATE枚举类型中的一个值
    LONG            WaitReason;//等待原因, KWAIT_REASON中的一个值
} SYSTEM_THREAD_INFORMATION , *PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFRMATION
{
    ULONG           NextEntryDelta;//指向下一个结构体的指针
    ULONG           ThreadCount;//本进程的总线程数
    ULONG           Reserved1[6];//保留
    LARGE_INTEGER   CreateTime;//进程创建的时间
    LARGE_INTEGER   UserTime;//在用户层的使用时间
    LARGE_INTEGER   KernelTime;//在内核层的使用时间
    UNICODE_STRING  ProcessName; // 进程名
    KPRIORITY       BasePriority;
    ULONG           ProcessId;//进程ID
    ULONG           InheritedFromProcessId;
    ULONG           HandleCount; // 进程的句柄总数
    ULONG           Reserved2[2]; // 保留
    VM_COUNTERS     VmCounters;
    IO_COUNTERS     IoCounters;
    SYSTEM_THREAD_INFORMATION Threads[1]; // 子线程信息数组
}SYSTEM_PROCESS_INFORMATION , *PSYSTEM_PROCESS_INFORMATION;
 
typedef DWORD(WINAPI* PQUERYSYSTEM)(UINTPVOIDDWORD, PDWORD);
int IsThreadSuspend(DWORD dwProcessID, DWORD dwThreadID)
{
    int ret = 0;
    NTSTATUS Status = 0;
    PQUERYSYSTEM NtQuerySystemInformation = NULL;
    PSYSTEM_PROCESS_INFORMATION pInfo = { 0 };
    //获取函数地址
    NtQuerySystemInformation=(PQUERYSYSTEM)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
    //获取API所需Size
    DWORD dwSize = 0;
    Status = NtQuerySystemInformation(5,NULL, 0, &dwSize); //#define SystemProcessesAndThreadsInformation 5 // 功能号
    //申请内存
    char* pBuff = new char[dwSize];
    pInfo =(PSYSTEM_PROCESS_INFORMATION) pBuff;
    if (pInfo == NULL)
        return -1;
    //调用API获取信息
    Status = NtQuerySystemInformation(5, pInfo, dwSize, &dwSize); //#define SystemProcessesAndThreadsInformation 5 // 功能号
    if (!NT_SUCCESS(Status))
    {
        printf("失败");
        delete[] pInfo;
        return -1;
    }
    //找到进程并遍历所有线程
    while (1)
    {   //判断是否还有下一个进程
        if (pInfo->NextEntryDelta == 0)
            break;
        //判断是否找到了进程ID
        if (pInfo->ProcessId == dwProcessID)
        {
            //遍历进程下的所有线程(如果某线程已终止,将遍历不到)
            for (DWORD i = 0; i < pInfo->ThreadCount; i++)
            {
                //找到线程
                if (pInfo->Threads[i].ClientId.UniqueThread == dwThreadID)
                {
                    printf("线程状态为%ld\n", pInfo->Threads[i].State);
                    if (pInfo->Threads[i].State == StateRunning)
                    {
                        ret = 1;
                        break;
                    }
                    if (pInfo->Threads[i].State == StateWait)
                    {   //等待原因
                        if (pInfo->Threads[i].WaitReason == Suspended)
                            printf("等待原因:Suspended!\n");
                        ret = 2;
                        break;
                    }
                     
                }
            }
            break;
        }
        //换下一个节点
        pInfo = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pInfo + pInfo->NextEntryDelta);
    }
    delete[] pBuff;
    return ret;
}
 
//判断线程是否还活着,活着为True,结束为False
BOOL IsThreadAlive(DWORD dwThreadID)
{
    BOOL ret = FALSE;
    DWORD ExitCode = 0;
    HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, dwThreadID);
    if (hThread != NULL) {
        if (GetExitCodeThread(hThread, &ExitCode)) {
            if (ExitCode == STILL_ACTIVE)
                ret= TRUE;
        }
        CloseHandle(hThread);
    }
    return ret;
}
 
#define PID 11372   //进程ID
#define TID 32      //线程ID
int main()
{
    if (IsThreadAlive(TID))
        printf("线程存活\n");
    else
        printf("线程已结束\n");
 
    int ret = IsThreadSuspend(PID,TID);
    switch (ret)
    {
        case 1: printf("线程运行状态");
            break;
        case 2:    printf("线程等待状态");
            break;
        default:printf("线程不是运行或等待状态");
            break;
    }
}
最后于 2019-9-5 18:42 被Lixinist编辑 ,原因:
2019-9-5 18:15
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册