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了 ...
随机推荐
- Oracle dg下掉一个从库
1.在数据库中查找要下线的从库 SQL> show parameter log_archive_dest NAME TYPE VALUE----------------------------- ...
- C++如何解析函数调用
C语言是一个简单的语言.用户针对每一个函数,只能设置一个唯一的函数签名.但是C++而言,就给了我们很多的灵活性: 你可以将多个函数设置为相同的名字(overloading) 你可以使用内置操作符重载( ...
- 比Django官方实现更好的分页组件+Bootstrap整合
前言 Django全家桶自带的分页组件只能说能满足分页这个功能,但是没那么好用就是了 Django的分页效果 django-pure-pagination分页效果 使用方法 首先安装: pip ins ...
- iovec结构体使用说明
http://blog.163.com/lichuan0502@126/blog/static/9933534820111033228285/
- 扩展中国剩余定理(EXCRT)学习笔记
扩展中国剩余定理(EXCRT)学习笔记 用途 求解同余方程组 \(\begin{cases}x\equiv c_{1}\left( mod\ m_{1}\right) \\ x\equiv c_{2} ...
- JMeter元件作用域实践指南
从一个问题说起 对于以下测试脚本: 为了能调用进入房间接口,需要从考场接口获取考场token.为了调用考场接口,需要从登陆接口获取登陆token.元件说明如下: 学生登录,提取登录${token}传入 ...
- Windows安装完ADFS后卸载ADFS清除ADFS数据库
ADFS卸载后不会卸载掉之前ADFS配置后留下来的数据库,所以如果有必要去删掉这个数据库的话需要找到对应的路径去将数据库删除掉. 具体路径为C:/windows/wid/data/adfsartifa ...
- 北航OO第一单元作业总结(1.1~1.3)
经过了三次作业之后,OO第一单元告一段落,作为一个蒟蒻,我初步了解了面向对象的编程思想,并将所学内容用于实践. 一.第一次作业 1.架构分析 本次作业需要完成的任务为简单多项式导函数的求解.表达式仅支 ...
- 基于gitlab的项目管理流程
框架 背景 个人是不太愿意使用用户体验差的软件来做项目管理,行业内,要找到这么一款软件,又要符合自己的需求,着实不容易.要免费,易用性要好,要安全,要有数据统计.而程序员的世界,SVN 之后,可能没有 ...
- 算法很美,听我讲完这些Java经典算法包你爱上她
大家好,我是小羽. 对于编程来说的话,只有掌握了算法才是了解了编程的灵魂,算法对于新手来说的话,属实有点难度,但是以后想有更好的发展,得到更好的进阶的话,对算法进行系统的学习是重中之重的. 对于 Ja ...