zoukankan      html  css  js  c++  java
  • pg3 bypass源码阅读 —— 学习x64内核hook跳板技术

    如之前描述的 pg3复杂了许多

    先来看看都要hook哪些点

    1、hook dpc和定时器分发器,防止seh路线触发pg

    KiTimerListExpire,KiRetireDpcList

    看一下hook点

    hook的就是call的位置。

    这里有两种方案:一种是直接jmp + 64bit addr,显然有同步问题,需要暂停所有cpu然后把irql提升到HIGH_LEVEL去操作。

    另一种是 call 32bit 跳板 addr,如下图,操作8byte符合原子操作

    e8 xxxxxxxx是32位转移,我们需要一个nt范围内的跳板,作者是这样处理的。把KiCustomAccessRoutine4跳转到KiCustomAccessRoutine0,那么KiCustomAccessRoutine4后面的代码就可以随便改了,不需要原子操作,这是一个技巧。

    1.  
      void VistaAll_DpcInterceptor(
    2.  
      PKDPC InDpc,
    3.  
      PVOID InDeferredContext,
    4.  
      PVOID InSystemArgument1,
    5.  
      PVOID InSystemArgument2)
    6.  
      {
    7.  
      ULONGLONG Routine = (ULONGLONG)InDpc->DeferredRoutine;
    8.  
       
    9.  
      __try
    10.  
      {
    11.  
      if((Routine >= 0xFFFFFA8000000000) && (Routine <= 0xFFFFFAA000000000))
    12.  
      {
    13.  
      }
    14.  
      else
    15.  
      if(KeContainsSymbol((void*)Routine))
    16.  
      {
    17.  
      if(!PgIsPatchGuardContext(InDeferredContext))
    18.  
      InDpc->DeferredRoutine(InDpc, InDeferredContext, InSystemArgument1, InSystemArgument2);
    19.  
      }
    20.  
      else
    21.  
      InDpc->DeferredRoutine(InDpc, InDeferredContext, InSystemArgument1, InSystemArgument2);
    22.  
      }
    23.  
      __except(EXCEPTION_EXECUTE_HANDLER)
    24.  
      {
    25.  
      }
    26.  
      }

    fake dpc的处理非常简单,判断dpc context即可

    2.hook ExpWorkerThread 工作线程也有可能触发pg,hook方法同上,fake函数如下

    1.  
      VOID VistaAll_ExpWorkerThreadInterceptor(PWORKER_THREAD_ROUTINE InRoutine, VOID* InContext, VOID* InRSP)
    2.  
      {
    3.  
      ULONGLONG Val = (ULONGLONG)InRoutine;
    4.  
       
    5.  
      if((Val >= 0xfffffa8000000000) && (Val <= 0xfffffaa000000000))
    6.  
      return;
    7.  
       
    8.  
      __try
    9.  
      {
    10.  
      InRoutine(InContext);
    11.  
      }
    12.  
      __except(EXCEPTION_EXECUTE_HANDLER)
    13.  
      {
    14.  
      }
    15.  
      }

    过滤了所有内核的work thread,工作线程是non-seh mode,无法过滤非传统地址,所以过滤了所有的nt工作线程。。总是系统跑起来之后也不会再排新的工作线程就是了。

    3.这样还不够,hook KeBugcheckEx作为补充,KeBugcheckEx是被PG循环恢复的,但是分析代码KeBugcheckEx一开始就调用到RtlCaptureContext,所以转去hook RtlCaptureContext,还是用跳板函数,用到了栈回溯

    1.  
      RtlCaptureContext_Hook PROC
    2.  
       
    3.  
      ; call high level handler without messing up the context structure...
    4.  
      push rcx
    5.  
      push rdx
    6.  
      push r8
    7.  
      push r9
    8.  
      push r10
    9.  
      push r11
    10.  
      mov rcx, qword ptr[rsp + 128]
    11.  
      mov rdx, qword ptr[rsp + 7 * 8]
    12.  
      sub rsp, 32
    13.  
      call KeBugCheck_Hook
    14.  
      mov qword ptr [rsp], rax
    15.  
      add rsp, 32
    16.  
      pop r11
    17.  
      pop r10
    18.  
      pop r9
    19.  
      pop r8
    20.  
      pop rdx
    21.  
      pop rcx
    22.  
      pop rax
    23.  
       
    24.  
      ; recover destroyed bytes of RtlCaptureContext
    25.  
      pushfq
    26.  
      mov word ptr [rcx+38h],cs
    27.  
      mov word ptr [rcx+3Ah],ds
    28.  
      mov word ptr [rcx+3Ch],es
    29.  
      mov word ptr [rcx+42h],ss
    30.  
       
    31.  
      ; jump behind destroyed bytes... (RetVal of RtlCaptureContext_HookEx)
    32.  
      jmp qword ptr[rsp - 32 - 8 * 7 + 8]
    33.  
       
    34.  
      RtlCaptureContext_Hook ENDP

    fake函数将pg进入死循环
    1.  
      ULONGLONG KeBugCheck_Hook(ULONGLONG InBugCode, ULONGLONG InCaller)
    2.  
      {
    3.  
      FAST_MUTEX WaitAlways;
    4.  
       
    5.  
      //判断调用者
    6.  
      if((InCaller >= KeBugCheckEx_Sym) && (InCaller <= KeBugCheckEx_Sym + 100))
    7.  
      {
    8.  
      if(InBugCode == CRITICAL_STRUCTURE_CORRUPTION)
    9.  
      {
    10.  
      // KeBugCheckEx disables interrupts before calling RtlCaptureContext()
    11.  
      EnableInterrupts();
    12.  
       
    13.  
      //进入死循环
    14.  
      ExInitializeFastMutex(&WaitAlways);
    15.  
      ExAcquireFastMutex(&WaitAlways);
    16.  
      ExAcquireFastMutex(&WaitAlways);
    17.  
      }
    18.  
      }
    19.  
       
    20.  
      //返回跳转地址
    21.  
      return RtlCaptureContext_Sym + 14;
    22.  
      }


    jpg 改 rar 


  • 相关阅读:
    学习Asp.Net经常会用到的函数集
    string.Format 格式化时间,货币
    sqlite相关
    sql常用判断语句
    ToString() 格式 用法大全 保留 两位 小数
    一些常用短代码,页面缓存啥的
    判断iE并创建A标签
    Java学习之数组1(1.数组的声明;2.元素为引用数据类型的数组;3.关于main方法里的String[] args;4.数组排序;5.数3退1 数组算法,(用数组模拟链表);6数组查找之二分法;7数组的拷贝)
    Java学习之异常处理()
    Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与LinkedHashSet类))
  • 原文地址:https://www.cnblogs.com/kuangke/p/9397533.html
Copyright © 2011-2022 走看看