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

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

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

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

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-9-5 18:22 被Lixinist编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (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
活跃值: (1838)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
4
ZwQueryInformationThread
2019-9-4 10:38
1
雪    币: 12857
活跃值: (9172)
能力值: ( 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
上一份代码
#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)(UINT, PVOID, DWORD, 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
游客
登录 | 注册 方可回帖
返回
//