内核下枚举进程 (二)ZwQuerySystemInformation
说明: SYSTEM_INFORMATION_CLASS 的5号功能枚举进程信息。其是这个函数对应着ring3下的 NtQuerySystemInformation,但msdn上说win8以后ZwQuerySystemInformation函数已经不可用,本人也没有在win8下测试过。留给读者自己实验吧。顺便罗嗦一下,不像ring3下使用此函数是要先LoadLibrary,然后GetProcAddress。内核下就简单了,直接声明一下就可以用了(就是这个宏:NTSYSAPI),下面直接附上代码:
#include <ntddk.h> #define SystemProcessesAndThreadsInformation 5 typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
} _SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; NTSTATUS EnumSystemProcess( ); NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
); NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);
NTSTATUS status = STATUS_SUCCESS;
status = EnumSystemProcess( );
return status;
} NTSTATUS EnumSystemProcess( )
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
*pRet = FALSE; PSYSTEM_PROCESSES pProcessInfo = NULL;
PSYSTEM_PROCESSES pTemp = NULL;//这个留作以后释放指针的时候用。
ULONG ulNeededSize;
ULONG ulNextOffset; if (NULL == pProcess)
{
return status;
}
//第一次使用肯定是缓冲区不够,不过本人在极少数的情况下第二次也会出现不够,所以用while循环
status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation , pProcessInfo, 0, &ulNeededSize);
while (STATUS_INFO_LENGTH_MISMATCH == status)
{
pProcessInfo = ExAllocatePoolWithTag(NonPagedPool, ulNeededSize, '1aes');
pTemp = pProcessInfo;
if (NULL == pProcessInfo)
{
KdPrint(("[allocatePoolWithTag] failed"));
return status;
}
status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation , pProcessInfo, ulNeededSize, &ulNeededSize);
}
if (NT_SUCCESS(status))
{
KdPrint(("[ZwQuerySystemInformation]success bufferSize:%x", ulNeededSize));
}
else
{
KdPrint(("[error]:++++%d", status));
return status;
} do
{
KdPrint(("[imageName Buffer]:%08x", pProcessInfo->ProcessName.Buffer)); if (MmIsAddressValid(pProcessInfo->ProcessName.Buffer) && NULL != pProcessInfo)
{
KdPrint(("[ProcessID]:%d , [imageName]:%ws", pProcessInfo->ProcessId, pProcessInfo->ProcessName.Buffer));
} ulNextOffset = pProcessInfo->NextEntryDelta;
pProcessInfo = (PSYSTEM_PROCESSES)((PUCHAR)pProcessInfo + pProcessInfo->NextEntryDelta); } while (ulNextOffset != 0); ExFreePoolWithTag(pTemp, '1aes'); return status;
}
DbgView查看输出:
分析:win7 x86下运行可得到上面的结果,从结果从可以看在进程链表中,链表的第一个节点是无效的,所以应该事先判断内存的有效性,在进行输出,当时就应为这个问题蓝屏了好多次。害的真惨!!!
后记:这里补充一下 SYSTEM_INFORMATION_CLASS 结构: typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation, //5号功能
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemNextEventIdInformation,
SystemEventIdsInformation,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
SystemPowerInformation,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; 枚举进程常用5号功能,5号功能结构对应的结构中有很多信息,包括进程Id,父进程名等重要信息,但5号功能的结构有很多种写法,
下面说一下我所知道的三种写法: 1)第一种:
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset; //下一个结构的偏移量,最后一个偏移量为0
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName; //进程名
KPRIORITY BasePriority;
HANDLE UniqueProcessId; //进程ID
HANDLE InheritedFromUniqueProcessId; //父进程ID
ULONG HandleCount;
ULONG SessionId; //会话ID
ULONG_PTR PageDirectoryBase;
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 1)第二种
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
} _SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; 3)第三种
typedef struct _SYSTEM_THREAD {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitchCount;
ULONG State;
KWAIT_REASON WaitReason;
} SYSTEM_THREAD, *PSYSTEM_THREAD;// typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset; //NextEntryDelta 构成结构序列的偏移量
ULONG NumberOfThreads; //线程数目
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime; //创建时间
LARGE_INTEGER UserTime; //用户模式(Ring 3)的CPU时间
LARGE_INTEGER KernelTime; //内核模式(Ring 0)的CPU时间
UNICODE_STRING ImageName; //进程名称
KPRIORITY BasePriority; //进程优先权
HANDLE ProcessId; //ULONG UniqueProcessId 进程标识符
HANDLE InheritedFromProcessId; //父进程的标识符
ULONG HandleCount; //句柄数目
ULONG Reserved2[2];
ULONG PrivatePageCount;
VM_COUNTERS VirtualMemoryCounters; //虚拟存储器的结构
IO_COUNTERS IoCounters; //IO计数结构
SYSTEM_THREAD Threads[1]; //进程相关线程的结构数组
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 其实这三种结构是相同的,用上面的任意一种代替5号功能的结构都可以实现枚举,本人亲自试验过,没有出现任何问题。
就看个人喜欢用哪一个了,说实话本人喜欢用第一个。
内核下枚举进程 (二)ZwQuerySystemInformation的更多相关文章
- Linux内核分析(二)----内核模块简介|简单内核模块实现
原文:Linux内核分析(二)----内核模块简介|简单内核模块实现 Linux内核分析(二) 昨天我们开始了内核的分析,网上有很多人是用用源码直接分析,这样造成的问题是,大家觉得很枯燥很难理解,从某 ...
- “Linux内核分析”实验二报告
张文俊 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.第二周学习内 ...
- 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM内核下
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(1)之执行在不同CM内核下. 文接上篇 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计&g ...
- Windows内核下操作字符串!
* Windows内核下操作字符串! */ #include <ntddk.h> #include <ntstrsafe.h> #define BUFFER_SIZE 1024 ...
- python下实现二叉堆以及堆排序
python下实现二叉堆以及堆排序 堆是一种特殊的树形结构, 堆中的数据存储满足一定的堆序.堆排序是一种选择排序, 其算法复杂度, 时间复杂度相对于其他的排序算法都有很大的优势. 堆分为大头堆和小头堆 ...
- Linux内核学习笔记二——进程
Linux内核学习笔记二——进程 一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...
- QrenCode : 命令行下生成二维码图片
对于二维码大家应该并不陌生,英文名为 2-dimensional bar code 或 QR Code,是一种用图形记载信息的技术,最常见的是应用在手机应用上.用户通过手机摄像头扫描二维码或输入二维码 ...
- QrenCode : linux命令行下生成二维码图片
原文链接:http://wowubuntu.com/qrencode.html # 作者:riku/ / 本文采用CC BY-NC-SA 2.5协议授权,转载请注明本文链接. 对于二维码大家应该并不陌 ...
- windows 内核下获取进程路径
windows 内核下获取进程路径 思路:1):在EPROCESS结构中获取.此时要用到一个导出函数:PsGetProcessImageFileName,申明如下: NTSYSAPI UCHAR * ...
随机推荐
- 2019 牛客多校第一场 E ABBA
题目链接:https://ac.nowcoder.com/acm/contest/881/E 题目大意 问有多少个由 (n + m) 个 ‘A’ 和 (n + m) 个 ‘B’,组成的字符串能被分割成 ...
- 20140403 opencv GPU安装
1. 查看本机配置,查看显卡类型是否支持NVIDIA GPU,本机显卡为NVIDIA GeForce 8400 GS: 2. 从http://www.nvidia.cn/Download/inde ...
- scala 常用模式匹配类型
模式匹配的类型 包括: 常量模式 变量模式 构造器模式 序列模式 元组模式 变量绑定模式等. 常量模式匹配 常量模式匹配,就是在模式匹配中匹配常量 objectConstantPattern{ def ...
- 如何查看jdk版本和路径
cmd进入命令提示符,查看jdk版本,输入java -version;查看jdk路径 ,输入set java home.,这个也是默认路径
- sklearn提供的自带数据集
sklearn 的数据集有好多个种 自带的小数据集(packaged dataset):sklearn.datasets.load_<name> 可在线下载的数据集(Downloaded ...
- 29-Ubuntu-远程管理命令-03-SSH工作方式简介
在Linux中SSH是非常重要的工具,通过SSH客户端可以连接到运行了SSH服务器的远程机器上. 1.SSH客户端是一种使用Secure Shell(SSH)协议连接到远程计算机的软件程序. 2.SS ...
- arm-linux-copydump 的使用
生成可以执行的 2 进制代码 [arm@localhost gcc]#armlinuxcopydump O binary hello hello.bin
- NIO教程笔记
NIO操作文件部分详解 NIO——New IO,也可以理解为非阻塞IO(Non Blocking IO).可以替代旧IO,更高效的支持读写(文件读写,网络读写).但文件操作都是阻塞的.学习NIO首先要 ...
- dex2jar+jd-gui反编译apk的使用方法
1.将要反编译的APK后缀名改为.rar或 .zip,并解压 2.得到其中的classes.dex文件(它就是java文件编译再通过dx工具打包而成的),将获取到的classes.dex放到之前解压出 ...
- windows下mysql8.0.x简单安装!
1.官网下载mysql安装包并解压到自己喜欢的目录 2.在解压的目录下,添加my.ini配置文件,内容如下:[mysqld]# 设置3306端口port=3306# 设置mysql的安装目录 下面是我 ...