首页 > 代码库 > Windows编写driver

Windows编写driver

1. 编译

Pspeek.cpp

#include <ntddk.h>#define DANIEL_LIST_PROCESS 0x8001PDRIVER_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("###############\n");	DbgPrint("Daniel PsPeek daniel_DispatchCreate\n");	DbgPrint("###############\n");	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("###############\n");	DbgPrint("Daniel PsPeek DriverEntry\n");		DbgPrint("Current Pid: %d\n", PsGetCurrentProcessId());	DbgPrint("###############\n");	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=PspeekTARGETPATH=objTARGETTYPE=DRIVERSOURCES=Pspeek.cpp

  

 mk.bat

set setenv_script=D:\WinDDK\7600.16385.1\bin\setenv.batset ddk_path=D:\WinDDK\7600.16385.1set config=chkset platform=x86set os=WXP%setenv_script% %ddk_path% %config% %platform% %os% && H: && cd %cd% && build

  

2. 加载

ld.bat

sc stop Pspeeksc delete Pspeekcopy /y "F:\pspeek.sys" "C:\WINDOWS\system32\pspeek.sys"sc create Pspeek binPath= "C:\WINDOWS\system32\pspeek.sys" type= kernel start= auto error= ignore DisplayName= "Daniel Process Peek Driver"sc start Pspeek

  

3. 枚举进程列表

void GatherProcessListByEPROCESS(){	HANDLE pid = PsGetCurrentProcessId();	DbgPrint("Current Pid: %d\n", pid);	PEPROCESS eprocess;	PsLookupProcessByProcessId(pid, &eprocess);	DbgPrint("_EPROCESS: 0x%08x\n", 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]\n", active_process_node.Blink, active_process_node.Flink);	DbgPrint("VirtualSize: 0x%08x \n", *(ULONG*)((CHAR*)eprocess + 0xb0));}

  

 上面代码与WinDbg的验证一致,因此Windows下获取内核相关的数据与Linux并无太大差别。