• XP/2003/VISTA的简单INLINE HOOK


    利用HOTPATCH CODE~
    XP SP2
    以上才可以用


    //By MJ0011 2007-6-24
    KSPIN_LOCK
    SDTSpinLock;
    void WPOFF();
    VOID WPON
    ();
    ULONG g_uCr0
    = 0;

    void WPOFF()
    {
       
        ULONG uAttr
    ;
       
        _asm
       
    {
            push eax
    ;
            mov eax
    , cr0;
            mov uAttr
    , eax;
           
    and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
            mov cr0
    , eax;
            pop eax
    ;
            cli
       
    };
       
        g_uCr0
    = uAttr; //保存原有的 CRO 屬性
       
    }

    VOID WPON
    ()
    {
       
        _asm
       
    {
            sti
                push eax
    ;
            mov eax
    , g_uCr0; //恢復原有 CR0 屬性
            mov cr0
    , eax;
            pop eax
    ;
       
    };
       
    }
    NTSTATUS
    InlineHookFuncXP(IN PVOID FuncAddress,
                             IN PVOID
    NewFuncAddress)
    {
    //FuncAddress:orignal function address
    //NewFuncAddress:new function address to hook
    //if function successed,the old function which the hook function will jump to
    //is the FuncAddress+2

    KIRQL
    OldIrql ;
    NTSTATUS stat
    ;

       
    KeAcquireSpinLock( &SDTSpinLock, &OldIrql );

        WPOFF
    ();
       
    //进dpc

        __asm
       
    {
            push eax
            push ecx
            lea eax
    ,[FuncAddress]
            mov eax
    ,[eax]
            cmp
    byte ptr[eax],0x8b
            jnz failtohook
            cmp
    byte ptr[eax+1],0xff
            jnz failtohook
            mov ecx
    ,0xffffffff
    loopcheck
    :
            cmp
    byte ptr[eax+ecx],0x90
            jnz failtohook
            dec ecx
            cmp ecx
    ,0xfffffffa
            jnz loopcheck
           
           
    ;check function header if "mov edi,edi"
            mov
    byte ptr[eax],0xeb
            mov
    byte ptr[eax+1],0xf9
           
    ;write the new function header:jmp short funcaddr-5(0x00-0x07)
            mov
    byte ptr[eax-5],0xe9
           
    ;write 1 byte :jmp xxxxx
            mov ecx
    ,[NewFuncAddress]
           
    sub ecx,eax
            mov dword ptr
    [eax-4],ecx
            jmp hookok
    failtohook
    :
            mov stat
    ,0xc0000001
            jmp
    end
    hookok
    :
            mov stat
    ,0
    end:
            pop ecx
            pop eax


       
    }
        WPON
    ();
               
    KeReleaseSpinLock( &SDTSpinLock, OldIrql );

       
    return stat;
    }


    http://www.debugman.com/read.php?tid=670

    引用:
    NTSTATUS
    InlineHookFuncXP (
      IN PVOID FuncAddress,
      IN PVOID NewFuncAddress
      )

    /*++
      
    Author : MJ0011
    User   : sudami [xiao_rui_119@163.com]
    Time   : 08/01/24
                
    参数 :
      FuncAddress - [IN] 原函数

      NewFuncAddress - [IN] inline hook 函数
                
    返回 : 
      STATUS_SUCCESS - inline hook 成功

      STATUS_UNSUCCESSFUL - 失败
                  
    功能 : 
      在普通函数的开头处简单实现inline hook.XP以上版本适用
      btw -- 在新函数执行完后需要跳转到原函数地址 + 2处


        直线上的这5字节内容,是在大部分函数头前面.都是nop.这刚好可以
      放5字节的跳转: JMP XXXX

        |ˉˉˉ| --> 0xe9 (JMP)    
        |ˉˉˉ|    
        |ˉˉˉ|
        |ˉˉˉ|
        |ˉˉˉ| 这4字节存放新函数的地址
    ˉˉ |ˉˉˉ|ˉˉ--> 符合inline hook 条件的函数的前5字节一般都是---
        |ˉˉˉ|                                                     |
                                               ↓ˉˉˉˉ                
                                                  8bff   mov     edi,edi
       故只需要把8bff这2字节换成一个短转移   <--  55     push    ebp
       "ebf9" 便会跳转到 FuncAddress -5 处   <--  8bec   mov     ebp,esp        

                   <简单inline hook示意图>
    --*/

    {
        KSPIN_LOCK SDTSpinLock;
        KIRQL      oldIrql;
        NTSTATUS   state;
        
        KeAcquireSpinLock (&SDTSpinLock, &oldIrql);
        
        WPOFF();

        __asm {
            push eax
            push ecx
            lea eax,[FuncAddress]
            mov eax,[eax]
            /* 这几句是判断原函数是否符合这种简单inline hook的条件 */
            cmp byte ptr[eax],0x8b      
            jnz failtohook
            cmp byte ptr[eax+1],0xff  
            jnz failtohook   
            mov ecx,0xffffffff

    loopcheck:
            /* 这个循环确保函数头的上面5字节为nop;不是则hook失败 */
            cmp byte ptr[eax+ecx],0x90
            jnz failtohook
            dec ecx
            cmp ecx,0xfffffffa
            jnz loopcheck
            
            /* write the new function header:jmp short funcaddr-5(0x00-0x07) */
            mov byte ptr[eax],0xeb
            mov byte ptr[eax+1],0xf9
            
            /* write 1 byte : jmp xxxx */
            mov byte ptr[eax-5],0xe9

            /* write 4 byte : x xxxx */
            mov ecx,[NewFuncAddress]
            sub ecx,eax
            mov dword ptr[eax-4],ecx
            jmp hookok

    failtohook:
            mov stat,0xc0000001
            jmp end

    hookok:
            mov stat,0
    end:
            pop ecx
            pop eax
        }

        WPON();
        KeReleaseSpinLock (&SDTSpinLock, OldIrql);
        
        return state;
    当初Xp Sp2在函数前面加上mov edi,edi就是为了凑够5字节,升级补丁时不用重启,结果让Hooker捡便宜了。
  • 相关阅读:
    调用Type.InvokeMember()时出现MissingMethodException
    C#学习之Delegate
    WCF之元数据交换 (Metadata Exchange)
    定义Enum的开始和结束,这样就能循环Enum了
    定制自己的Visual Studio的Debugger Visualizer
    C#中 #if DEBUG 和 Conditional("DEBUG")的区别
    从哪里开始学习Windows 8?(zz)
    Macro 小总结
    WPF应用的图标
    如何把 Visutal studio中的“printonbreakpoint”消息打印在程序的任何地方
  • 原文地址:https://www.cnblogs.com/Safe3/p/1315392.html
Copyright © 2020-2023  润新知