驱动主动通知应用程序和64位和32位内核的开发区别

其实是应用程序使用 DeviceIoControl 发送请求,内核使用独享的同步事件(KEVENT)来等待.

 

当内核想发送数据给应用程序时就设置事件即可.

 

在应用程序中因为要等待 DeviceIoControl 函数的返回,所以应用程序应该新开一个线程来做这件事情.

 

内核中的缓冲区链表结构

 

内核使用一个 双向链表 来保存已经输入的字符串

 

应用层取 字符串 时, 每次返回一个并从链表中删除 保证先入显出的顺序,就向专门原来传递长度小于 512 字节的字符串的管道一样,双向链表使用 LIST_ENTRY

 

//定义一个列表原来保存字符串

 

#define CWK_STR_LEN_MAX 512

 

typedef struct {

 

LIST_ENTRY list_entry;

 

char buf[CWK_STR_LEN_MAX];

 

} CWK_STR_NODE;

 

//自旋锁保证链表操作的安全

 

KSPIN_LOCK g_cwk_lock;

 

//事件标识是否有字符串可以取

 

KEVENT g_cwk_event;

 

//必须的链表头

 

LIST_ENTRY g_cwk_str_list;

 

//分配内存并初始化一个链表节点

 

CWK_STR_NODE *cwkMallocStrNode(){

 

CWK_STR_NODE *ret = ExAllocatePoolWithTag(NonPagePool,sizeof(CWK_STR_NODE),MEM_TAG);

 

if(ret == NULL){

 

return NULL;

 

}

 

return ret;

 

}

 

//分配节点

 

str_node = cwkMallocStrNode();

 

if(str_node == NULL){

 

status = 资源不足...

 

break;

 

}

 

//拷贝字符串

 

strncpy(str_node->buf,(char *)buffer,CWK_STR_LEN_MAX);

 

//新的字符串插入到链表末尾

 

ExInterlockedInsertTailList(&g_cwk_str_list,(PLIST_ENTRY)str_node,&g_cwk_lock);

 

//设置事件

 

KeSetEvent(&g_cwk_event,0,TRUE);

 

//释放 ExFreePool

 

使用 while 循环来判断链表是否有数据

 

使用等待事件来改善CPU的占用,用睡眠也可以

 

注意使用过的内存需要释放

 

64位和32位内核开发的差异

 

64位系统新增机制 - WOW64 子系统

 

该子系统是为了兼容32位应用程序的,是一个轻量级的兼容层

 

主要由3个DLL实现,分配是 Wow64.dll Wow64Win.dll Wow64Cpu.dll

 

当一个32位应用程序发起系统调用,WoW64子系统拦截到系统调用,如果调用参数包涵指针,子系统就会把指针长度转换成合适的长度,然后再把请求提交给内核.

 

WOW64子系统有两个只要模块,分别是文件系统重定向器模块和注册表重定向器模块

 

windows 64位系统有两个 system32 目录,分别是 %windir%\System32 和 %windir%\SysWOW64

 

前者主要包含64位系统二进制文件,后者只要包涵32位系统二进制文件

 

不同位数的应用程序需要调用不同的系统DLL,如果是32位应用程序 WOW64子系统会对 System32目录做透明重定向 到 %windir%SysWOW64(绝大多数情况下)

 

例如:

HANDLE hFile = CreateFile(_T("C:\\windows\\system32\\testfile.txt"),



GENERIC_READ,0,NULL,CREATE_ALWAYS,0,NULL);



if(hFile != INVALID_HANDLE_VALUE){



CloseHandle(hFile);



hFile = INVALID_HANDLE_VALUE;



}

 

这个程序如果编译成32位程序,会在 SysWOW64 目录下生成文件.如果是64位程序,则在 System32 下生成

 

可以调用系统API来关闭重定向

 

BOOL WINAPI Wow64DisableWow64FsRedirection(_Out_ PVOID *Oldvalue); //参数用来保存原来的重定向状态

 

恢复重定向使用 Oldvalue 这个参数

 

BOOL WINAPI Wow64RevertWow64FsRedirection(_In_ PVOID Oldvalue);

 

并不是所有的 %windir%System32 下目录和文件都会重定向,一些特殊目录是不重定向的

 

%windir%\System32\catroot

 

%windir%\System32\catroot2

 

%windir%\System32\drivers\etc

 

%windir%\System32\logfiles

 

%windir%\System32\spool

 

注册表重定向器和文件系统重定向器类型,但功能更复杂,除了提供重定向功能外,还提供注册表反射功能

 

HKEY_LOCAL_MACHINE\SOFTWARE --> HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node

 

PatchGuard 技术

 

对于32位系统来说,驱动程序可以对内核的数据结构和关键函数进行挂钩和修改,但是在64位系统不再适用,因为微软在64位系统中引入了 PatchGuard(安全内核) 机制,这个机制会定时检查系统关键位置,如 SSDT(系统服务描述表) GDT(全局描述表) IDT(中断描述表) 系统模块(ntoskrnl.exe hal.sys 等) 一旦发现这些关机位置的数据或代码给篡改,系统就会触发蓝屏(BSOD),例如 SSDT HOOK INLINE HOOK IDT HOOK 等技术都不能在64位下使用(大概),然而并没有什么软用

 

注意32位应用程序加载64位驱动需要先关闭文件重定向

 

驱动文件在64位系统需要签名才能被加载,可以选择 禁用驱动签名 模式进入系统

 

64位驱动不在允许内嵌汇编,可以把汇编代码写成函数放到一个单独的asm文件中,然后通过函数的方式调用

 

Sources 文件中指定 asm 文件即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值