Windows编写driver

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("###############\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=Pspeek
TARGETPATH=obj
TARGETTYPE=DRIVER

SOURCES=Pspeek.cpp

  

 mk.bat

set setenv_script=D:\WinDDK\7600.16385.1\bin\setenv.bat
set ddk_path=D:\WinDDK\7600.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:\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

  

在Windows 7下,需要使用"管理员权限"才能执行上述脚本。

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并无太大差别。

 

 

void PProcess(char* eprocess)
{
	DbgPrint("%16s: 0x%08x\n", "_EPROCESS", eprocess);
	DbgPrint("%16s: %s\n", "ImageName", eprocess + 0x174);

	DbgPrint("\n");
}

void GatherProcessListByEPROCESS()
{
	HANDLE pid = PsGetCurrentProcessId();
	DbgPrint("Current Pid: %d\n", 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);
	}
}

  

  

posted @ 2014-07-23 15:10  Daniel King  阅读(422)  评论(0编辑  收藏  举报