首页
社区
课程
招聘
[原创]kmd驱动模拟键盘按键(masm源码)
发表于: 2008-9-17 12:26 21334

[原创]kmd驱动模拟键盘按键(masm源码)

2008-9-17 12:26
21334

驱动源码如下(每个函数及重要部份都标上了注释)

;@echo	off
;goto	make
;功能:驱动实现模拟键盘按键
;说明:模拟键盘按键就需要访问IO端口 但是系统默认是不允许访问的,所以我们利用驱动修改TSS中的IOPM(IO许可位图),允许我们的主程序访问IO端口(直接用in、out访问).
;by: 看雪--ericzw  QQ--巴丫丫 37261550
		.586
		.model	flat,stdcall
		option	casemap:none
include	\masm32\include\w2k\ntddk.inc;驱动开发必备的头文件
include	\masm32\include\w2k\ntstatus.inc;一些状态标识符
include	\masm32\include\w2k\ntoskrnl.inc;将用到ntoskrnl很多未公开的函数
includelib	\masm32\lib\w2k\ntoskrnl.lib
include	\masm32\macros\strings.mac
;字符宏 声明字符串
$s MACRO txt:REQ
	local d,sn
	sn TEXTEQU @CurSeg
 	.const
		d db txt,0
	@CurSeg ENDS
	sn SEGMENT
	EXITM <offset d>
ENDM
		.data
szUnicode	WORD 	'P','r','o','c','e','s','s','I','d',0
szUs	UNICODE_STRING	<sizeof szUnicode,sizeof	szUnicode,offset szUnicode>;这2句可以使用$COUNTED_UNICODE_STRING('ProcessId',4)宏来代替 
		.code
;驱动程序入口函数 每次驱动加截都将调用此函数
DriverEntry	proc	_lpDeriverObject:PDRIVER_OBJECT,_lpRegisterString:PUNICODE_STRING;1参:当前驱动对象指针,由系统初始化这个驱动程序时分配的DRIVER_OBJECT结构 2参:指向定长的Unicode字符串,记录该驱动在注册表中的键路径
	local	@oa:OBJECT_ATTRIBUTES
	local	@hKey;注册表句柄
	local	@kvpi:KEY_VALUE_PARTIAL_INFORMATION
	local	@lp;分配的虚拟内存指针
	local	@kProcess:PVOID;KPROCESS对象指针
	;int	3;需要调试此驱动的时候 把注释去掉,在softice里面开启捕捉int 3指令(使用“I3Here on“即可)
	
	;初始化OBJECT_ATTRIBUTES供ZwOpenKey使用(使用这几个注册表函数就是为了得到调用程序的进程ID 我们保存在注册表里面)
	lea	esi,@oa
	assume	esi:ptr OBJECT_ATTRIBUTES
	mov	[esi]._Length,sizeof OBJECT_ATTRIBUTES;结构大小 结构字段原来是Length,但汇编Length是保留字,所以定义的时候在它前面加了'_'符号
	mov	[esi].RootDirectory,NULL;根目录路径 为NULL则结构的ObjectName必须指向一个完整路径对象名称 不为NULL则ObjectName指定对象名称即可
	push	_lpRegisterString;驱动在注册表中的键路径
	pop	[esi].ObjectName;指向Unicode字符串 指示对象是由哪个句柄打开
	mov	[esi].Attributes,NULL;属性
	mov	[esi].SecurityDescriptor,NULL;指示对象安全描述 为NULL则为默认设置
	mov	[esi].SecurityQualityOfService,NULL;一般为NULL
	assume	esi:nothing
	invoke	ZwOpenKey,addr @hKey,KEY_READ,esi;打开现有注册表 参1:函数在此返回取得的注册表句柄 参2:操作权限 参3:指向已初始化的OBJECT_ATTRIBUTES
	.if	eax==STATUS_SUCCESS
		push	eax
		invoke	ZwQueryValueKey,@hKey,addr szUs,KeyValuePartialInformation,addr @kvpi,sizeof @kvpi,esp;取注册表中的键值 参1:打开的句柄 参2:定长的UNICODE_STRING字符串注册表中键的名字 参3:需要取得注册表键的值使用KeyValuePartialInformation 参4:指针指向结构KEY_VALUE_PARTIAL_INFORMATON(最终取得的值返回在结构中字段Data里面) 参5:结构大小 参6:在此返回取得的数据大小
		pop	ecx
		.if	eax==STATUS_SUCCESS && ecx!=0;函数成功 同时取得的数据不为0(ecx就是上个函数堆栈上的值pop弹出的)
			invoke	MmAllocateNonCachedMemory,8192;我们总共有8192个许可位图 所以分配1个不被cache的虚拟内存
			.if	eax
				mov	@lp,eax
				lea	ecx,@kvpi
				invoke	PsLookupProcessByProcessId,DWORD ptr (KEY_VALUE_PARTIAL_INFORMATION PTR [ecx]).Data,addr @kProcess;利用进程ID取得进程对象  参1:进程id 参2:在此处返回取得的进程对象  使用此函数会使进程对象的引用计数加1
				.if	eax==STATUS_SUCCESS
					invoke	Ke386QueryIoAccessMap,1,@lp;从TSS中取得许可位图 参1:为0将所有位置1 为1普通的拷贝  参2:虚拟内存指针 许可位图的数据返回到此指针指向的虚拟内存
					.if	al;成功al非0
						;把60 64端口都置位 注:由于IO许可位图使用的是bit位 我们正常表示都是字节 所以他们需要除8
						mov	esi,@lp
						add	esi,60h / 8 
						mov	eax,[esi]
						btr	eax, 60h mod 8;btr把指定的位清0 也就是把60h端口位设置成0 允许访问60h端口
						mov	[esi],eax
						
						mov	esi,@lp
						add	esi,64h / 8
						mov	eax,[esi]
						btr	eax,64h mod 8
						mov	[esi],eax
						invoke	Ke386SetIoAccessMap,1,@lp;拷贝新的IOPM(IO许可位图)到TSS中 参1:必须为1 参2:指向不低于2000h的虚拟内存
						.if	al;成功al非0
							invoke	Ke386IoSetAccessProcess,@kProcess,1;上面的数据拷贝进TSS后 必须使TSS中的偏移定位到新的IOPM  参1:KPROCESS进程对象  参2:为0表示禁址对I/O端口进行存取将IOPM的偏移指到TSS段外面 为1表示允许存取I/O端口
							.if	al;成功al非0
								invoke	DbgPrint,$s('driver ok...')
							.endif
						.endif
					.endif
					invoke	ObDereferenceObject,@kProcess;将对象引用计数减1
				.endif
				invoke	MmFreeNonCachedMemory,@lp,8192;释放内存
			.endif
			invoke	ZwClose,@hKey;释放句柄
		.endif
	.endif
	mov	eax,STATUS_DEVICE_CONFIGURATION_ERROR;入口函数返回值,这里将使系统返回设备配置错误,系统将直接把驱动从内存中清除
	ret
DriverEntry	endp
end		DriverEntry

:make

set drv=myDriver

\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj

del %drv%.obj

echo.
pause


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 8
支持
分享
最新回复 (25)
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
非常不错的。。。。。
2008-9-17 18:39
0
雪    币: 207
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不知道和winio有什么区别?
2008-9-18 01:45
0
雪    币: 408
活跃值: (158)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
4
winio我不太了解,刚才特意上网搜它的驱动源码看了一下,他也是使用的:void Ke386SetIoAccessMap(int, IOPM *);void Ke386QueryIoAccessMap(int, IOPM *);void Ke386IoSetAccessProcess(PEPROCESS, int);这几个来实现的,这几个函数在我上面的代码里面有。你可以看一下它们各自功能,
2008-9-18 02:02
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
5
还看不懂,先收藏了,以后学习.
2008-9-18 09:05
0
雪    币: 311
活跃值: (124)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
同上,先收藏了,以后学习.
2008-9-18 09:27
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
问一下,如果没有PS2键盘的话这个60h端口模拟的方法还能用吗?希望大家实验一下。呵呵
2008-9-18 09:59
0
雪    币: 408
活跃值: (158)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
8
呵呵。这就不太清楚。我的是笔记本试不了。。。
2008-9-18 10:36
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
多谢了,注释很多,看的明白啊!
2008-9-23 08:10
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
是个好文章:)
2008-9-23 17:50
0
雪    币: 194
活跃值: (71)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
PsLookupProcessByProcessId
Ke386QueryIoAccessMap
Ke386SetIoAccessMap
在xp 2600的ddk上找不到
要包含哪个头文件?
2008-9-23 23:17
0
雪    币: 408
活跃值: (158)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
12
这几个函数是由ntoskrnl.exe 文件导出的
2008-9-24 16:04
0
雪    币: 194
活跃值: (71)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
不是链接的时候,  是编译的时候出的错误
包含了wdm.h,包含ntddk.h也一样
系统是xp sp2, ddk版本是xp 2600
2008-9-24 22:08
0
雪    币: 194
活跃值: (71)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
知道了, 是未公开函数.
2008-9-25 00:44
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
越来越糊涂了!
SetKey    proc    _Lparamkey;
        @Lp1:;无论向0x60,还是0x64写东西前都要等状态寄存器OBF变0
        in    al,64h
        and  al,10b
        jnz  @Lp1
        ;向$64端口写命令
        mov  al,0D2h;写键盘输出缓存命令
        out  64h,al
        
        @Lp2:;无论向0x60,还是0x64写东西前都要等状态寄存器OBF变0
        in    al,64h
        and   al,10b
        jnz  @Lp2
        ;向$60端口写参数
        mov  ebx,_Lparamkey
        mov  al,bl
        out  60h,al
        ret
SetKey    endp
不是位0才是OBF的么 ?这样岂不是等IBF变0?
2008-9-27 12:35
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
好帖,这样的帖还有个样子.
多谢楼主放出来.
顶一下.
2008-12-5 10:54
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
楼主用QQ号或在网上联系方式,方便的话发一个给我lifour1980@163.com.
2008-12-5 11:00
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
请问能用于64位的XP系统吗?
2009-5-1 20:22
0
雪    币: 152
活跃值: (588)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
必须用驱动吗??为什么那些连发工具根本不加载驱动啊??
2010-2-22 19:05
0
雪    币: 12696
活跃值: (4299)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
收藏学习~~~谢谢分享源码~~
2010-2-23 04:31
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
不是吧,没钱了太郁闷了
2010-8-6 06:03
0
雪    币: 191
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
改成鼠标左键怎么改?
2010-9-30 14:20
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
win10 64bit下無法使用
2016-5-29 17:40
0
雪    币: 29
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
牛逼,大佬
2023-4-23 17:33
0
雪    币: 214
活跃值: (191)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
考古
2023-4-23 22:04
0
游客
登录 | 注册 方可回帖
返回
//