• 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("###############
    ");
    	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);
    	}
    }
    

      

      

  • 相关阅读:
    vue keep-alive的使用
    vscode 快捷键整理
    form表单的验证validator如何传递参数
    使用elementui 的validateField,resetFields,clearValidate的使用
    vue sass样式穿透实现
    部署node服务(在本地模拟环境进行部署)
    利用存css实现弧形边界
    koa mongoose 实践篇,各种必要的功能总结;
    koa mogoose 创建后台服务连接数据库并进行增删改查
    vue项目中 render函数直接操作html元素报错
  • 原文地址:https://www.cnblogs.com/long123king/p/3860830.html
Copyright © 2020-2023  润新知