zoukankan      html  css  js  c++  java
  • 一份非常棒的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;
    }
  • 相关阅读:
    SharePoint 2013 商务智能报表发布
    sharepoint designer web 服务器似乎没有安装microsoft sharepoint foundation
    SharePoint 2013 Designer系列之数据视图
    SharePoint 2013 Designer系列之数据视图筛选
    SharePoint 2013 Designer系列之自定义列表表单
    SharePoint 2013 入门教程之创建及修改母版页
    SharePoint 2013 入门教程之创建页面布局及页面
    SharePoint 2010 级联下拉列表 (Cascading DropDownList)
    使用SharePoint Designer定制开发专家库系统实例!
    PL/SQL Developer 建立远程连接数据库的配置 和安装包+汉化包+注册机
  • 原文地址:https://www.cnblogs.com/Safe3/p/1315381.html
Copyright © 2011-2022 走看看