最近一直在找WMD相关的资料结果发现用VC++ DDK 包之类的要下太多东西。。于是又看到有个交KMD的驱动编程结构找了一些资料参考了下,总算知道一点步骤了!供有需要的人参考参考
kmd 是WIndows内核驱动程序,也就是底层的驱动程序!
应用程序在WINDOWS平台运行时,WINDOWS并不是把程序直接全部装入内
存中的,而是用内存分页机制先程序映射到虚拟内存中,等待需要被提交的时候才真正COPY到内存!
而在这个虚拟内存中每个程序(进程)都拥有独立的4GB寻址空间,它这4GB空间中,低2GB是给
用户级别的程序自己用的,高2GB是系统寻址空间,系统寻址空间是受保护的,只能是Ring0级的代码才能
访问在这段空间。那么我们写的这个驱动程序就拥有Ring0级的权限!
下面说下创建一个简单的kmd(kernel Mode Driver) 需要的几个步骤:
我这里就用WIN32ASM来说: ( 因为用它来写KMD最简洁!)
首先我们得拥有一个win32ASm 编程环境 ,可以去下个RadAsm集成环境(还不错)!这个集成环境已经有Kmd开发所需要的一些头文件以及导入库了.
接下可以编程了 :
1、首先新建一个.sys空的工程,它默认会选中3个文件,.asm、.inc、.bak,满足它的愿望吧我们就生成这3个文件;接下来先把一些头文件定义好,我喜欢把头文件统一定义到.inc文件:
=====================我的kmd.inc文件内容如下:====================
;kmd.inc
include e:\Program Files\RadAsm\masm32\include\w2k\ntddk.inc ;驱动开发必备的头文件
include e:\Program FIles\RadAsm\masm32\include\w2k\ntstatus.inc ;一些操作状态标识
=====================接着写kmd.asm 文件:=========================
.386
.modle flat,stdcall
option casemap:none
.code
_DriverEntry proc _pDriverObject,_pRegisterPath
;IO管理器在调用此函数时会传来 _pDriverObject 是当前驱动对象指针,由系统初始化这个驱动程序时分配的,是一个DRIVER_ODBJECT结构体。_pRegisterPath是指向一个定长的Unicode字符串,记录着该驱动在注册表的键路径!
;mov eax,STATUS_DEVICE_CONFIGURATION_ERROR ;返回设备配置错误 那么程序驱动程序什么都不做
mov eax,STATUS_SUCCESS ;返回一个驱动驻留内存标识
ret
_DriverEntry endp
end _DriverEntry
那么我一个简单驱动模块就这样写出来了 简单吧 比hello world 还简单吧!
将它编译链接最后生成了kmd.sys文件!看到了吧!这就是传说中驱动文件!
再来我们需要写一个将加载驱动文件的程序!
再新建一个win32程序吧,这次要选择win32App 工程,一切默认那么它生成了一系列文件,我们目前还是只关心app.asm 与app.inc 文件,
=============================同上先在app.inc文件里加头:===========================
;app.inc
include windows.inc ;sdk必备
include kernel32.inc ;内存管理等
include user32.inc ;用户GUI等
include advapi32.inc ;高级API
includelib kernel32.lib ;导入inc 对应的函数索引值
includelib user32.lib
includelib advapi32.lib
include E:\Program Files\RadASM\masm32\macros\Strings.mac ;这是个用来引用字符串的宏
============================app.asm 内容如下:======================================
.386
.model flat,stdcall
option casemap:none
include test.inc
.code
szActiveDatabase db "ServicesActive", 0
SERVICES_ACTIVE_DATABASE equ offset szActiveDatabase
start proc
local hSCManager:HANDLE ;SCM服务句柄
local hService:HANDLE ;驱动句柄
local acDriverPath[MAX_PATH]:byte ;驱动文件的目录路径名
;开打一个SCM服务管理句柄(SCM是服务启动与通信的管理器, SCP是与SCM通信用来启动与关闭的服务),它的第一个参数代表要打开的主机名这NULL表示本机!第二个参数是驱动服务数据库名,第三个参数是这个句柄的权限,SC_MANAGER_CREATE_SERVICE标识开打的句柄有创建驱动服务的权限
invoke OpenSCManager,NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_CREATE_SERVICE
.if !eax ;如果得到SCM句柄
mov hSCManager,eax ;保存这个SCM句柄
push eax ;开辟一个临时变量
;$CTAO 是 Strings.mac 里的宏
invoke GetFullPathName,$CTA0("kmd.sys"),sizeof acDriverPath,addr acDriverPath,esp
pop eax ;得到当前目录全路径字符串
;用刚才得到的拥有创建服务权限的SCM句柄来创建一个驱动服务 ,前三个参数分别代表 先前得到的SCM句柄、驱动在注册表中的键名、驱动服务在用户节目的名称,当函数执行成功后,这些字段可以在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 建的子键项目是kmd 下对应的键值看到对应的信息,后面的一些字段都是驱动服务的一些属性
invoke CreateService, hSCManager, $CTA0("kmd"), $CTA0("Service Test"), \
SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acDriverPath, NULL, NULL, NULL, NULL, NULL
mov hService,eax ;得到已被添加到SCM服务数据库里的一个驱动服务句柄
;现在我们可以启动这个驱动程序,启动后的一些特征是创建服务时给出的权限一一对应的!
invoke StartService,hService,NULL,NULL
;启动驱动服务后函数会一直等的驱动程序结束后才会返回!,当驱动程序处理完后我们对这个驱动程序进程卸载
invoke DeleteService,hService ;删除服务标志 这里会等的服务停止后才会删除服务
invoke CloseServiceHandle,hService ;释放驱动句柄
invoke CloseServiceHandle,hSCManager ;释放SCM句柄
invoke ExitProcess,NULL ;推出程序
.endif
start endp
end start
这就是一个简单的KMD程序了!!!!可以将app.exe与kmd.sys放在一起运行app.exe就行了!!!
再次说明一点要在拥有Administratos 权限的情况下才能注册驱动程序
运行的时候要小心哦。,因为本人刚刚不消息试了以个代码就蓝屏幕了 痛苦啊 ..
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)