H头文件 ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// typedef struct _ServiceDescriptorTable { PVOID ServiceTableBase; //System Service Dispatch Table 的基地址 PVOID ServiceCounterTable; //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 }*PServiceDescriptorTable; extern PServiceDescriptorTable KeServiceDescriptorTable; #pragma pack(1) typedef struct _JMPCODE { BYTE E9; ULONG JMPADDR;//88881234=B }JMPCODE,*PJMPCODE; #pragma pack() ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ULONG GetNt_CurAddr() //获取当前SSDT_NtOpenProcess的当前地址 { LONG *SSDT_Adr,SSDT_NtOpenProcess_Cur_Addr,t_addr; KdPrint(("驱动成功被加载中............................. ")); //读取SSDT表中索引值为0x7A的函数 //poi(poi(KeServiceDescriptorTable)+0x7a*4) t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase; KdPrint(("当前ServiceTableBase地址为%x ",t_addr)); SSDT_Adr=(PLONG)(t_addr+0x7A*4); KdPrint(("当前t_addr+0x7A*4=%x ",SSDT_Adr)); SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr; KdPrint(("当前SSDT_NtOpenProcess_Cur_Addr地址为%x ",SSDT_NtOpenProcess_Cur_Addr)); return SSDT_NtOpenProcess_Cur_Addr; } ULONG GetNt_OldAddr() { UNICODE_STRING Old_NtOpenProcess; ULONG Old_Addr; RtlInitUnicodeString(&Old_NtOpenProcess,L"NtOpenProcess"); Old_Addr=(ULONG)MmGetSystemRoutineAddress(&Old_NtOpenProcess);//取得NtOpenProcess的地址 KdPrint(("取得原函数NtOpenProcess的值为 %x",Old_Addr)); return Old_Addr; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// CPP文件中: 全局变量: JMPCODE oldCode;//用来保存前5字节 以便恢复 PJMPCODE pcur; ULONG flag = 0; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// DriverEntry函数: ULONG cur,old; JMPCODE JmpCode; PJMPCODE pcur; cur=GetNt_CurAddr();//A old=GetNt_OldAddr();//C if (cur!=old) { flag = 1; //保存旧地址 pcur = (PJMPCODE)(cur); oldCode.E9 = pcur->E9; //1字节 oldCode.JMPADDR = pcur->JMPADDR; //4字节 JmpCode.E9=0xE9; JmpCode.JMPADDR=old-cur-5; KdPrint(("要写入的地址%X",JmpCode.JMPADDR)); //写入JMP C-A-5=B //实际要写入地址 __asm //去掉页面保护 { cli //关掉中断 避免在执行时被打扰 sti 允许操作 mov eax,cr0 and eax,not 10000h //and eax,0FFFEFFFFh mov cr0,eax } pcur=(PJMPCODE)(cur); pcur->E9 = 0xE9; pcur->JMPADDR = JmpCode.JMPADDR; __asm //恢复页保护 { mov eax,cr0 or eax,10000h //or eax,not 0FFFEFFFFh mov cr0,eax sti } KdPrint(("NtOpenProcess被HOOK了")); } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// DDK_Unload函数: __asm //去掉页面保护 { cli //关掉中断 避免在执行时被打扰 sti 允许操作 mov eax,cr0 and eax,not 10000h //and eax,0FFFEFFFFh mov cr0,eax } if (flag)//全局 去看是否被HOOK 了 被HOOK才还原 { pcur->E9 = oldCode.E9; //1字节 pcur->JMPADDR = oldCode.JMPADDR; //4字节 } __asm //恢复页保护 { mov eax,cr0 or eax,10000h //or eax,not 0FFFEFFFFh mov cr0,eax sti }