免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

IDT HOOK

A、实例演示
   B、替换IDT处理函数
   D、IDT HOOK 代码书写
   D、测试效果
课时:36分 断网

//-----------全局变量--------------------------------
ULONG int3proc_addr; //用来存放int 3处理函数地址
ULONG jmpaddr_int3proc_9; //用来存放intproc+9处理函数地址
//-----------全局变量 定义结束-----------------------

1、ULONG ReadIdtBase(ULONG CPUNUM)  
2、void __declspec(naked)  myInt3Proc()
3、ULONG HookInt3Proc()
4、void __declspec(naked)  int3UnHookcode()
  {
804dfaa1 6a00            push    0
804dfaa3 66c74424020000  mov     word ptr [esp+2],0

   }
5、ULONG UnHookInt3Proc()

===================================================

笔记:
本节课实战保护记事本,如果发现OD调试则蓝屏,哇好猛啊!
原理在上节课已经讲清楚了.首先是替换IDT函数,分成 5个步骤:1取得基址,2.处理断点,3进行HOOK,4保存原有代码,5卸载恢复

#include <ntddk.h>
#pragma pack(push)
#pragma pack(1) //
typedef struct _IDTR //IDT基址
{
        USHORT limit; //范围占位
        ULONG base; //基地址占位_IDT_ENTRY类型指针
}IDTR,*PIDTR;

typedef struct _IDT_ENTRY
{
        USHORT offset_low; //中断处理函数地址低位
        USHORT selector;
        UCHAR  reserved;
        UCHAR  type:4;
    UCHAR  always0:1;
        UCHAR  dpl:2;
        UCHAR  present:1;
        USHORT offset_high;//中断处理函数地址低位
}IDT_ENTRY,*PIDT_ENTRY;
#pragma pack(pop) //#pragma pack(pop)
//-----------全局变量--------------------------------
ULONG int3proc_addr; //用来存放int 3处理函数地址
ULONG jmpaddr_int3proc_9; //用来存放intproc+9处理函数地址
//-----------全局变量定义结束-----------------------

#pragma PAGECODE
ULONG ReadIdtBase(ULONG CPUNUM)                                //1-取得基址
{
  IDTR idtr;//获取表基址
  PIDT_ENTRY Aidt;
       KdPrint(("IDT_ENTRY size=%d \n",sizeof(IDT_ENTRY)));
  __asm sidt idtr;//获取表基址信息
   KdPrint(("IDT BASE=%x \n",idtr.base));
  Aidt=PIDT_ENTRY(idtr.base);
  return idtr.base;
}
void __declspec(naked)  int3UnHookcode()        //4-保存原有代码
{
        __asm
        {
                push    0
                mov     word ptr [esp+2],0
        }
}

#pragma PAGECODE
void __declspec(naked)  myInt3Proc()                //2-处理断点
{       
        __asm
        {
                pushad
                pushfd
        }
        KdPrint(("\n entry my Int3Proc \n"));
        //在这里添加自己的条件过滤代码
        //获取进程上下文
        PEPROCESS EP;         
        EP=PsGetCurrentProcess();
        // (PTSTR)((ULONG)EP+0x174)是否等于需要反断点的进程
        if (strcmp((PTSTR)((ULONG)EP+0x174),"notepad.exe")==0)
        {
                //需要保护的进程直接蓝屏
                KdPrint(("\n 蓝屏蓝屏蓝屏\n"));
                __asm retn 100;
        }
        __asm
        {
                popfd
                popad
        }
        __asm
        {
                    push 0
                        mov word ptr [esp+2], 0
                        //前条需要恢复的指令占字节
                        jmp jmpaddr_int3proc_9
        }
}
#pragma  PAGECODE
ULONG HookInt3Proc()                                                //3.HOOK处理
{   
ULONG status=1;
PIDT_ENTRY Pidt_info=(PIDT_ENTRY)ReadIdtBase(0);
ULONG jmpaddr;

Pidt_info+=3;//转到IDT 数组里边存放着int 3 处理函数地址
//Pidt_info=Pidt_info+sizeof(Pidt_info)*3;
//begin计算出int3处理函数地址
int3proc_addr=Pidt_info->offset_high<<16;//makelong 0x804d0000 高字节存放
//MAKELONG(Pidt_info->offset_high,Pidt_info->offset_Slow) //0xfaa1 =804dfaa1
int3proc_addr=int3proc_addr+Pidt_info->offset_low;        //合并高低字节
KdPrint (("\n int proc addr=%x \n",int3proc_addr));
//end;
//begin inline hook int3Proc write
// E9+jmp地址//jmp地址=myInt3Proc-int3proc_addr-5;
jmpaddr=ULONG(&myInt3Proc)-int3proc_addr-5;
jmpaddr_int3proc_9=int3proc_addr+9;

        __asm //去掉页面保护
        {
                cli
                        mov eax,cr0
                        and eax,not 10000h //and eax,0FFFEFFFFh
                        mov cr0,eax

        }
__asm                                                                        //用硬编码写入跳转
{  
        push ebx
                push eax
                mov ebx,int3proc_addr
                mov byte ptr ds:[ebx],0xE9                       
                mov eax,jmpaddr
                mov dword ptr ds:[ebx+1],eax
                pop eax
                pop ebx
}
//end;inline hook int3proc write

__asm
        {
                mov     eax, cr0
                        or     eax, 10000h
                        mov     cr0, eax
                        sti
        }   
return status;
}

#pragma  PAGECODE
ULONG UnHookInt3Proc()                                                //5.卸载还原
{  
   ULONG status=1;
       
        KdPrint(("\n 卸载Idt Hook \n"));


        __asm //去掉页面保护
        {
                cli
                        mov eax,cr0
                        and eax,not 10000h //and eax,0FFFEFFFFh
                        mov cr0,eax

        }
        __asm
        {   
        push ebx
        push eax
        push ecx
        mov ebx,int3proc_addr                                 //0x804dfaa1
        lea ecx,int3UnHookcode
        //一共9个字节分三次写入
        mov eax,[ecx+0]                                       
        mov dword ptr ds:[ebx],eax                        //写入4字节
                mov eax,[ecx+4]
                mov dword ptr ds:[ebx+4],eax        //写入4字节
                        mov eax,[ecx+8]
                        mov byte ptr ds:[ebx+8],al        //写入1字节
                                pop ecx
                                pop eax
                                pop ebx
        }

__asm
        {
                mov     eax, cr0
                        or     eax, 10000h
                        mov     cr0, eax
                        sti
        }   
        //end;inline hook int3proc write
        return status;
}

老师对整个代码进行详解,又在WINDBG里查看卸载过程,一共要恢复9个字节的代码,分3次写回.又将教程中的代码修改一下,最后在虚拟机里加载notepad.exe程序则蓝屏死机,再修改一下代码当检查到调试器时则马上蓝屏…太狠了

返回列表