在Windows操作系统的内核级编程和系统管理领域,NtQueryInformationThread 是一个非常强大且具有重要意义的函数。它允许开发者获取关于线程的各种详细信息,为深入理解系统线程的行为和状态提供了有力的工具。
NtQueryInformationThread 属于Windows NT内核API的一部分。其作用是查询指定线程的各种信息,包括但不限于线程的基本信息(如线程ID、线程状态等)、线程的优先级、线程的上下文(包含寄存器值等重要信息)以及线程的安全属性等。
官网API说明:NtQueryInformationThread function (winternl.h) - Win32 apps | Microsoft Learn
NTSTATUS NtQueryInformationThread(
HANDLE ThreadHandle,
THREADINFOCLASS ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength,
PULONG ReturnLength
);
#include <windows.h>
#include <winternl.h>
// 定义必要的结构体和常量
typedef NTSTATUS (WINAPI *PNtQueryInformationThread)(
HANDLE ThreadHandle,
THREADINFOCLASS ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength,
PULONG ReturnLength
);
int main() {
HANDLE hThread = /* 获取线程句柄 */;
THREAD_BASIC_INFORMATION tbi;
ULONG returnLength;
PNtQueryInformationThread NtQueryInformationThread = /* 加载函数地址 */;
NTSTATUS status = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), &returnLength);
if (NT_SUCCESS(status)) {
// 处理查询到的信息
} else {
// 处理错误
}
return 0;
}
需要注意的是,实际使用时需要正确加载 NtQueryInformationThread 函数的地址,并处理相关的错误情况。
下面是ThreadInformationClass官方公开的用法
typedef enum _THREADINFOCLASS {
ThreadIsIoPending = 16,
ThreadNameInformation = 38
} THREADINFOCLASS;
实际上ThreadInformationClass还有许多官方未公开的用法,
typedef enum _THREADINFOCLASS {
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY
ThreadBasePriority, // s: LONG
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup, // s: BOOLEAN
ThreadEventPair,
ThreadQuerySetWin32StartAddress, // q: PVOID
ThreadZeroTlsCell, // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress,
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState,
ThreadIsTerminated, // 20, q: ULONG
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: ULONG
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION
ThreadPagePriority, // q: ULONG
ThreadActualBasePriority,
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon,
ThreadCSwitchPmu,
ThreadWow64Context, // q: WOW64_CONTEXT
ThreadGroupInformation, // 30, q: GROUP_AFFINITY
ThreadUmsInformation,
ThreadCounterProfiling,
ThreadIdealProcessorEx, // q: PROCESSOR_NUMBER
ThreadCpuAccountingInformation, // since WIN8
ThreadSuspendCount, // since WINBLUE
MaxThreadInfoClass
} THREADINFOCLASS;
来源于:none/src/unone/native/unone-native.h at master · BlackINT3/none
利用ThreadInformationClass拓展值,可以检测是否存在指定名称的进程挂起,如果有挂起则终止挂起的进程
bool IsThreadSuspended(HANDLE hThread) {
qInfo() << QOperatingSystemVersion::current();
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1) {
//qInfo() << "IsThreadSuspended system version lower for win8.1";
DWORD suspendCount = SuspendThread(hThread);
ResumeThread(hThread);
//qInfo() << "SuspendThread previse count = " << suspendCount;
return suspendCount != 0;
}
PNtQueryInformationThread NtQueryInformationThread =
(PNtQueryInformationThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationThread");
if (!NtQueryInformationThread) {
//qWarning() << "GetProcAddress [NtQueryInformationThread] failed. Error: %lu" << GetLastError();
return false;
}
ULONG suspendCount;
NTSTATUS status = NtQueryInformationThread(hThread, (THREADINFOCLASS)35, &suspendCount,
sizeof(suspendCount), NULL);
if (status != 0) {
//qWarning() << "NtQueryInformationThread failed. Error: %lu" << GetLastError();
return false;
}
return suspendCount > 0;
}
bool TerminateSuspendedProcesses(const std::wstring& processName, DWORD currentProcessID) {
bool bFound = false;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
//qWarning() << "CreateToolhelp32Snapshot failed. Error: " << GetLastError();
return bFound;
}
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe32)) {
//qWarning() << "Process32First failed. Error: " << GetLastError();
CloseHandle(hSnapshot);
return bFound;
}
do {
if (pe32.szExeFile == processName && pe32.th32ProcessID != currentProcessID) {
HANDLE hProcess =
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pe32.th32ProcessID);
if (hProcess != NULL) {
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap != INVALID_HANDLE_VALUE) {
THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32);
if (Thread32First(hThreadSnap, &te32)) {
do {
if (te32.th32OwnerProcessID == pe32.th32ProcessID) {
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME, FALSE,
te32.th32ThreadID);
if (hThread != NULL) {
if (IsThreadSuspended(hThread)) {
//qInfo() << L"Terminating suspended process " << processName << L" with PID "
// << pe32.th32ProcessID;
TerminateProcess(hProcess, EXIT_CODE_HUNG_KILL);
bFound = true;
break; // Assuming only one suspended thread is enough to terminate the process
}
CloseHandle(hThread);
} else {
//qWarning() << "Failed to open thread. Error: " << GetLastError();
}
}
} while (Thread32Next(hThreadSnap, &te32));
}
CloseHandle(hThreadSnap);
} else {
//qWarning() << "CreateToolhelp32Snapshot for threads failed. Error: " << GetLastError();
}
if (bFound) {
DWORD dwExitCode; // 进程退出代码
// 等待进程终止
if (WaitForSingleObject(hProcess, INTERVAL_MAX_WAIT_PROCESS_EXIT) == WAIT_FAILED) {
//qWarning() << "WaitForSingleObject Process terminated failed. Error: " << GetLastError();
} else {
//qInfo() << "Process terminated successfully";
}
// 获取进程退出代码
if (!GetExitCodeProcess(hProcess, &dwExitCode)) {
//qWarning() << "GetExitCodeProcess failed. Error: " << GetLastError();
} else {
//qInfo() << "Process exit code: " << dwExitCode;
}
}
CloseHandle(hProcess);
} else {
//qWarning() << "Failed to open process. Error: " << GetLastError();
}
}
} while (Process32Next(hSnapshot, &pe32));
CloseHandle(hSnapshot);
return bFound;
}
bool ApplicationHandler::CheckSuspendAndKill() {
return TerminateSuspendedProcesses(TARGET_PROCESS_NAME, GetCurrentProcessId());
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有