首页
社区
课程
招聘
[求助]驱动里面有没有办法直接取得键盘状态?
发表于: 2009-4-13 17:07 7380

[求助]驱动里面有没有办法直接取得键盘状态?

2009-4-13 17:07
7380
ring3下面GetKeyboardState可以得到当前的键盘状态,而这个函数最终还是sysenter进ring0去取键盘信息的?那么ring0下有没有办法直接取得当前的键盘状态呢(类似于GetKeyboardState的功能)?

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
我装了SOFTICE跟踪了一下,里面代码还是挺多的,不过不能观察堆栈状况,所以对流程依然不解。最像是跳转到相关处理函数的地方就是下面有个call ebx,于是我记录下call ebx时相关的寄存器值,硬编码了一份驱动代码,原esp相关的我也已经作了转换,只是堆栈内的值不清楚,只能大致保证与原esp偏移相同。
测试了一下,没挂,SOFTICE跟进,代码倒是执行过了,只是没取到想要的东西。不过这个call ebx内部的ebp竟然依赖于call之前的值,像这样乱的参数传递方式,估计也不会有外部接口了。
有大侠研究过这个吗?也就是设法直接在ring0调用sysenter之后的代码。我现在是想找到GetKeyboardState对应的ring0级API,用LordPE看过几个sys的导出函数,始终没找到相像的
……
2009-4-15 22:46
0
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
3
NtUserGetKeyboardState。
从NT4的代码来看,其实这个函数是从
ETHREAD->Tcb.Win32Thread->pq中取到当前的键盘状态的。Win32Thread是个很重要的数据结构,
为便于用户态代码更容易获得Win32Thread的值,Windows NT/2000也在线程的TEB中存取了Win32Thread指针。
CPU从键盘中断取到数据后会经过几个驱动层才会讲数据放入这个队列,其中kbclass的是在ddk有代码的。别的要在泄露的NT4里面找。
2009-4-15 22:54
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
请教LS,NtUserGetKeyboardState是哪个sys文件里的?原型是什么?
网上找了一下,似乎说是win32k.sys里面的,可是我用LordPE没有看到这个导出函数。
由于不知道原型,也不知道该怎么去声明。
试过这样声明,并链接win32k.lib,结果也链接不上。
extern "C"
{
NTSYSAPI int NTAPI NtUserGetKeyboardState(unsigned char*);
}
2009-4-16 00:05
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
5
在驱动中调用如下代码可获得当前KeyState(驱动,RING3都可使用,仅用于XP)

BYTE KeyState[256];
PBYTE pb = KeyState ;
BOOL bget ;
__asm
{
push pb
lea edx , [esp]
mov  eax , 0x119e
int 0x2e
add esp , 0x4
mov  bget , eax
}
2009-4-16 00:18
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
[QUOTE=qihoocom;607329]在驱动中调用如下代码可获得当前KeyState(驱动,RING3都可使用,仅用于XP)

BYTE KeyState[256];
PBYTE pb = KeyState ;
BOOL bget ;
__asm
{
push pb
lea edx , [esp]
mov  eax ,...[/QUOTE]

我系统是XP,试过仿造一个sysenter到原sysenter入口,用SOFTICE跟踪过,前面执行都很正常,问题是最后有一个sysexit,此指令执行后,就失去了ring0权限,接下来F5的话,机器就蓝了。仿造一个2k的int 2e倒是没有试过,不过就算可以的话,这个局限性太强了,还是那个NtUserGetKeyboardState通用一点吧?
2009-4-16 08:46
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
学习了一下Undocumented Windows NT和Undocumented Windows 2000,知道了有KeServiceDescriptorTable这么一个服务表,通过这个表以及一些附加手段,我得到了win32k的服务表,并且也找到了那个NtUserGetKeyboardState的入口地址BF85267A,这个地址与SOFTICE用bpx GetKeyboardState后单步跟踪过去然后call ebx去到的那个地址是相同的,问题是参数该怎么传?同2L那次一样,尽管我模仿了一下断点跟踪过来时的寄存器的值,但是调用后啥效果都没有……
/********************************************/
对了,5Lqihoocom大侠的方法我也试过ring3下是可行的,驱动下调用后也是没效果,是不是还要先做些其他什么事?
2009-4-18 10:17
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
我知道大概怎么回事了,函数调用方式还是_stdcall。但是根据http://www.pediy.com/bbshtml/bbs8/pediy8-682.htm这贴最后说的第四步,“检查EAX中的参数堆栈指针与MmUserProbeAddress。这是一个ntoskrnl导出的全局变量。通常等于0x7FFF0000,如果参数指针不在这个地址之下,返回STATUS_ACCESS_VIOLATION”,我跟踪了一下整个过程。在NtUserGetKeyboardState里面会调用ProbeForWrite,而在这个函数里面会CMP EAX, [ntoskrnl!MmUserProbeAddress],此时EAX是一个堆栈指针,如果是GetKeyboardState过去的,EAX必定小于0x7FFF0000,但是如果是驱动调用的,它就大于了这个值,所以调用都是失败,打印输出了一下NtUserGetKeyboardState返回值,结果确实是这样。
这样说来,似乎在驱动里面就绝对没有办法调用这几个函数了,因为堆栈地址太高?
2009-4-18 11:06
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
9
可以用ZwAllocateVirutalMemory在驱动中分配一块用户内存
2009-4-18 12:39
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
多谢指点!我试了一下你说的方法,ProbeForWrite可以正常过去了,但是接下来
call [ntoskrnl!PsGetCurrentThread] 
push eax
call [ntoskrnl!PsGetProccessWin32Process]    
mov eax, [eax+30]

PsGetCurrentThread应该是取得一个当前线程相关的线程结构体指针,然后作参数调用PsGetProccessWin32Process,这个函数里面也很简单,就是从线程结构体里面取了一个成员出来,不过可惜其值是NULL,所以下面的mov eax, [eax+30]就抛出异常,被函数入口设置的异常处理程序捕获,就调用失败了。
这个是不是网上说的必须是GUI线程调用才行?如果是的话,有没有方法转换成那样的线程,或者自己创建一个那样的线程?
2009-4-18 14:56
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
11
必须是GUI线程~
可以用PsConvertToGuiThread来转换
2009-4-18 16:15
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
我刚想问PsConvertToGuiThread怎么回事呢。。。
这函数到底是哪里的?ntoskrnl.exe导出函数里面没有,win32k.sys导出函数里面也没有,
我这样声明
NTSYSAPI
NTSTATUS
NTAPI
PsConvertToGuiThread(
);
不过不知道该链接哪个lib,链接不上啊……
2009-4-18 16:37
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
13
未导出函数
如果你通过int2e来调用NtUserGetKeyboardState,会自动转换
2009-4-18 16:40
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
试了一下,还是不行,不过我大致知道怎么回事了,PsConvertToGuiThread的主要作用应该是得到win32k对应的那个服务表,不过我现在只是测试,系统是XP,所以通过已经通过硬编码(往前偏移一个),得到了KeServiceDescriptorTableShadow表,所以其实PsConvertToGuiThread调不调用应该都差不多了吧?(我试过用int 2e调用了一下,可惜KeServiceDescriptorTable的win32k表还是NULL,这就不知道怎么回事了)。
不过我查了一下PsGetProcessWin32Process,似乎它的作用是取得相关的WIN32进程的进程描述结构体,然后从它那里取得键盘状态,也应该就是3Lweolar大侠说的那个过程。但是因为我这个完全是驱动程序,并没有什么相关的WIN32进程,所以就取不到了。或许KeAttachProcess之后会有点用处,我再研究研究……
2009-4-18 17:06
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
15
PsConvertToGuiThread并不光是将你的currentthread的ServiceTable转换为支持SHADOW调用的shadow table,还有Win32ProcessCallOut和 Win32ThreadCallOut的调用

如果你直接调用shadow表里的地址,不会调用Win32Callout来CreateThread/ProcessInfo , 这样会导致你的线程没有w32thread,所以就无法获取状态

必须通过上面的int 0x2e方法调用shadow 函数才有效
2009-4-18 17:09
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
谢谢指正,劳烦LS帮忙看下,下面这样写有没有问题
	HANDLE hl = (HANDLE)-1;
	PVOID lpData = NULL;
	ULONG uSize = 0x1000;
	if (NT_SUCCESS(ZwAllocateVirtualMemory(hl, &lpData, 0, &uSize, MEM_COMMIT, PAGE_READWRITE)))
	{
		int result = 0;
		TestOut();
		__asm
		{
			push dword ptr[lpData]
			mov edx, esp
			mov eax, 0x119e
			int 0x2e
			add esp, 0x4
			mov dword ptr[result] , eax
		}
		DbgPrint("VK_CAPITAL = %d, result = %d\r\n", *(((PUCHAR)lpData) + 0x14), result);
		ZwFreeVirtualMemory(hl, &lpData, &uSize, MEM_RELEASE);
	}

调用后输出的result是0,也就是调用失败。
其中TestOut是我用来加断点的,由于int 2e单步跟踪不了,在TestOut处断下后,我在NtUserGetKeyboardState(BF85267A)和mov dword ptr[result], eax两处分别加了两个断点,然后F5继续执行,结果mov dword ptr[result], eax先被断下,也就是说不知为何NtUserGetKeyboardState根本没被调用,这又是怎么回事呢?int 2e还可以继续跟踪吗?
2009-4-18 21:16
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
17
看了下,没有user32的话convert时从win32k上调下来的User mode callback无法实现(KernelCallbackTable没填充~),试试attachprocess吧~
2009-4-19 00:29
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
18
看样子是没有办法了,试了一下KeAttachProcess,int 2e还是老样子,而且int 2e以后,直接调用NtUserGetKeyboardState也不行,还是在PsGetProcessWin32Process返回了NULL。
2009-4-19 16:05
0
游客
登录 | 注册 方可回帖
返回
//