1. 编译
Pspeek.cpp
#include <ntddk.h> #define DANIEL_LIST_PROCESS 0x8001 PDRIVER_OBJECT daniel_DriverObject; PDEVICE_OBJECT daniel_DeviceObject; NTSTATUS daniel_DispatchCreate( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION stackLocation; PIO_SECURITY_CONTEXT securityContext; stackLocation = IoGetCurrentIrpStackLocation(Irp); securityContext = stackLocation->Parameters.Create.SecurityContext; DbgPrint("############### "); DbgPrint("Daniel PsPeek daniel_DispatchCreate "); DbgPrint("############### "); Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS KphDispatchDeviceControl( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp ) { NTSTATUS status; PIO_STACK_LOCATION stackLocation; PVOID originalInput; ULONG inputLength; ULONG ioControlCode; KPROCESSOR_MODE accessMode; UCHAR capturedInput[16 * sizeof(ULONG_PTR)]; PVOID capturedInputPointer; stackLocation = IoGetCurrentIrpStackLocation(Irp); originalInput = stackLocation->Parameters.DeviceIoControl.Type3InputBuffer; inputLength = stackLocation->Parameters.DeviceIoControl.InputBufferLength; ioControlCode = stackLocation->Parameters.DeviceIoControl.IoControlCode; accessMode = Irp->RequestorMode; // Probe and capture the input buffer. if (accessMode != KernelMode) { __try { ProbeForRead(originalInput, inputLength, sizeof(UCHAR)); memcpy(capturedInput, originalInput, inputLength); } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); goto ControlEnd; } } else { memcpy(capturedInput, originalInput, inputLength); } capturedInputPointer = capturedInput; // avoid casting below switch (ioControlCode) { case DANIEL_LIST_PROCESS: { status = STATUS_SUCCESS; } break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } ControlEnd: Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } VOID daniel_DriverUnload( __in PDRIVER_OBJECT DriverObject ) { PAGED_CODE(); IoDeleteDevice(daniel_DeviceObject); } extern "C" NTSTATUS DriverEntry( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath) { NTSTATUS status; UNICODE_STRING deviceName; PDEVICE_OBJECT deviceObject; PAGED_CODE(); DbgPrint("############### "); DbgPrint("Daniel PsPeek DriverEntry "); DbgPrint("Current Pid: %d ", PsGetCurrentProcessId()); DbgPrint("############### "); daniel_DriverObject = DriverObject; // Create the device. RtlInitUnicodeString(&deviceName, L"\Device\DanielPsPeekDriver"); status = IoCreateDevice( DriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject ); if (!NT_SUCCESS(status)) return status; daniel_DeviceObject = deviceObject; // Set up I/O. DriverObject->MajorFunction[IRP_MJ_CREATE] = daniel_DispatchCreate; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KphDispatchDeviceControl; DriverObject->DriverUnload = daniel_DriverUnload; deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; return status; }
sources
TARGETNAME=Pspeek TARGETPATH=obj TARGETTYPE=DRIVER SOURCES=Pspeek.cpp
mk.bat
set setenv_script=D:WinDDK7600.16385.1insetenv.bat set ddk_path=D:WinDDK7600.16385.1 set config=chk set platform=x86 set os=WXP %setenv_script% %ddk_path% %config% %platform% %os% && H: && cd %cd% && build
2. 加载
ld.bat
sc stop Pspeek sc delete Pspeek copy /y "F:pspeek.sys" "C:WINDOWSsystem32pspeek.sys" sc create Pspeek binPath= "C:WINDOWSsystem32pspeek.sys" type= kernel start= auto error= ignore DisplayName= "Daniel Process Peek Driver" sc start Pspeek
在Windows 7下,需要使用"管理员权限"才能执行上述脚本。
3. 枚举进程列表
void GatherProcessListByEPROCESS() { HANDLE pid = PsGetCurrentProcessId(); DbgPrint("Current Pid: %d ", pid); PEPROCESS eprocess; PsLookupProcessByProcessId(pid, &eprocess); DbgPrint("_EPROCESS: 0x%08x ", eprocess); _LIST_ENTRY active_process_node = {0,0}; memcpy(&active_process_node, (CHAR*)eprocess + 0x88, 8); DbgPrint("Active Process List Node: [0x%08x, 0x%08x] ", active_process_node.Blink, active_process_node.Flink); DbgPrint("VirtualSize: 0x%08x ", *(ULONG*)((CHAR*)eprocess + 0xb0)); }
上面代码与WinDbg的验证一致,因此Windows下获取内核相关的数据与Linux并无太大差别。
void PProcess(char* eprocess) { DbgPrint("%16s: 0x%08x ", "_EPROCESS", eprocess); DbgPrint("%16s: %s ", "ImageName", eprocess + 0x174); DbgPrint(" "); } void GatherProcessListByEPROCESS() { HANDLE pid = PsGetCurrentProcessId(); DbgPrint("Current Pid: %d ", pid); PEPROCESS eprocess; PsLookupProcessByProcessId(pid, &eprocess); _LIST_ENTRY active_process_node = {0,0}; memcpy(&active_process_node, (CHAR*)eprocess + 0x88, 8); _LIST_ENTRY* head = active_process_node.Flink; PProcess((char*)eprocess); for (_LIST_ENTRY* cur=head; cur->Flink != head; cur = cur->Flink) { PProcess((char*)cur - 0x88); } }