• 一份非常棒的inline hook代码


    #include <ntddk.h> 
    #include <ntifs.h>
    #include <windef.h>
    ULONG g_KiInsertQueueApc;
    ULONG g_uCr0;

    BYTE g_HookCode[5] = { 0xe9, 0, 0, 0, 0 };
    BYTE g_OrigCode[5] = { 0 }; // 原函数的前字节内容
    BYTE jmp_orig_code[7] = { 0xEA, 0, 0, 0, 0, 0x08, 0x00 }; 

    BOOL g_bHooked = FALSE;

    VOID
    fake_KiInsertQueueApc (
        PKAPC Apc,
        KPRIORITY Increment
        );
        
    VOID
    Proxy_KiInsertQueueApc (
        PKAPC Apc,
        KPRIORITY Increment
        );

    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;
        };
       
    }


    //
    // 停止inline hook
    //
    VOID UnHookKiInsertQueueApc ()
    {
        KIRQL  oldIrql;

        WPOFF();
        oldIrql = KeRaiseIrqlToDpcLevel();
        
        RtlCopyMemory ( (BYTE*)g_KiInsertQueueApc, g_OrigCode, 5 );

        KeLowerIrql(oldIrql);
        WPON();

        g_bHooked = FALSE;
    }


    //
    // 开始inline hook --  KiInsertQueueApc
    //
    VOID HookKiInsertQueueApc ()

        KIRQL  oldIrql;

        if (g_KiInsertQueueApc == 0) {
            DbgPrint("KiInsertQueueApc == NULL\n");
            return;
        }

        //DbgPrint("开始inline hook --  KiInsertQueueApc\n");
        DbgPrint( "KiInsertQueueApc的地址t0x%08x\n", (ULONG)g_KiInsertQueueApc );
        // 保存原函数的前字节内容
        RtlCopyMemory (g_OrigCode, (BYTE*)g_KiInsertQueueApc, 5);
        *( (ULONG*)(g_HookCode + 1) ) = (ULONG)fake_KiInsertQueueApc - (ULONG)g_KiInsertQueueApc - 5;
        
        
        // 禁止系统写保护,提升IRQL到DPC
        WPOFF();
        oldIrql = KeRaiseIrqlToDpcLevel();
     
        RtlCopyMemory ( (BYTE*)g_KiInsertQueueApc, g_HookCode, 5 );
        *( (ULONG*)(jmp_orig_code + 1) ) = (ULONG) ( (BYTE*)g_KiInsertQueueApc + 5 );
        
        RtlCopyMemory ( (BYTE*)Proxy_KiInsertQueueApc, g_OrigCode, 5);
        RtlCopyMemory ( (BYTE*)Proxy_KiInsertQueueApc + 5, jmp_orig_code, 7);

        // 恢复写保护,降低IRQL
        KeLowerIrql(oldIrql);
        WPON();

        g_bHooked = TRUE;
        
        
    }

    //
    // 跳转到我们的函数里面进行预处理
    //
    __declspec (naked) 
    VOID
    fake_KiInsertQueueApc (
        PKAPC Apc,
        KPRIORITY Increment
        )
    {
      

        // 去掉DbgPrint,不然这个hook会产生递归
        //DbgPrint("inline hook --  KiInsertQueueApc 成功\n");
      
        __asm
        {
                   jmp Proxy_KiInsertQueueApc
        }
    }

    //
    // 代理函数,负责跳转到原函数中继续执行
    //
    __declspec (naked) 
    VOID
    Proxy_KiInsertQueueApc (
        PKAPC Apc,
        KPRIORITY Increment
        )
    {
      
        __asm {  // 共字节
                _emit 0x90
                _emit 0x90
                _emit 0x90
                _emit 0x90
                _emit 0x90  // 前字节实现原函数的头字节功能
                _emit 0x90  // 这个填充jmp
                _emit 0x90
                _emit 0x90
                _emit 0x90
                _emit 0x90  // 这字节保存原函数+5处的地址
                _emit 0x90  
                _emit 0x90  // 因为是长转移,所以必须是0x0080
        }
    }




    ULONG GetFunctionAddr( IN PCWSTR FunctionName)
    {
        UNICODE_STRING UniCodeFunctionName;
        RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
        return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );   

    }

    //根据特征值,从KeInsertQueueApc搜索中搜索KiInsertQueueApc
    ULONG FindKiInsertQueueApcAddress()
    {
      char * Addr_KeInsertQueueApc = 0;
      int i = 0;
      char Findcode[] = { 0xE8, 0xcc, 0x29, 0x00, 0x00 };
      ULONG Addr_KiInsertQueueApc = 0;
        Addr_KeInsertQueueApc = (char *) GetFunctionAddr(L"KeInsertQueueApc");
      for(i = 0; i < 100; i ++)
      {
            if( Addr_KeInsertQueueApc[i] == Findcode[0] &&
          Addr_KeInsertQueueApc[i + 1] == Findcode[1] &&
          Addr_KeInsertQueueApc[i + 2] == Findcode[2] &&
          Addr_KeInsertQueueApc[i + 3] == Findcode[3] &&
          Addr_KeInsertQueueApc[i + 4] == Findcode[4] 
          )
        {
          Addr_KiInsertQueueApc = (ULONG)&Addr_KeInsertQueueApc[i] + 0x29cc + 5;
          break;
        }
      }
      return Addr_KiInsertQueueApc;
    }


    VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
    {
      DbgPrint("My Driver Unloaded!");
      UnHookKiInsertQueueApc();
    }

    NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
    {
      DbgPrint("My Driver Loaded!");
      theDriverObject->DriverUnload = OnUnload;
        
      g_KiInsertQueueApc = FindKiInsertQueueApcAddress();
      HookKiInsertQueueApc();

      return STATUS_SUCCESS;
    }
  • 相关阅读:
    我好久没在这上面写东西了,一部分东西都放到有道云笔记上了
    bootstrop 瀑布流
    css3瀑布流
    简洁瀑布流
    Nginx配置文件nginx.conf中文详解
    CSS选择器详解
    CSS3制作各种形状图像
    wen zi gun dong
    下拉菜单
    div
  • 原文地址:https://www.cnblogs.com/Safe3/p/1315381.html
Copyright © 2020-2023  润新知