内核下枚举进程 (二)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 * ...
随机推荐
- NX二次开发-UFUN修改当前导出CGM文件选项设置UF_CGM_set_session_export_options
文章转载自唐康林NX二次开发论坛,原文出处: http://www.nxopen.cn/thread-126-1-1.html 刚才有同学问到这个问题,如果是用NXOpen来做,直接录制一下就可以了: ...
- (转)在eclipse中将android项目生成apk并且给apk签名
转:http://www.cnblogs.com/tianguook/archive/2012/09/27/2705724.html 生成apk最懒惰的方法是:只要你运行过android项目,到工作目 ...
- 牛客多校第八场 G Gemstones 栈/贪心
题意: 对于一个序列,把可以把连着三个相同的字母拿走,问最多拿走多少组. 题解: 直接模拟栈,三个栈顶元素相同则答案+1,并弹出栈 #include<bits/stdc++.h> usin ...
- NPAPI插件开发新手容易遇到的问题
在网上找了一个npdemo的例子,编译了一下在FireFox运行正常,在Chrome下就是不行,也没任何提示. 折腾了好久,最后发现是rc文件 支持语言编码问题 NPAPI插件开发详细记录:用VS20 ...
- linux网络速率监控
#!/bin/bash #作者:fafu_li #时间: #监控网卡传输速率 source /etc/profile #加载系统环境变量 source $HOME/.bash_profile #加载用 ...
- DRF的序列化组件
目录 DRF的序列化组件 Serializer组件 序列化 反序列化 ModelSerializer组件 序列化和反序列化 自定义Response方法 基表相关 DRF中ORM的多表关联操作 外键设计 ...
- 最短路(sp
#include<stdio.h> #include<iostream> #include<queue> using namespace std; #define ...
- android:两个应用之间怎样传值之activity
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zjh171/article/details/37738579 两个应用之间怎样传值.事实上这个标题太 ...
- JS事件 鼠标经过事件(onmouseover)鼠标经过事件,当鼠标移到一个对象上时,该对象就触发onmouseover事件,并执行onmouseover事件调用的程序。
鼠标经过事件(onmouseover) 鼠标经过事件,当鼠标移到一个对象上时,该对象就触发onmouseover事件,并执行onmouseover事件调用的程序. 现实鼠标经过"确定&quo ...
- git统计项目中成员代码量
查看git上个人代码量 git log --author="username" --pretty=tformat: --numstat | awk '{ add += $1; su ...