首页
社区
课程
招聘
[原创]Kmd(kernel mode Driver)简单入门之谈!!
发表于: 2007-12-20 01:08 13887

[原创]Kmd(kernel mode Driver)简单入门之谈!!

2007-12-20 01:08
13887

最近一直在找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期)

收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 381
活跃值: (140)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
2
不错,写的很详细。
2007-12-20 05:03
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
3
呵呵。前阵子kanxue里面zhouzhen 大牛共享了个《汇编内核模式驱动程序设计教程》word版的。
http://bbs.pediy.com/showthread.php?t=48819
按照那里面的步骤来就不会BSOD咯~
2007-12-20 07:15
0
雪    币: 424
活跃值: (1879)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
首先我们得拥有一个win32ASm 编程环境 ,可以去下个RadAsm集成环境(还不错)!这个集成环境已经有Kmd开发所需要的一些头文件以及导入库了.


LZ搞错了吧,.inc、.lib文件不是RadASM自带的,是别人另外打包进去的(比如cao_cong打包的RadASM),汇编用的驱动开发包叫KmdKit
2007-12-20 08:43
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
支持一下!楼主加油!
2007-12-20 09:25
0
雪    币: 1919
活跃值: (901)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
支持楼主~~~
2007-12-20 12:02
0
雪    币: 290
活跃值: (11)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
7
正解 !忘记说了!
这些头是可以单独下载, 是DIY进去的!
2007-12-20 14:34
0
雪    币: 290
活跃值: (11)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
8
  我就是参考这份资料的!!!不过目前只看了几页
2007-12-20 14:42
0
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
9
搞个系统底层研究和设计算了,最近论坛搞内核的很多啊...
2007-12-20 19:33
0
雪    币: 266
活跃值: (52)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
10
支持一下

我也是感觉Kmd上手很容易,才用它的,也是刚开始学。。。

希望多多交流与分享经验和心得。。。
2007-12-22 21:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
关注,支持一下
2007-12-24 12:37
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
invoke GetFullPathName,$CTA0("kmd.sys"),sizeof acDriverPath,addr acDriverPath,esp(看了MSDN..就是这参数为什么用ESP..不懂,貌似最后的参数是路径最后一个字符的存放地址)

pop       eax ;得到当前目录全路径字符串     (POP EAX,和前面的入栈应该没用吧,句柄已经保存了,我自己做的时候 把宏和这两句去掉了  个人习惯)
.. GetFullPathName返回的是路径字符串的长度.....全路径字符串是放在acDriverPath里的
CreateService倒数第6个参数就是指向全路径字符串的指针--addr acDriverPath
2007-12-24 14:38
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
www.aogosoft.com的那个MASMPlus在用来做VXD/WDM似乎很方便。但是是“98 DDK 中的 MASM 编译器/链接器”。
2007-12-28 17:44
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
前些天刚学过罗翻译的那几篇《Kmd教程》,现在基本上都忘完了~~~
2007-12-28 18:52
0
游客
登录 | 注册 方可回帖
返回
//