NtQuerySystemInformation获取进程/线程状态
__kernel_entry NTSTATUS NtQuerySystemInformation(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
这是一个NT函数,需要通过LoadLibrary()和GetProcAddress()来获取其地址继而调用它。其第一个参数SystemInformationClass指定要检索的系统信息的类型,如果要检测进程和线程的信息就让参数的值为SystemProcessInformation。由SystemInformation参数指向的缓冲区包含每个进程的SYSTEM_PROCESS_INFORMATION结构。这些结构中的每一个紧随其后的是内存中的一个或多个SYSTEM_THREAD_INFORMATION结构,这些结构为上一个进程中的每个线程提供信息。
typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER Reserved1[3];
ULONG Reserved2;
PVOID StartAddress; //线程开始的虚拟地址;
CLIENT_ID ClientId; //线程标识符;
KPRIORITY Priority; //线程优先级;
LONG BasePriority; //基本优先级;
ULONG Reserved3;
ULONG ThreadState; //当前状态;
ULONG WaitReason; //等待原因;
} SYSTEM_THREAD_INFORMATION;
ThreadState的值与WaitReason的值都等于5则表示线程被挂起了。如果我们要判断进程的状态就可以通过判断进程中所有线程是不是都被挂起了。
#include <winternl.h>
typedef NTSTATUS(_stdcall * pfnNtQuerySystemInformation)(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
int main()
{
pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)::GetProcAddress(::LoadLibrary(TEXT("ntdll.dll")),TEXT("NtQuerySystemInformation"));
LPVOID dwBufferProcess = 0; //接收数据的缓冲区
DWORD dwBufferProcessSize = 0; //需要接收的数据的缓冲区大小
DWORD dwThreadNum; //进程中所含线程数目
NtQuerySystemInformation(SystemProcessInformation, 0, 0, &dwBufferProcessSize);
dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000](); //为了防止进程/线程信息发生突变,多申请0x10000内存
LPVOID dwOldBufferProcess = dwBufferProcess; //保存缓冲区地址
NtQuerySystemInformation(SystemProcessInformation, dwBufferProcess, dwBufferProcessSize + 0x10000, &dwBufferProcessSize);
dwThreadNum = ((SYSTEM_PROCESS_INFORMATION*)dwBufferProcess)->NumberOfThreads; //线程数目
while(TRUE)
{
LPVOID dwAddress = dwBufferProcess;
dwStatus = 0;
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_PROCESS_INFORMATION);
for (DWORD i = 0; i < dwThreadNum; i++)
{
//检测进程状态和导致此状态的原因
if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
dwStatus = 0;
else
dwStatus = 1;
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION); //指向此进程的下一个线程结构
}
dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset); //指向下一个进程
if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0) //遍历完成结束
break;
}
delete[] dwOldBufferProcess; //释放内存
}
//如果进程对应的dwStatus的值为0则表示进程的所有线程都被挂起了,也就说明进程被挂起了。
NtQuerySystemInformation获取进程/线程状态的更多相关文章
- UNIX环境编程学习笔记(21)——进程管理之获取进程终止状态的 wait 和 waitpid 函数
lienhua342014-10-12 当一个进程正常或者异常终止时,内核就向其父进程发送 SIGCHLD信号.父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用的函数(信号处理程序).对于这 ...
- 获取当前线程状态--Thread类
String msgToPrint = Thread.currentThread().getStackTrace()[3] .getMethodName(); 就是调用时的方法名. 其中使用的Thre ...
- Java线程状态及切换
Java线程状态及切换 一.什么是Java线程状态 在Java程序中,用于描述Java线程的六种状态: 新建(NEW):当前线程,刚刚新建出来,尚未启动. 运行(RUNNABLE):当前线程,处于竞争 ...
- 从源码看java线程状态
关于java线程状态,网上查资料很混乱,有的说5种状态,有的说6种状态,初学者搞不清楚这个线程状态到底是怎么样的,今天我讲一下如何看源码去解决这个疑惑. 直接上代码: public class Thr ...
- C# 获取进程或线程的相关信息
信息来自: http://blog.163.com/kunkun0921@126/blog/static/169204332201293023432113/ using System; using S ...
- 获取系统中所有进程&线程信息
读书笔记--[计算机病毒解密与对抗] 目录: 遍历进程&线程程序 终止进程 获取进程信息 获取进程内模块信息 获取进程命令行参数 代码运行环境:Win7 x64 VS2012 Update3 ...
- Java 获取当前线程、进程、服务器ip
/** * 获取当前线程id */ private Long getThreadId() { try { return Thread.currentThread().getId(); } catch ...
- java线程状态和获取线程基本信息
1. 线程状态 新生状态 用 new 关键字建立一个线程后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start()方法进入就绪状态. 就绪状态 处于就绪状态线程具备了运行 ...
- 利用进程ID获取主线程ID
利用进程ID获取主线程ID,仅适用于单线程.多线程应区分哪个是主线程,区分方法待验证 (1)好像可以用StartTime最早的,不过通过线程执行时间不一定可靠,要是在最开始就CreateThread了 ...
随机推荐
- Spring笔记(三)
Spring AOP 一.AOP(概念) 1. 什么是AOP 面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了 ...
- vue+django实现websocket连接
一.概述 在项目中,需要使用websocket,来展示一些实时信息. 这里使用django 3.1.5 二.django项目 安装模块 pip3 install django-cors-headers ...
- DAOS 分布式异步对象存储|安全模型
DAOS 使用了一个灵活的安全模型,将身份验证和授权分离开来.它的设计令其对 I/O 的影响被降到最小. DAOS 对用于 I/O 传输的网络结构没有提供任何传输安全性保障.在部署 DAOS 时,管理 ...
- 懵了!女朋友突然问我MVCC实现原理
前言 都知道事务的可重复读级别实现原理是使用MVCC实现的,那么你对MVCC的底层实现原理知道多少呢?面试高频点,你值得拥有. 一.MVCC到底是什么? MVCC即多版本控制器,其特点就是在同一时间, ...
- 鸿蒙开源第三方组件——SlidingMenu_ohos侧滑菜单组件
目录: 1.前言 2.背景 3.效果展示 4.Sample解析 5.Library解析 6.<鸿蒙开源第三方组件>文章合集 前言 基于安卓平台的SlidingMenu侧滑菜单组件(http ...
- C#委托的学习了解
C#的委托(Delegate)类似于C\C++的函数指针.委托是存有对某一个方法引用的一种引用变量类型,引用可在运行时被改变. 委托特别用于实现事件和回调方法.所有的委托都派生自System.Dele ...
- C++实现控制台学生学籍管理系统
操作流程 创建文件 创建管理类 管理类负责的内容如下: 提供与用户的沟通菜单界面 实现对职工增删改查的操作 数组数据与文件的读写交互 菜单功能实现 在StudentManager.h中定义Show ...
- C语言利用for循环打印菱形
C语言利用for循环打印菱形(高度为奇数) 这次用的方法是上下部分分开打印,先打印上部分,再打印下部分. 先举个简单的例子打印,再改进代码,登堂入室从而理解. 例:打印一个高度(高度必须为奇数)为 5 ...
- Floyd算法C++实现与模板题应用
简介 Floyd算法算是最简单的算法,没有之一. 其状态转移方程如下map[i , j] =min{ map[i , k] + map[k , j] , map[i , j] }: map[i , j ...
- 现代操作系统原书第3版.mobi
电子书资源:现代操作系统原书第3版 书籍简介 本书是操作系统领域的经典之作,与第2版相比,增加了关于Linux.Windows Vista和Symbian操作系统的详细介绍.书中集中讨论了操作系统 ...