内核下枚举进程 (二)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 * ...
随机推荐
- 让nginx支持patchinfo,(支持codeigniter,thinkphp,ZF等框架)
nginx 的config配置: server { listen ; server_name xxx; ....if (!-e $request_filename) { rewrite ^/(.*)$ ...
- Always On主辅延迟相关描述
延迟是AlwaysOn最大的敌人之一 延迟是AlwaysON的最大敌人之一.对AlwaysON而言,其首要目标就尽量减少(无法避免)主副本.辅助副本的数据延迟,实现主副本.辅助副本的“数据同步”.只有 ...
- 创建 Angular 8.0 项目
创建 Angular 8.0 项目,首先确保已经安装了 nodejs,如果没有安装,请看这篇文章安装:node.js 安装 1.新建一个空文件夹 angularproject,作为工作区 2.安装 A ...
- i++ 和 ++i 的区别
先说运算规则吧. i++ 是先赋值后自增:++i 是先自增后赋值. 以下是代码示例: int a=0; int b=0; int i=0; a=i++; System.out.println(&quo ...
- 剑指offer——34之字打印二叉树
题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 题解: 与上道题没区别,就是在存入数据时 ...
- Myeclipse配置tomcat和jdk
1.打开Myeclipse,Windows--preference--出现如下窗口.Browse为导入解压的tomcat路径. 2.配置jdk.使用哪个tomcat,就配置哪个tomcat下的jdk, ...
- python 16 文件操作(二)
转自 http://www.cnblogs.com/BeginMan/p/3169020.html 一.文件系统 从系统角度来看,文件系统是对文件存储器空间进行组织和分配,负责文件存储并对存入的文件进 ...
- Java基础知识之常见关键字以及概念总结
static 特点: 随着类的加载而加载 优先于对象存在 被所有对象所共享 可以直接被类名调用 使用注意: 静态方法只能访问静态成员 但是非静态成员可以直接访问静态成员 静态方法中不可用使用this, ...
- MySQL更新指定分组中最大值记录
数据表中存储着某个状态字段,当分组中所有数据入库后,需要根据相应的最大值更新状态字段,如表: 现在要将no=11的分组中把最大值记录的status更新为1,可以直接这么写: ; done~
- C++: string copy-on-write
https://blog.csdn.net/haoel/article/details/24058 https://www.cnblogs.com/promise6522/archive/2012/0 ...