__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. Aibabelx-shop 大型微服务架构系列实战之技术选型

    一.本项目涉及编程语言java,scala,python,涉及的技术如下: 1.微服务架构: springboot springcloud mybatisplus shiro 2.全文检索技术 sol ...

  2. 为 .NET 打 Call,为国产平台 Gitee 打 Call,我的 .NET/C# 开源项目清单,同步维护于 Github 和 Gitee

    所有项目遵循 MIT 开源协议.可以随意使用,但是需在源代码和产品关于画面保留版权声明和我的网站链接,谢谢. Sheng.Winform.IDE Github:https://github.com/i ...

  3. Linux 用户登陆提示This account is currently not available

    使用 su 切换到用户 hdfs 时提示:This account is currently not available,使用 hdfs 用户登陆会直接退出 ssh 窗口. 此时可以尝试检查文件 /e ...

  4. 打造云原生大型分布式监控系统系列文章-腾讯工程师roc

    附上本系列文章链接 打造云原生大型分布式监控系统(一): 大规模场景下 Prometheus 的优化手段 打造云原生大型分布式监控系统(二): Thanos 架构详解 打造云原生大型分布式监控系统(二 ...

  5. SqlServer游标的创建与使用

    前言 大家都对SqlServer视图.存储过程.触发器的创建与使用有一定的了解了,我们来看下什么是游标,怎么使用,什么时候用. SqlServer视图的创建与使用 SqlServer存储过程的创建与使 ...

  6. 设计Web页面(2)

    1.前面我们新建了一个空白的ASP.NET网页,那么接下来这章我们就讲一下设计Web页面 2.布局页面有两种方法,一种是通过Table表格来布局页面窗体,另一种是通过CSS+DIV来布局窗体,其中作为 ...

  7. spieces-in-pieces动画编辑器

    前言: 制作灵感来源于 http://species-in-pieces.com/ 这个网站,此网站作者是来自阿姆斯特丹的设计师 Bryan James,其借用纯CSS技术表现出30种濒危动物的碎片拼 ...

  8. JAVAEE_Servlet_23_路径编写总结和url_pattern的编写方式

    路径编写总结和url_pattern的编写方式 路径的编写 超链接 form表单的action属性 重定向 response.sendRedirect("/项目名/资源路径"): ...

  9. Spring Cloud Alibaba(3)---Nacos概述

    Spring Cloud Alibaba(3)---nacos概述 上一篇博客讲了有关 SpringCloudAlibaba的概述,这篇开始讲SpringCloudAlibaba组件之一---Naco ...

  10. NetCore去注册Eureka

    首先先安装nuget组件:Steeltoe.Discovery.ClientCore 然后在ConfigureServices中进行注入 services.AddDiscoveryClient(Con ...