5.驱动主动通知应用程序和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 文件即可

你可能感兴趣的:(5.驱动主动通知应用程序和64位和32位内核的开发区别)