阅读:4109回复:21
在XP中键盘中断号是多少?
我也不知道为什么,试了N个都不行,难道是程序出了问题,贴出来一看:
#define SYSTEMCALL 0x09 //定义 IDTR typedef struct tagIDTR { WORD IDTLimit; WORD LowIDTbase; WORD HiIDTbase; }IDTR, *PIDTR; //定义 IDT typedef struct tagIDTENTRY{ WORD OffsetLow; WORD selector; BYTE unused_lo; unsigned char unused_hi:5; unsigned char DPL:2; unsigned char P:1; WORD OffsetHigh; } IDTENTRY, *PIDTENTRY; DWORD OldIntService; VOID InstallMyInt(); VOID UninstallMyInt(); VOID __fastcall ReadKBOffset() { KIRQL OldIrql; KeRaiseIrql(HIGH_LEVEL, &OldIrql); // 提升当前的 IRQL 级别防止被中断 t<<\"但愿可以执行到这里!\\n\"; KeLowerIrql(OldIrql); //恢复原始 IRQL } __declspec(naked) MyIntService() { t<<\"哈哈,可以执行到这里!\\n\"; __asm{ pushad pushfd push fs mov bx,0x30 mov fs,bx push ds push es sti call ReadKBOffset; // 调用记录函数 cli pop es pop ds pop fs popfd popad jmp OldIntService; //跳到原始 INT 09 继续工作 } } VOID InstallMyInt() { IDTR idtr; PIDTENTRY OIdt; PIDTENTRY NIdt; //得到 IDTR 中得段界限与基地址 __asm { sidt idtr; } //得到IDT基地址 OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase); //保存原来的 INT 09 服务例程 OldIntService = MAKELONG(OIdt[SYSTEMCALL].OffsetLow,OIdt[SYSTEMCALL].OffsetHigh); NIdt = &(OIdt[SYSTEMCALL]); __asm { cli lea eax,MyIntService; //得到新的 INT 09 服务例程偏移 mov ebx, NIdt; mov [ebx],ax; //INT 09 服务例程低 16 位 shr eax,16; //INT 09 服务例程高 16 位 mov [ebx+6],ax; lidt idtr; //装入新的 IDT sti } t<<\"呵呵,可以执行到这里!\\n\"; } VOID UninstallMyInt() { IDTR idtr; PIDTENTRY OIdt; PIDTENTRY NIdt; __asm { sidt idtr; } OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase); NIdt = &(OIdt[SYSTEMCALL]); _asm { cli lea eax,OldIntService; mov ebx, NIdt; mov [ebx],ax; shr eax,16 mov [ebx+6],ax; lidt idtr sti } t<<\"嘿嘿,可以执行到这里!\\n\"; } 由于SoftICE不能用,可能在DriverMonitor里面看了,启动和卸载的时候InstallMyInt和UninstallMyInt,都执行了,可是其它的感觉不出来,另外请问一下,为啥我的SoftICE一用就死机呀,我用的是DS3.1中带的SoftICE,需要改什么文件,如果把startup选项boot则根本就就不能进系统 |
|
沙发#
发布于:2005-05-23 09:31
键盘中断是31
|
|
|
板凳#
发布于:2005-05-23 22:49
键盘中断是31 TO:bmyyyud 基本上每次的问题都是你帮我解决的,在此表示感谢,最真诚的感谢。我小本快毕业了,要去上海,什么时候过来玩可以找我,吃的住的还付得起吧。 我把中断号改为31了也不行,不管是十进制还是十六进制。我自己都不知道是为什么,要不我把程序发过来你看看,其实主要的都贴出来了, 另外,我的SOFTICE其实可以用,只是不能用鼠标,在设置的时候如果禁止鼠标就可以用了,但是不用鼠标是不是太困惑了。我的主板是微星的,鼠标是微星主板赠的光电鼠,应该选项P/S 2吧,鼠标和键盘都不是PNP的,哪位给点建议,到底为啥子嘛 |
|
地板#
发布于:2005-05-24 15:11
键盘中断是31,bmyyyud是从windows internels 4上看的吧,在apic
的描述上,无论是inside 2000,还是第四版,都有很多地方不准确。 internels的书上说apic用于mp,在up上用apic仿真pic,但是我发现我们现在的p4 的单cpu,用的都是apic了。反汇编代码,所涉及到的中断irq,idt,irql都 符合mp的部分,而不是书上所说的up的部分。 你用ice的irq命令看一下,我们一般的键盘的irq都是1,可以从键盘 驱动的属性里看到。所以int1看到的是vector就是键盘的idt,在我机器上是0x93,这个值是随机分配来的。我正在分析这部分代码 0x9还是实模式dos下,ivt中键盘中断的index。保护模式下早就不一样了。 |
|
地下室#
发布于:2005-05-24 16:27
键盘中断是31,bmyyyud是从windows internels 4上看的吧,在apic 不是从书上得来的,你看过我以前做的hook全部中断的演示了吗?那个在迅驰1.3上试的。 在单处理器上肯定是31,包括softice激活时,按CTRL+D,都会进入31。这其实给我调试那个演示带来了很多麻烦。多处理器会不一样,没试过,我发现P4超线程是多处理器的核心,我以后会在这上面试一下。 你用ice的irq命令看一下,我们一般的键盘的irq都是1,可以从键盘 驱动的属性里看到。所以int1看到的是vector就是键盘的idt,在我机器上是0x93,这个值是随机分配来的。我正在分析这部分代码 中断映射只跟核心即HAL,NTOSKRNL装的是单处理器还是多处理器版,不会是随机的 :D 另外我刚装server 2003,以前是xp,你可以先看看我的那个垃圾原创在你那里试试。 把代码发给我,我系统安装完毕,给你试试,吃的住的先记下 :P我在上海也有很多老同学了,如果有机会,也去看看 顺便wowocock也在上海,过去了不要忘了拜访他,他可是真正的高手 :D |
|
|
5楼#
发布于:2005-05-24 16:30
我现在正在给2003打补丁呢,发信点我帖子下的发信就可以了 :D
|
|
|
6楼#
发布于:2005-05-24 17:50
你的单cpu是pic还是apic?我的cpu是celeron,好像不支持超线程,
但用的是apic. <<<中断映射只跟核心即HAL,NTOSKRNL装的是单处理器还是多处理器 <<<版,不会是随机的 在apic下,idt是动态分配的,可以看nt源吗的nthal\\halmps\\i386\\mpsysbus.c中的HalpGetSystemInterruptVector,反汇编xp的代码 做比较,不是定死的,2k,xp就不一样 |
|
7楼#
发布于:2005-05-24 18:21
我现在正在给2003打补丁呢,发信点我帖子下的发信就可以了 :D 我把一些没有用的东西都删了,就是为了让结构看得简单一些,主要都在interrupt.h中,其它的都是按照DS自动生成的。 点了给你 发信,可是好像不能添加附件。就发这里吧 |
|
|
8楼#
发布于:2005-05-24 20:02
我现在正在给2003打补丁呢,发信点我帖子下的发信就可以了 :D 大佬,我按zhaock的方法试了一下: 你用ice的irq命令看一下,我们一般的键盘的irq都是1,可以从键盘 果然是这样,目前可以正确显示了,至少在每次按键盘的时候能有提示信息,我想,既然SOFTICE能查到IRQ1的vector,那我们在驱动程序中也可以查到吧,有谁能给点建议。zhaock研究得怎么样了,有心得没,SOFTICE是怎样查到的? 谢谢大家的建议,如果大佬很忙就不用看了,里面也没有什么实质的东西,新手倒是可以一看,大家看过后笑笑就算了,有什么好的方法,想法,一起研究吧:) |
|
9楼#
发布于:2005-05-24 22:35
哪位帮忙看一下源码吧,VC环境下我不知道为什么用DS的那个控件不能编译,只能用VC的那个控件编译,说是
__declspec(naked) MyIntService() { t<<\"哈哈,可以执行到这里!\\n\"; __asm{ pushad pushfd push fs mov bx,0x30 mov fs,bx push ds push es sti call ReadKBOffset; // 调用记录函数 cli pop es pop ds pop fs popfd popad jmp OldIntService; //跳到原始 INT 09 继续工作 } } 没有返回值,我也不知道怎么办,用VC控件编译的时候只是一个警告,我不知道是不是这个原因,有时候生成的驱动程序不稳定,为造成重启(我这里很少蓝屏,我自己都不知道为什么) |
|
10楼#
发布于:2005-05-25 11:31
[quote]我现在正在给2003打补丁呢,发信点我帖子下的发信就可以了 :D 大佬,我按zhaock的方法试了一下: 你用ice的irq命令看一下,我们一般的键盘的irq都是1,可以从键盘 果然是这样,目前可以正确显示了,至少在每次按键盘的时候能有提示信息,我想,既然SOFTICE能查到IRQ1的vector,那我们在驱动程序中也可以查到吧,有谁能给点建议。zhaock研究得怎么样了,有心得没,SOFTICE是怎样查到的? 谢谢大家的建议,如果大佬很忙就不用看了,里面也没有什么实质的东西,新手倒是可以一看,大家看过后笑笑就算了,有什么好的方法,想法,一起研究吧:) [/quote] 我做那个hook中断的笔记本上是0x31,每次都是不会变的。 我这里的机器都看了,服务器是真正的双CPU,包括P4超线程,用到了256级中断,但单CPU的后面全是空的,你可以看看你的机器上的hal 和ntoskrnl是从安装盘上单处理器版本还是多处理器版本拷来的 如果要找键盘中断,Windows中有个中断对象,看那里能否找到关联 |
|
|
11楼#
发布于:2005-05-25 11:41
请参考
http://www.driverdevelop.com/forum/html_92533.html?1116992039 你会明白为什么是这样,人多力量大,有人补全了!!也许我的单处理器机器有点老,但是我也奇怪,迅驰1.3不老啊?? celeron的机器,我最高只有1.3G的,也是PIC版 |
|
|
12楼#
发布于:2005-05-25 12:25
我昨天回家看了看我家里的机器是athlon 2200+,肯定不是
超线程,肯定是单cpu,用的也是apic. 看intel的文档从奔腾以后就支持apic了,但不知道windows是从 哪个型号的cpu开始采用apic,不用pic的? 但单cpu支持apic肯定是没有问题的。 |
|
13楼#
发布于:2005-05-25 15:04
请参考 APIC那一篇我昨天晚上看了,可是不知道\"IO重定向表\"这个表放在什么地方,如果能打到这个表的话,可以直接到表里面取。 |
|
14楼#
发布于:2005-05-26 12:05
TO zhaock:
请问你有没有用过DS中的Kinterrupt类做中断呀?我用SOFTICE的intobj 93查看了一个键盘中断对象,也就是键盘驱动挂接的那个中断对象,部分信息如下: …… Vector 93 Device IRQL 08 Synchronixe IRQL 09 Save Fioating Piont FALSE Processor Affinity Mask 01 Share interrupt FALSE Interrput mode Edge …… Share interrupt FALSE是不是说明了不能再通过Kinterrupt类来挂接中断了呀,只有通过嵌汇编的方式自己修改中断服务地址才可以? 我用Kinterrupt类挂接后,用SOFTICE查看了一下,根本就没有挂上,部分代码如下: #define MYVector 0x93 #define MYIRQL 0x08 myInterrupt( MYIRQL, MYVector, Latched, TRUE ) …… myDpc.Setup(LinkTo(Dpc),this); myInterrupt.Connect(LinkTo(Isr),this); 可以帮忙指导一下吗?谢谢了 |
|
15楼#
发布于:2005-05-26 17:42
键盘中断是独占的,只能修改IDT来挂了。
下面也不记得是谁写的代码了,它演示了如何挂INT 0x2E. #include <ntddk.h> //----------------------------------------------------------// Structure Definition //----------------------------------------------------------#pragma pack(1) typedef struct _idtr { short IDTLimit; unsigned long IDTBase; }IDTR,*PIDTR; typedef struct _idtentry { unsigned short OffsetLow; // The lower 16-bit offset of ISR unsigned short Selector; // The selector of ISR unsigned char Reserved; unsigned char Type:4; // The type of gate in IDT(IntGate, TrapGate, TaskGate) unsigned char SegmentFlag:1; // Flag of segment unsigned char DPL:2; unsigned char Present:1; unsigned short OffsetHigh; // The higher 16-bit offset of ISR }IDTENTRY,*PIDTENTRY; #pragma pack() //----------------------------------------------------------------------------- // Function Declaration //----------------------------------------------------------------------------- VOID DriverUnload(PDRIVER_OBJECT DriverObject); VOID HookInterrupt(VOID); VOID UnHookInterrupt(VOID); VOID NewInterruptTrapHandler(); VOID __fastcall Monitor(); //----------------------------------------------------------------------------- // Constants Definition //----------------------------------------------------------------------------- #define HOOKINTID 0x2E //----------------------------------------------------------------------------- // Global Variable Definition //----------------------------------------------------------------------------- unsigned long OldOffset = 0; unsigned short OldSelector = 0; NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; DbgPrint(\"::::::::::::::::::::::::::::::::::::::::\\n\"); DbgPrint(\"HookInt: ------> DriveEntry\\n\"); DriverObject->DriverUnload = DriverUnload; //NewISR = (unsigned int)NewInterruptTrapHandler; DbgPrint(\"HookInt: ------> HookInterrupt\\n\"); HookInterrupt(); DbgPrint(\"HookInt: <------ HookInterrupt\\n\"); DbgPrint(\"HookInt: OldOffset = 0x%X,OldSelector = 0x%X\\n\", OldOffset, OldSelector); DbgPrint(\"HookInt: <------ DriveEntry\\n\"); return status; } VOID DriverUnload(PDRIVER_OBJECT DriverObject) { DbgPrint(\"HookInt: ------> DriverUload\\n\"); DbgPrint(\"HookInt: ------> UnHookInterrupt\\n\"); UnHookInterrupt(); DbgPrint(\"HookInt: <------ UnHookInterrupt\\n\"); DbgPrint(\"HookInt: <------ DriverUload\\n\"); } VOID HookInterrupt(VOID) { IDTR idtr; PIDTENTRY IdtEntry; __asm sidt idtr; IdtEntry = (PIDTENTRY)idtr.IDTBase; // Save the orginal ISR OldOffset= ((unsigned long)IdtEntry[HOOKINTID].OffsetHigh << 16) | (IdtEntry[HOOKINTID].OffsetLow); // Set new ISR __asm cli IdtEntry[HOOKINTID].OffsetLow = (unsigned short)NewInterruptTrapHandler; IdtEntry[HOOKINTID].OffsetHigh = (unsigned short)((unsigned long)NewInterruptTrapHandler >> 16); __asm sti; } VOID UnHookInterrupt(VOID) { IDTR idtr; PIDTENTRY IdtEntry; __asm sidt idtr; IdtEntry = (PIDTENTRY)idtr.IDTBase; __asm cli IdtEntry[HOOKINTID].OffsetLow = (unsigned short)OldOffset; IdtEntry[HOOKINTID].OffsetHigh = (unsigned short)(OldOffset >> 16); __asm sti; } __declspec (naked) VOID NewInterruptTrapHandler() { unsigned short OldInterruptTrapHandler[3]; __asm PUSHAD; __asm PUSHFD; __asm CALL Monitor; OldInterruptTrapHandler[0] = (unsigned short)OldOffset; OldInterruptTrapHandler[1] = (unsigned short)(OldOffset >> 16); OldInterruptTrapHandler[2] = OldSelector; __asm POPFD; __asm POPAD; // Call original interrupt service routine __asm JMP DWORD PTR OldInterruptTrapHandler; __asm IRETD; } VOID __fastcall Monitor() { unsigned long dwServiceId, dwProcessId; KIRQL OldIrql; // // INT 0x2E = System Service Interrupt // Get the Service ID from EAX // __asm mov dwServiceId, eax; DbgPrint(\"System Service 0x%X called\\n\", dwServiceId); // // Get current process ID // dwProcessId = (unsigned int)PsGetCurrentProcessId(); // // KeRaiseIrql(HIGH_LEVEL, &OldIrql); // // switch(dwServiceId) // { // case 0x23: // ZwCreateKey // DbgPrint(\"ProcessId: %d ZwCreateKey\\n\", dwProcessId); // break; // // default: // DbgPrint(\"Not our Interrupt,ProcessId: %d\\n\", dwProcessId); // break; // } // // KeLowerIrql(OldIrql); } |
|
|
16楼#
发布于:2005-05-26 20:11
对,前面中断处理函数如果Share interrupt FALSE,后面就不能再通过Kinterrupt类(实际上是调用IoConnectInterrupt)来安装中断处理函数了。
不知道你这样做的目的是什么? 即使Share interrupt TRUE,你通过IoConnectInterrupt来hook,可能也会有问题。共享中断,每个中断处理函数,都先判断是不是自己要处理的中断,如果不是,返回false,系统再调用下一个。如果是,就处理了,返回true,系统对于level interrupt 就不会调用下一个。即使对于edge interrupt系统会调用下一个,如果前面的中断处里函数破坏了现场,后面的中断处理函数,可能也读不到数据了 还是通过替换Idt里函数指针来hook简单 |
|
17楼#
发布于:2005-05-26 20:13
谢谢seaquester大佬的回答,我上面的也是参考这个写的:)
既然不能用Kinterrupt那就算了 现在只剩下如何取键盘中断号了,也就是所谓IO重定向表,或者说是那个HalpINTItoVector数组到底在哪儿放着,我的SOFTICE太困惑了,每用一次只能重启电脑,鼠标的不能用,困惑的说,在内在单元中查找不太熟的说,找了几次都没有找到,如果哪们大虾能给点建议就太好了。 没有太多讨论的地方了,谢谢大家的帮助,我感觉给的分太少了,我再开一个新贴给分吧。谢谢大家了 |
|
18楼#
发布于:2005-05-28 13:06
请问一下,怎样才能只执行我的中断服务例程,不执行系统的呀,我试了一下,直接死跷跷了,有没有一个好的办法来实现锁键盘呀
|
|
19楼#
发布于:2005-05-28 13:49
请问一下,怎样才能只执行我的中断服务例程,不执行系统的呀,我试了一下,直接死跷跷了,有没有一个好的办法来实现锁键盘呀 如果你要用键盘过滤驱动,偶就说几句废话 我在做我那个垃圾原创中的键盘过滤驱动时就是这样,我试过如果不调用系统的服务,表明你没有完成这个键盘中断,因而它不断仍产生这个中断,结果就死掉了。这也相当于锁键盘啊 :D 开个玩笑 至于锁键盘的程序,如果你用键盘过滤驱动去做,very easy。照我那个垃圾原创改一点点,我那个做的是使CTRL+ALT+DEL无效,你把判断去掉,直接全部无效就可以了 |
|
|
上一页
下一页