用ZwQuerySystemInformation枚举进程
很基础的一个驱动代码#include <ntddk.h>
#define SystemProcessesAndThreadsInformation 5
NTKERNELAPI NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass, // SYSTEM_INFORMATION_CLASS
IN OUT PVOID SystemInformation, //需要_SYSTEM_PROCESSES
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2;
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
} _SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;
BOOLEAN EnumProcessList()
{
ULONG cbBuffer = 0x8000; //等下开辟缓冲区的长度,先设为0x8000字节
PVOID pBuffer = NULL; //用来执行缓冲区
NTSTATUS rc; //返回值,等下获取信息的返回值放这里面
LPWSTR pszProcessName; //进程名
PSYSTEM_PROCESSES pInfo; //指向SYSTEM_PROCESSES的指针
do
{
pBuffer = ExAllocatePool (NonPagedPool, cbBuffer); //开辟内存,这里需要非分页内存
if (pBuffer == NULL)
return FALSE; //申请不成功,直接返回失败,不继续了
rc = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL);
//获取
if ( rc == STATUS_INFO_LENGTH_MISMATCH) //缓冲区不足
{
ExFreePool(pBuffer);
//缓冲区不足,则先把申请好的删掉,再把申请内存的大小扩大一倍,等下再申请
cbBuffer *= 2;
}
else if (!NT_SUCCESS(rc))
{
ExFreePool(pBuffer);
//其它错误,直接返回失败,不继续
return FALSE;
}
}while (rc == STATUS_INFO_LENGTH_MISMATCH);//直到有充足的缓冲区
//如果没有足够的缓冲区,就会接着循环,直到足够,然后获得了信息
pInfo = (PSYSTEM_PROCESSES)pBuffer;
//这时,缓冲区里就是返回来的进程信息了
while (1)
{
pszProcessName = pInfo->ProcessName.Buffer;
//获取进程名
if (pszProcessName == NULL)
{
pszProcessName = L"NULL";
//为空 则输出时也显示NULL
}
if (pInfo->ProcessId == 0)
{
DbgPrint("PID %5d System Idle Process", pInfo->ProcessId);
//PID是0,系统的
}
else
{
DbgPrint("PID %5d %ws", pInfo->ProcessId, pInfo->ProcessName.Buffer);
//输出PID和进程名
}
if (pInfo->NextEntryDelta == 0)
{
break;
//如果没有下一个就结束
}
pInfo = (PSYSTEM_PROCESSES)(((PUCHAR)pInfo) + pInfo->NextEntryDelta);
//指向下一个
}
ExFreePool(pBuffer);
//全部结束,释放内存
}
void unload(PDRIVER_OBJECT pO)
{
KdPrint(("unload\n"));
}
NTSTATUS DriverEntry( PDRIVER_OBJECT pObj , PUNICODE_STRING path)
{
pObj->DriverUnload = unload;
DbgPrint("load\n");
EnumProcessList();
//功能都在这个函数里
return 0;
} 高深的驱动
页:
[1]