__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获取进程/线程状态的更多相关文章

  1. UNIX环境编程学习笔记(21)——进程管理之获取进程终止状态的 wait 和 waitpid 函数

    lienhua342014-10-12 当一个进程正常或者异常终止时,内核就向其父进程发送 SIGCHLD信号.父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用的函数(信号处理程序).对于这 ...

  2. 获取当前线程状态--Thread类

    String msgToPrint = Thread.currentThread().getStackTrace()[3] .getMethodName(); 就是调用时的方法名. 其中使用的Thre ...

  3. Java线程状态及切换

    Java线程状态及切换 一.什么是Java线程状态 在Java程序中,用于描述Java线程的六种状态: 新建(NEW):当前线程,刚刚新建出来,尚未启动. 运行(RUNNABLE):当前线程,处于竞争 ...

  4. 从源码看java线程状态

    关于java线程状态,网上查资料很混乱,有的说5种状态,有的说6种状态,初学者搞不清楚这个线程状态到底是怎么样的,今天我讲一下如何看源码去解决这个疑惑. 直接上代码: public class Thr ...

  5. C# 获取进程或线程的相关信息

    信息来自: http://blog.163.com/kunkun0921@126/blog/static/169204332201293023432113/ using System; using S ...

  6. 获取系统中所有进程&线程信息

    读书笔记--[计算机病毒解密与对抗] 目录: 遍历进程&线程程序 终止进程 获取进程信息 获取进程内模块信息 获取进程命令行参数 代码运行环境:Win7 x64 VS2012 Update3 ...

  7. Java 获取当前线程、进程、服务器ip

    /** * 获取当前线程id */ private Long getThreadId() { try { return Thread.currentThread().getId(); } catch ...

  8. java线程状态和获取线程基本信息

    1. 线程状态 新生状态 用 new 关键字建立一个线程后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start()方法进入就绪状态. 就绪状态 处于就绪状态线程具备了运行 ...

  9. 利用进程ID获取主线程ID

    利用进程ID获取主线程ID,仅适用于单线程.多线程应区分哪个是主线程,区分方法待验证 (1)好像可以用StartTime最早的,不过通过线程执行时间不一定可靠,要是在最开始就CreateThread了 ...

随机推荐

  1. 练习1—参数传递、递归调用(Java)

    1.方法参数的值传递机制 1.说明 方法:必须由其所在类或对象调用才有意义.若方法含有参数: 形参:方法声明时的参数: 实参:方法调用时实际传给形参的参数值 Java的实参值如何传入方法:Java里方 ...

  2. x86汇编 条件跳转

    条件跳转表 汇编语言-条件跳转指令 直接转移指令 指令格式 机器码 测试标志 条件说明 符号  JO       OPR 70  OF=1  结果有溢出    JNO      OPR 71  OF= ...

  3. Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇(内附开发 demo)

    简介 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. 系列 云原生 API 网关,gRPC-Gateway V2 初探 业务流程 官方开发接入文档 ...

  4. 前端er必须知道的Git地址及常用工具地址

    商城篇(找工作必练) 开源商城 推荐指数:5星,掌握了它,可以说,今后工作中的各种需求都不是问题,工作1~2年的也可以学习其中的思路(建议收藏). 这是一个集小程序/公众号/app为一体的商城系统,包 ...

  5. ADFS修改默认访问端口

    在安装Dynamics CRM部署IFD需要安装ADFS来进行身份验证.而ADFS默认会占用服务器的443端口.如果我们想自己使用443端口的话则需要修改ADFS的默认端口.(如果需要部署移动端的话还 ...

  6. OO_Unit3_Summary

    JML这一单元是真的有含金量,很有难度.而且这难点和前两单元完全不同,前两单元是容易架构混乱导致细节出问题,JML单元是读不懂JML规格的话架构都构不出来,以及即使能够读懂JML规格了,让自己写规格的 ...

  7. python进阶(3)--条件判断、用户输入

    文档目录: 一.if语句二.检索条件三.用户输入input四.while+inoput(),让用户选择何时退出五.break与continue六.while循环处理字典和列表 ------------ ...

  8. Mediapipe 在RK3399PRO上的初探(一)(编译、运行CPU和GPU Demo, RK OpenglES 填坑,编译bazel)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  9. 2020.1 PyCharm 激活

    1 下载安装 平台windows,官网: 选路径后, 选项分别是64位的快捷方式,添加运行目录到环境变量PATH,添加右键菜单"打开文件夹作为一个工程",python文件关联,按需 ...

  10. 【Azure Developer】使用Java SDK代码创建Azure VM (包含设置NSG,及添加数据磁盘SSD)

    在参考Azure官方文档进行VM创建时,发现其中没有包含如何设置NSG的内容,以及如何在创建时就添加数据磁盘的代码(设置磁盘为SSD类型).本文的内容以"使用 Java 创建和管理 Azur ...