应用层和内核层通信

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在看Windows内核安全与驱动开发,总结了一些东西,主要介绍一些自旋锁,事件,链表相关的东西。</span>

LIST_ENTRY一个双向链表,在Windows中经常使用。在使用时只需在结构体中插入一个LIST_ENTRY结构,位置无所谓(最好在前面)。比如:

typedef	struct	{
	LIST_ENTRY	list_entry;
	UNICODE_STRING	file_name;
}MY_LIST_TEST;

在使用之前需要调用InitializeListHead来初始化:

#define	MEM_TAG  'test'
LIST_ENTRY my_list_head; 		//链表头(注意不是自己定义的链表结构体)
InitializeListHead(&my_list_head);	//初始化
MY_LIST_TEST *my_first_list = ExAllocatePoolWithTag(NonPagedPool, sizeof(CWK_STR_NODE), MEM_TAG);	//申请空间
my_first_list->file_name = .....	//填写数据成员
InsertHeadList(&my_list_head,(PLIST_ENTRY)&my_first_list); 	//添加节点


这样做非常不安全,因为多线程的情况下操作同一个链表会破坏这个链表,这个时候就要引进自旋锁的概念。使用自旋锁首先要初始化一个自旋锁:

KSPIN_LOCK g_cwk_lock;	
KeInitializeSpinLock(&g_cwk_lock);	//初始化一个自旋锁
ExInterlockedInsertHeadList(&my_list_head, (PLIST_ENTRY)&my_first_list, &g_cwk_lock);	//添加节点 并进行加锁
my_first_list = ExInterlockedRemoveHeadList(&my_list_first, &g_cwk_lock);	//移除一个节点 并返回到my_first_list中


下面说一下同步事件,当一个地方需要等待另一个事件完成后才能继续进行时需要设置同步事件,同步事件数据结构是KEVENT

 
KEVENT event;	//定义一个事件
KeInitializeEvent(&event,SynchronizationEvent,TRUE); //事件初始化
......
//这里设置事件等待,如果这个事件没有被设置,那么会一直在这里等待
KeWaitForSingleObject(&_event,Executive,KernelMode,0,0);
......
//这理设置事件,只有这里执行完了以后,上面的等待才能放行,去执行后续流程
KeSetEvent(&_event, 0, TRUE);


要实现用户层和内核层的通信,首先要生成一个设备对象,在驱动开发中设备对象和分发函数构成了整个内核体系的基本框架。生成设备可以使用函数IoCreateDevice函数,

NTSTATUS IoCreateDevice
(
IN PDRIVER_OBJECT DriverObject,		//从DriverEntry的参数获得
IN ULONG DeviceExtensionSize,		//设备扩展大小
IN PUNICODE_STRING DeviceName OPTIONAL,	//设备名
IN DEVICE_TYPE DeviceType,		//设备类型
IN ULONG DeviceCharacteristics,		//设备属性
IN BOOLEAN Exclusive,			//表示是否是一个独占设备
OUT PDEVICE_OBJECT *DeviceObject	//返回成成的设备对象指针
);


但是这个生成的设备具有默认的安全属性,必须用管理员权限的进程才能打开,当用户是普通用户就没办法打开,所以使用IoCreateDeviceSecure函数创建设备
NTSTATUS IoCreateDeviceSecure
(
IN PDRIVER_OBJECT DriverObject,		//从DriverEntry的参数获得
IN ULONG DeviceExtensionSize,		//设备扩展大小
IN PUNICODE_STRING DeviceName OPTIONAL,	//设备名
IN DEVICE_TYPE DeviceType,		//设备类型
IN ULONG DeviceCharacteristics,		//设备属性
IN BOOLEAN Exclusive,			//表示是否是一个独占设备
IN PUCNICODE_STRING DefaultSDDLString,	//设置设备安全
IN LPCGUID DeviceClassGuid,		//微软提供CoCreateGuid生成,第一次生成就一直使用,不要每次启动都生成一个新的
OUT PDEVICE_OBJECT *DeviceObject	//返回成成的设备对象指针
);
可以发现只有两个地方不一样,其中DefaultSDDLString这个参数传入L"D:P(A;;GA;;;WD)"即表示允许任何用户访问该设备的万能安全设置字符串,使用如下:
//全局参数
PDEVICE_OBJECT g_cdo = NULL;
const GUID  CWK_GUID_CLASS_MYCDO = {0x17a0d1e0L, 0x3249, 0x12e1, {0x92,0x16, 0x45, 0x1a, 0x21, 0x30, 0x29, 0x06}};//GUID
//......
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg_path){
	UNICODE_STRING sddl = RTL_CONSTANT_STRING(L"D:P(A;;GA;;;WD)"); 
	UNICODE_STRING cdo_name = RTL_CONSTANT_STRING(L"\\Device\\cwk_3948d33e"); //设备名
	IoCreateDevic
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值