首页
社区
课程
招聘
Windows内核-驱动(二)
2022-8-10 20:39 5907

Windows内核-驱动(二)

2022-8-10 20:39
5907

二、驱动

2.1.hello world

1.创建项目

2.删除Driver Files里面的helloworld.inf文件

3.右键属性

Inf2Cat->General->Run Inf2Cat 改成否
Driver Settings->General->Traget OS VERSION和Target Platform改成对应的平台
C/C++ -->常规->警告等级改为3,将警告视为错误改成否
C/C++ -->代码生成-->Spectre Mitigation改为Disabled

4.helloworld.c

#include <ntifs.h>

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
	DbgPrint("卸载驱动\r\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	pDriver->DriverUnload = DriverUnload;
	DbgPrint("加载驱动\r\n");
	DbgPrint("注册表路劲:%wZ\r\n",pReg);

	return STATUS_SUCCESS;
}

2.2.驱动基础

1.字符串函数

1.RtiInitString初始化多字节ascii
2.RtiInitUnicodestring初始化宽字符
3.RtlFreeUnicodeString释放uncode字符串
4.RtlStringCbPrintfA格式化输出记得引用#include <ntstrsafe.h
5.RtiCoipareunicodestring字特串比较

2.申请内存

ExAllocatePool   #申请内存
ExFreePool		 #释放内存	

3.创建线程

PsCreateSystemThread    #创建线程

2.3.链表

LIST_ENTRY

typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;

节点

 struct MYNODE{
	LIST_ENTRY ListEntry;
	int data;
 };

操作

InitializeListHead  初始化链表头 
IsListEmpty			判断链表是否为空 
InsertHeadList		从链表头部插入节点 
InsertTailList		从链表尾部插入节点 
RemoveHeadList		从链表头部删除节点 
RemoveTailList		从链表尾部删除节点

二叉树

#include <ntifs.h>


typedef struct _AAA 
{
	int id;
	int y;
	int x;
}AAA,*PAAA;

RTL_GENERIC_TABLE gTABLE = {0};

RTL_GENERIC_COMPARE_RESULTS NTAPI GenericCmp(
	_In_ struct _RTL_GENERIC_TABLE *Table,
	_In_ PVOID FirstStruct,
	_In_ PVOID SecondStruct
)
{
	PAAA  a1 = (PAAA)FirstStruct;
	PAAA  a2 = (PAAA)SecondStruct;
	if (a1->id == a2->id)
	{
		return GenericEqual;
	}

	if (a1->id > a2->id) return GenericGreaterThan;
	return GenericLessThan;
	
}

PVOID NTAPI GenericAllocate(
	_In_ struct _RTL_GENERIC_TABLE *Table,
	_In_ CLONG ByteSize
)
{
	return ExAllocatePool(NonPagedPool, ByteSize);
}

VOID NTAPI GenericFree(
	_In_ struct _RTL_GENERIC_TABLE *Table,
	_In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer
)
{
	ExFreePool(Buffer);
}

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	
	AAA aaa = { 1,2,3 };
	AAA aaa1 = { 2,4,5 };
	AAA aaa2 = { 3,6,7 };
	AAA aaa3 = {4,8,9};

	//初始化二叉树
	RtlInitializeGenericTable(&gTABLE, GenericCmp, GenericAllocate, GenericFree, NULL);

	
	BOOLEAN newE = FALSE;
	//插入
	RtlInsertElementGenericTable(&gTABLE, &aaa, sizeof(AAA), &newE);
	RtlInsertElementGenericTable(&gTABLE, &aaa1, sizeof(AAA), &newE);
	RtlInsertElementGenericTable(&gTABLE, &aaa2, sizeof(AAA), &newE);
	RtlInsertElementGenericTable(&gTABLE, &aaa3, sizeof(AAA), &newE);

	AAA node = {3,0,0};

	//查找
	AAA * xxx = RtlLookupElementGenericTable(&gTABLE, &node);

	//获取元素个数
	int number = RtlNumberGenericTableElements(&gTABLE);

	AAA *RestartKey = NULL;
	AAA* xx = 0;

	//判断树是否空
	if (!RtlIsGenericTableEmpty(&gTABLE))
	{
		//遍历
		for (xx = RtlEnumerateGenericTableWithoutSplaying(&gTABLE, &RestartKey);
			xx != NULL;
			xx = RtlEnumerateGenericTableWithoutSplaying(&gTABLE, &RestartKey))
		{
			DbgPrintEx(77, 0, "%x\r\n", xx->id);
		}
	}
	
	//删除
	RtlDeleteElementGenericTable(&gTABLE, &node);

	node.id = 3;
	xxx = RtlLookupElementGenericTable(&gTABLE, &node);

	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

2.4.驱动断链

断链自身

#include <ntifs.h>

typedef struct _KLDR_DATA_TABLE_ENTRY {
	LIST_ENTRY InLoadOrderLinks;
	ULONG exp;
	ULONG un;
	ULONG NonPagedDebugInfo;
	ULONG DllBase;
	ULONG EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	USHORT LoadCount;
	USHORT __Undefined5;
	ULONG  __Undefined6;
	ULONG  CheckSum;
	ULONG  TimeDateStamp;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;


NTKERNELAPI NTSTATUS ObReferenceObjectByName(
	__in PUNICODE_STRING ObjectName,
	__in ULONG Attributes,
	__in_opt PACCESS_STATE AccessState,
	__in_opt ACCESS_MASK DesiredAccess,
	__in POBJECT_TYPE ObjectType,
	__in KPROCESSOR_MODE AccessMode,
	__inout_opt PVOID ParseContext,
	__out PVOID *Object
);

extern POBJECT_TYPE* IoDriverObjectType;

void DriverHide(PWCH objName)
{
	LARGE_INTEGER in = {0};
	in.QuadPart = -10000 * 5000; //等待5s
	KeDelayExecutionThread(KernelMode,FALSE,&in);

	UNICODE_STRING driverName = { 0 };
	RtlInitUnicodeString(&driverName, objName);
	PDRIVER_OBJECT httpDriver = NULL;
	NTSTATUS status = ObReferenceObjectByName(&driverName, FILE_ALL_ACCESS, 0, 0, *IoDriverObjectType, KernelMode, NULL, httpDriver);
	if (NT_SUCCESS(status))
	{
		PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)httpDriver->DriverSection;
		DbgPrintEx(77,0,"[db]: driver name = %wZ\r\n",&ldr->FullDllName);
		RemoveEntryList(&ldr->InLoadOrderLinks);
		httpDriver->DriverInit = NULL;
		httpDriver->DriverSection = NULL;
		ObDereferenceObject(httpDriver);
	}
	return ;
}


VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
	DbgPrint("卸载驱动\r\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	HANDLE hThread = NULL;
	NTSTATUS status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, DriverHide, L"\\driver\\1.duanlian");
	if (NT_SUCCESS(status))
	{
		NtClose(hThread);
	}
    
	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
	
}

断链PCHunter32aq.sys

#include <ntifs.h>

//当系统加载一个驱动时,会为这个驱动建立一个_KLDR_DATA_TABLE_ENTRY结构体,
//DRIVER_OBJECT结构体的DriverSection成员指向这个结构体
//所有驱动的结构体通过InLoadOrderLinks成员链接起来
typedef struct _KLDR_DATA_TABLE_ENTRY {
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY exp;
	ULONG un;
	ULONG NonPagedDebugInfo;
	ULONG DllBase;
	ULONG EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	USHORT LoadCount;
	USHORT __Undefined5;
	ULONG  __Undefined6;
	ULONG  CheckSum;
	ULONG  TimeDateStamp;
} KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY;

//根据驱动名字得到驱动对象
NTKERNELAPI NTSTATUS ObReferenceObjectByName(
	__in PUNICODE_STRING ObjectName,
	__in ULONG Attributes,
	__in_opt PACCESS_STATE AccessState,// 访问权限可以写0 写0完全访问不受控制FILE_ALL_ACCESS,
	__in_opt ACCESS_MASK DesiredAccess,
	__in POBJECT_TYPE ObjectType,//对象类型
	__in KPROCESSOR_MODE AccessMode, //内核模式 有三种模式 enum 类型
	__inout_opt PVOID ParseContext,
	__out PVOID* Object     //输出对象 我们要得到的驱动对象
);

extern POBJECT_TYPE* IoDriverObjectType;

void DriverHide(PWCH objName)
{
	LARGE_INTEGER in = { 0 };
	in.QuadPart = -10000 * 5000;
	KeDelayExecutionThread(KernelMode, FALSE, &in);  //线程等待5s

	//初始化驱动名字
	UNICODE_STRING driverName = { 0 };
	RtlInitUnicodeString(&driverName, objName);

	//根据驱动名字得到驱动对象
	PDRIVER_OBJECT httpDriver = NULL;  //驱动对象
	NTSTATUS status = ObReferenceObjectByName(&driverName, FILE_ALL_ACCESS, 0, 0, *IoDriverObjectType, KernelMode, NULL, &httpDriver);

	if (NT_SUCCESS(status))
	{
		PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)httpDriver->DriverSection;
		DbgPrintEx(77, 0, "[db]: driver name = %wZ\r\n", &ldr->FullDllName);
		//断链之前把PCHunter32aq的DriverSetion指向随便一个位置,隐藏驱动的信息
		httpDriver->DriverSection = ldr->InLoadOrderLinks.Flink;
		//断链
		RemoveEntryList(&ldr->InLoadOrderLinks);
		httpDriver->DriverInit = NULL;
		//删除引用计数
		ObDereferenceObject(httpDriver);
	}
	return ;
}


VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
	DbgPrint("卸载驱动\r\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	HANDLE hThread = NULL;
	//创建系统线程
	NTSTATUS status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, DriverHide, L"\\driver\\PCHunter32aq");
	if (NT_SUCCESS(status))
	{
		NtClose(hThread);
	}

	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
	
}

2.5.驱动通信

2.5.1.IRP_MJ_DEVICE_CONTROL

驱动main.c

#include <ntifs.h>

#define DEVICE_NAME L"\\Device\\tongxin"//设备名
#define SYM_NAME    L"\\??\\tongxin"

#define CODE_CTR_INDEX 0x800   //为设备定义一个唯一标识功能号
#define TEST CTL_CODE(FILE_DEVICE_UNKNOWN,CODE_CTR_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)   //控制代码


NTSTATUS DefDispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;//通知R3,派发已成功
	IoCompleteRequest(Irp, 0);//调用方已完成所有I/O请求处理操作,并将给定的 IRP 返回给 I/O 管理器

	return STATUS_SUCCESS;
}


NTSTATUS Dispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
    //返回一个指向IO_STACK_LOCATION结构的指针
	PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
	//DbgBreakPoint();
    //判断类型是不是这个IRP_MJ_DEVICE_CONTROL
	if (ioStack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
	{

		int size = ioStack->Parameters.DeviceIoControl.InputBufferLength;
		int OutputBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;  
		ULONG IoControlCode = ioStack->Parameters.DeviceIoControl.IoControlCode;  //控制码

		switch (IoControlCode)//判断控制代码
		{
		case TEST:
		{
			int* x = (int*)Irp->AssociatedIrp.SystemBuffer;   //获取R3传过来的参数
			int y = 500;
			DbgPrint("[db]:-------%x----------\r\n", *x);
			memcpy(Irp->AssociatedIrp.SystemBuffer,&y,4);     //写数据也是在这个缓冲区
			Irp->IoStatus.Information = OutputBufferLength;
		}
		break;
		}
	}
	Irp->IoStatus.Status = STATUS_SUCCESS;//设置成功
	IoCompleteRequest(Irp, 0);
	return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);
	IoDeleteSymbolicLink(&symName);               //删除符号链接
	IoDeleteDevice(pDriver->DeviceObject);        //删除设备
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	UNICODE_STRING unName = { 0 };
	RtlInitUnicodeString(&unName, DEVICE_NAME);   //初始化设备名

	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);     //初始化符号名

	PDEVICE_OBJECT pDevice = NULL;

	//创建一个驱动设备使用的设备对象
	NTSTATUS status = IoCreateDevice(
		pDriver,                           //DriverObject,指向调用者的驱动程序对象的指针
		0,                                //指定要为设备对象的设备扩展分配的驱动程序确定的字节数
		&unName,                          // 命名设备对象
		FILE_DEVICE_UNKNOWN,              //指定设备类型的值
		FILE_DEVICE_SECURE_OPEN,         //提供有关驱动程序设备的附加信息
		FALSE,                          //指定设备对象是否代表独占设备
		&pDevice                        //指向变量的指针,该变量接收指向新创建的DEVICE_OBJECT结构的指针
	);


	if (!NT_SUCCESS(status))
	{
		DbgPrint("[db]:%x\r\n", status);
		//DbgPrintEx(77, 0, "");
		return status;
	}

	//设备名和用户的可见名之间创建符号链接
	status = IoCreateSymbolicLink(&symName, &unName);


	if (!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDevice);
		DbgPrint("[db]:%x\r\n", status);
		return status;
	}

	pDevice->Flags &= ~DO_DEVICE_INITIALIZING;  //xp系统才需要干掉这个位,win7以上系统不需要
	pDevice->Flags |= DO_BUFFERED_IO;

	pDriver->MajorFunction[IRP_MJ_CREATE] = DefDispatch;   //设置回调函数
	pDriver->MajorFunction[IRP_MJ_CLOSE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;

	pDriver->DriverUnload = DriverUnload;
	return status;
}

r3.cpp

#include <stdio.h>
#include <Windows.h>
#include <winioctl.h>

#define SYM_NAME    "\\\\.\\tongxin"   //符号名

#define CODE_CTR_INDEX 0x800   //为设备定义一个唯一标识功能号
#define TEST CTL_CODE(FILE_DEVICE_UNKNOWN,CODE_CTR_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)   //控制代码

int main()
{
	HANDLE hDevice = CreateFileA(
		SYM_NAME,								 //要创建或打开的文件或设备的名称
		GENERIC_READ | GENERIC_WRITE,			//权限
		FILE_SHARE_READ | FILE_SHARE_WRITE,    //请求的文件或设备的共享模式
		NULL, 
		OPEN_EXISTING,                         //对存在或不存在的文件或设备采取的操作。
		FILE_ATTRIBUTE_NORMAL,				  //文件或设备属性和标志,FILE_ATTRIBUTE_NORMAL是文件最常见的默认值。
		NULL
	);

	int x = 100;
	int y = 0;
	DWORD p = 0;

	BOOL  b = DeviceIoControl(
		hDevice,				//要在其上执行操作的设备的句柄
		TEST,				   //操作的控制代码
		&x,					  //指向包含执行操作所需数据的输入缓冲区的指针
		4,                   //输入缓冲区的大小
		&y,                 //指向输出缓冲区的指针
		4,                 //输出缓冲区的大小
		&p,                //一个指向变量的指针
		NULL
	);     


	CloseHandle(hDevice);
	printf("%d\r\n", y);
	system("pause");
	return 0;
}

测试

先运行驱动,然后运行r3程序,可以看到y值改为500

2.5.2.IRP_MJ_READ

驱动main.c

#include <ntifs.h>

#define DEVICE_NAME L"\\Device\\tongxin"
#define SYM_NAME    L"\\??\\tongxin"


NTSTATUS DefDispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, 0);

	return STATUS_SUCCESS;
}

NTSTATUS ReadDispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
	DbgBreakPoint();
	PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
	LARGE_INTEGER ByteOffset = ioStack->Parameters.Read.ByteOffset;
	int Length = ioStack->Parameters.Read.Length;
	int* xxx = Irp->AssociatedIrp.SystemBuffer;
	*xxx = 100;
	Irp->IoStatus.Information = Length;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, 0);
	return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);
	IoDeleteSymbolicLink(&symName);
	IoDeleteDevice(pDriver->DeviceObject);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	UNICODE_STRING unName = { 0 };
	RtlInitUnicodeString(&unName, DEVICE_NAME);

	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);

	PDEVICE_OBJECT pDevice = NULL;

	NTSTATUS status = IoCreateDevice(pDriver, 0, &unName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevice);

	if (!NT_SUCCESS(status))
	{
		DbgPrint("[db]:%x\r\n", status);

		return status;
	}

	status = IoCreateSymbolicLink(&symName, &unName);


	if (!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDevice);
		DbgPrint("[db]:%x\r\n", status);
		return status;
	}

	pDevice->Flags &= ~DO_DEVICE_INITIALIZING;
	pDevice->Flags |= DO_BUFFERED_IO;

	pDriver->MajorFunction[IRP_MJ_CREATE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_CLOSE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_READ] = ReadDispatch;

	pDriver->DriverUnload = DriverUnload;
	return status;
}

r3.cpp

#include <stdio.h>
#include <Windows.h>
#include <winioctl.h>

#define SYM_NAME    "\\\\.\\tongxin"

int main()
{
	HANDLE hDevice = CreateFileA(SYM_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	int x = 500;
	DWORD p = 0;

	ReadFile(hDevice, &x, 4, &p, NULL); 

	CloseHandle(hDevice);
	printf("%d\r\n", x);
	system("pause");
	return 0;
}

测试

先运行驱动,然后运行r3程序,可以看到x值改为500

2.6.通信封装

驱动main.c

#include <ntifs.h>
#include <Windowsx.h>

#define DEVICE_NAME L"\\Device\\tongxinfz"
#define SYM_NAME    L"\\??\\tongxinfz"

#define _COMM_ID	0x12345678//设定一个ID进行对比

typedef struct _CommPackage
{
	ULONG64 id;
	ULONG64 code;
	ULONG64 inData;
	ULONG64 inLen;
	ULONG64 outData;
	ULONG64 outLen;
}CommPackage, * PCommPackage;//自己创建一个包,用于通信

typedef NTSTATUS(NTAPI* CommCallback)(PCommPackage package);//定义了一个结构体指针

CommCallback gCommCallback = NULL;//创建一个新的结构体

typedef struct _Test
{
	int x;
}Test, * PTest;

typedef enum _CMD//枚举
{
	TEST = 0,
}CMD;

VOID DriverDestoryComm(PDRIVER_OBJECT  pDriver)
{
	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);
	IoDeleteSymbolicLink(&symName);
	if (pDriver->DeviceObject) IoDeleteDevice(pDriver->DeviceObject);
}//销毁符号链接和设备链接	

NTSTATUS DefDispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, 0);
	return STATUS_SUCCESS;
}

NTSTATUS WriteDispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
	DbgBreakPoint();
	PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);//返回一个指向IO_STACK_LOCATION结构的指针
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	int Length = ioStack->Parameters.Write.Length;//要写入的数据长度
	if (Length == sizeof(CommPackage) && gCommCallback)//判断这个包是否存在
	{
		PCommPackage package = Irp->AssociatedIrp.SystemBuffer;
		if (package->id == _COMM_ID)//对比ID是不是一样的
			if (MmIsAddressValid(package)) status = gCommCallback(package);
	}

	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = status;//完成写入
	IoCompleteRequest(Irp, 0);
	return status;
}

NTSTATUS NTAPI Dispatch(PCommPackage package)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	switch (package->code)//再来根据编号选择执行不同的指令
	{
	case TEST:
	{
		PTest t = (PTest)package->inData;
		t->x = 200;
		DbgPrintEx(77, 0, "[db]:%d\r\n", t->x);//观察是否成功写入
		status = STATUS_SUCCESS;
	}
	break;
	}

	return status;
}

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	DriverDestoryComm(pDriver);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {
	UNICODE_STRING unName = { 0 };
	UNICODE_STRING symName = { 0 };

	RtlInitUnicodeString(&unName, DEVICE_NAME);
	RtlInitUnicodeString(&symName, SYM_NAME);

	PDEVICE_OBJECT pDevice = NULL;

	NTSTATUS status = IoCreateDevice(pDriver, 0, &unName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevice);

	if (!NT_SUCCESS(status)) {
		KdPrintEx((77, 0, "[db]:%x\r\n", status));
		return status;
	}

	status = IoCreateSymbolicLink(&symName, &unName);

	if (!NT_SUCCESS(status)) {
		IoDeleteDevice(pDevice);
		KdPrintEx((77, 0, "[db]:%x\r\n", status));
	}

	pDevice->Flags &= ~DO_DEVICE_INITIALIZING;
	pDevice->Flags |= DO_BUFFERED_IO;

	pDriver->MajorFunction[IRP_MJ_CREATE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_CLOSE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_WRITE] = WriteDispatch;//与之前的过程相仿

	if (NT_SUCCESS(status))
	{
		gCommCallback = Dispatch;
	}

	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

r3.cpp


#include "stdio.h"
#include <Windows.h>

HANDLE ghDevice;
#define SYM_NAME    L"\\??\\tongxinfz"
typedef struct _CommPackage
{
	ULONG64 id;
	ULONG64 code;
	ULONG64 inData;
	ULONG64 inLen;
	ULONG64 outData;
	ULONG64 outLen;
}CommPackage, * PCommPackage;
#define _COMM_ID	0x12345678

typedef struct _Test
{
	int x;
}Test, * PTest;

typedef enum _CMD
{
	TEST = 0,
}CMD;

int main()
{

	Test x1 = { 0 };
	x1.x = 100;

	ghDevice = CreateFileW(SYM_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (ghDevice == NULL || ghDevice == INVALID_HANDLE_VALUE)
	{
		ghDevice = NULL;
		return 0;
	}

	CommPackage packag;
	packag.code = TEST;
	packag.inData = (ULONG64)&x1;
	packag.inLen = (ULONG64)4;
	packag.outData = (ULONG64)NULL;
	packag.outLen = (ULONG64)NULL;
	DWORD pro = NULL;
	packag.id = _COMM_ID;//构造结构体

	WriteFile(ghDevice, &packag, sizeof(CommPackage), &pro, NULL);
	printf("%d\r\n", x1.x);
	system("pause");
	return 0;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-9-9 10:57 被zhang_derek编辑 ,原因:
收藏
点赞13
打赏
分享
最新回复 (3)
雪    币: 2129
活跃值: (1611)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
goldli 2022-8-11 09:17
2
0
收藏了。
雪    币: 2590
活跃值: (1957)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wbzloveme 2022-8-11 14:15
3
0
来收藏下
雪    币: 229
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
heye123 2022-8-17 00:10
4
0
收藏
游客
登录 | 注册 方可回帖
返回