阅读:1439回复:7
大家帮忙看看我的中断截获程序有什么错误
程序如下,但不知为什么产生中断的时候没有进入Monitor函数,不知道是不是没有Hook成功还是怎么的。大家帮忙看看吧
//////////////////////////////////////////////////////////// unsigned int OldOffset=0; unsigned int NewISR=0; unsigned short OldSelector=0; // constants define #define HOOKINTID 0x2e //我们要Hook的中断向量 // struct defines typedef struct _idtr { //定义中断描述符表的限制,长度两字节; short IDTLimit; //定义中断描述服表的基址,长度四字节; unsigned int IDTBase; }IDTR,*PIDTR; typedef struct _idtentry { //中断执行代码偏移量的底16位; unsigned short OffsetLow; //选择器,也就是寄存器; unsigned short Selector; //保留位,始终为零; unsigned char Reserved; //IDT中的门的类型:包括中断门,陷阱门和任务门; unsigned char Type:4; //段标识位; unsigned char SegmentFlag:1; //中断门的权限等级,0表示内核级,3表示用户级; unsigned char DPL:2; //呈现标志位; unsigned char Present:1; //中断执行代码偏移量的高16位; unsigned short OffsetHigh; }IDTENTRY,*PIDTENTRY; NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; DbgPrint("::::::::::::::::::::::::::::::::::::::::\n"); DbgPrint(":::::::>进入驱动的DriveEntry主函数"); DriverObject->DriverUnload = DriverUnload; //NewISR = (unsigned int)NewInterruptTrapHandler; DbgPrint("InterruptHook::::>HookInterrupt\n"); HookInterrupt(); DbgPrint("InterruptHook<::::HookInterrupt\n"); DbgPrint("OldOffset::::>%d,OldSelector::::>%d", OldOffset, OldSelector); return status; } VOID DriverUnload(PDRIVER_OBJECT DriverObject) { DbgPrint("InterruptHook::::>DriverUload\n"); UnHookInterrupt(); DbgPrint("InterruptHook<::::DriverUload\n"); } VOID HookInterrupt(VOID) { IDTR idtr; //记录IDT数组的指针,通过它可以查找到我们需要Hook中断号对应的中断门; PIDTENTRY IdtEntry; //汇编指令sidt,获取IDT入口信息; __asm sidt idtr; //赋予IDT基地址值; IdtEntry = (PIDTENTRY)idtr.IDTBase; //保存中断号HOOKINTID对应中断门所指向的执行代码偏移量,以备执行中断处理或恢复时使用; OldOffset= ((unsigned int)IdtEntry[HOOKINTID].OffsetHigh << 16) | (IdtEntry[HOOKINTID].OffsetLow); //关中断 __asm cli //更新执行代码偏移量的底16位; IdtEntry[HOOKINTID].OffsetLow = (unsigned short)NewInterruptTrapHandler; //更新执行代码偏移量的高16位; 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 //恢复中断号HOOKINTID对应中断门执行代码偏移量的底16位; IdtEntry[HOOKINTID].OffsetLow = (unsigned short)OldOffset; //恢复中断号HOOKINTID对应中断门执行代码偏移量的高16位; IdtEntry[HOOKINTID].OffsetHigh = (unsigned short)((unsigned int)OldOffset >> 16); __asm sti; } __declspec (naked) VOID NewInterruptTrapHandler() { unsigned short OldInterruptTrapHandler[3]; DbgPrint("InterruptHoook::::>NewInterruptTrapHandler\n"); // 保存寄存器状态 __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; // 调用原来的中断服务例程 __asm JMP FWORD PTR OldInterruptTrapHandler; //将控制权返回系统内核 __asm IRETD; } VOID __fastcall Monitor() { unsigned long dwServiceId,dwProcessId; KIRQL OldIrql; //由于我们处理的中断号为0x2e, //对应于系统服务中断(System Service Interrupt), //通过获取eax寄存器中的数值来区分系统服务调用; __asm mov dwServiceId,eax; //执行内核函数获取当前进程的ID号; dwProcessId = (unsigned int)PsGetCurrentProcessId(); //提升当前IRQL,防止被中断; KeRaiseIrql(HIGH_LEVEL,&OldIrql); DbgPrint("InterruptHook::::>Monitor\n"); switch(dwServiceId) { //如果eax对应的数值为0x23, //则对应于Windows2000的ZwCreateKey系统服务调用; case 0x23: DbgPrint("ProcessId: %d ZwCreateKey\n",dwProcessId); break; default: DbgPrint("Not our Interrupt,ProcessId: %d",dwProcessId); break; } //恢复原始IRQL; KeLowerIrql(OldIrql); } |
|
最新喜欢:flying |
沙发#
发布于:2004-08-06 17:29
在SOFTICE下看一下它的中断偏移值不就知道了吗
|
|
板凳#
发布于:2004-08-06 20:19
use softice bp at idt 2e address,and trace into to see what happened
|
|
|
地板#
发布于:2004-08-06 20:20
maybe you can reference webcrazy's strace application.
|
|
|
地下室#
发布于:2004-09-09 14:50
我试了你的代码,为何“IdtEntry = (PIDTENTRY)idtr.IDTBase;
”有时为空? |
|
5楼#
发布于:2004-09-09 18:14
不死机算你运气.....
首先要搞明白naked函数是什么东西 你要明白使用naked的时候...vc帮你生成了什么代码..你自己要生成什么代码....自己查msdn... 然后你要知道...一个中断处理函数..一个跟windows兼容的中断处理函数都是运行在一个什么样子的环境...他应该构造一个什么样子的环境.... 你的代码错误多多呀.... |
|
6楼#
发布于:2004-09-10 09:05
naked只是不生成prolog和epilog.是不是这种方法在windows下根本就行不通?
|
|
7楼#
发布于:2004-09-10 09:40
不是行不通而是他不干你得干,由你自己来处理
比如 _ASM ENTER XX,0 .... _ASM LEAVER _ASM RET N |
|
|