首页
论坛
课程
招聘
[原创]某6789安全卫士核心功能之InfinityHook (抄,我疯狂的抄)
2020-3-26 13:15 9614

[原创]某6789安全卫士核心功能之InfinityHook (抄,我疯狂的抄)

2020-3-26 13:15
9614
InfinityHook 核心原理 替换WmipLoggerContext[CLCK_INDEX]->GetCpuClock

原作者见 https://github.com/everdox/InfinityHook

from 6789base.sys version 5.12.0.4874

为节约版面以下只放关键内容

DriverEntry->InitializeInfinityHook()

启动两条线程,一条初始化infhook,一条保护infhook

__int64 InitializeInfinityHook()
{
  HANDLE ThreadHandle; // [rsp+40h] [rbp-58h]
  HANDLE Handle; // [rsp+48h] [rbp-50h]
  OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+50h] [rbp-48h]
  unsigned int v4; // [rsp+80h] [rbp-18h]

  v4 = -1073741823;
  ThreadHandle = 0i64;
  ObjectAttributes.Length = 0;
  memset(&ObjectAttributes.RootDirectory, 0, 0x28ui64);
  if ( byte_3648C )
    return 3221225473i64;
  stru_365D0.Count = 1;
  stru_365D0.Owner = 0i64;
  stru_365D0.Contention = 0;
  KeInitializeEvent(&stru_365D0.Event, SynchronizationEvent, 0);
  sub_22980(&unk_36608);
  KeInitializeEvent(&Event, NotificationEvent, 0);
  byte_36938 = 1;
  stru_36568.Count = 1;
  stru_36568.Owner = 0i64;
  stru_36568.Contention = 0;
  KeInitializeEvent(&stru_36568.Event, SynchronizationEvent, 0);
  ObjectAttributes.Length = 48;
  ObjectAttributes.RootDirectory = 0i64;
  ObjectAttributes.Attributes = 512;
  ObjectAttributes.ObjectName = 0i64;
  ObjectAttributes.SecurityDescriptor = 0i64;
  ObjectAttributes.SecurityQualityOfService = 0i64;
  v4 = PsCreateSystemThread(
         &ThreadHandle,
         0x1FFFFFu,
         &ObjectAttributes,
         0i64,
         0i64,
         (PKSTART_ROUTINE)InfinityHookInitThread,
         0i64);
  if ( !v4 )
    ZwClose(ThreadHandle);
  ObjectAttributes.Length = 48;
  ObjectAttributes.RootDirectory = 0i64;
  ObjectAttributes.Attributes = 512;
  ObjectAttributes.ObjectName = 0i64;
  ObjectAttributes.SecurityDescriptor = 0i64;
  ObjectAttributes.SecurityQualityOfService = 0i64;
  v4 = PsCreateSystemThread(
         &Handle,
         0x1FFFFFu,
         &ObjectAttributes,
         0i64,
         0i64,
         (PKSTART_ROUTINE)InitializeInfinityHookProtectThread,
         0i64);
  if ( !v4 )
  {
    ObReferenceObjectByHandle(Handle, 0x1FFFFFu, PsThreadType, 0, &g_ThreadObject, 0i64);
    ZwClose(Handle);
  }
  return v4;
}



void __fastcall InfinityHookInitThread(PVOID StartContext)
{
  __int64 _RAX; // rax
  LARGE_INTEGER (*_RCX)(); // rcx
  __int64 _RCX; // rcx
  LARGE_INTEGER Interval; // [rsp+20h] [rbp-28h]
  _QWORD *getCpuClock; // [rsp+28h] [rbp-20h]
  int v6; // [rsp+30h] [rbp-18h]

  v6 = -1073741823;
  getCpuClock = 0i64;
  Interval.QuadPart = -30000000i64;
  while ( !LoadNtdll() )
    KeDelayExecutionThread(0, 0, &Interval);
  if ( (int)InitializeInfhookCore() >= 0 )
  {
    v6 = EnableEtwLogger();
    if ( v6 >= 0 )
    {
      v6 = GetCkcl(2u, (_QWORD *)infhookCore + 90115);
      if ( v6 >= 0 && *((_QWORD *)infhookCore + 90115) )
      {
        getCpuClock = (_QWORD *)(*((_QWORD *)infhookCore + 90115)
                               + (unsigned int)OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK);
        if ( (unsigned __int8)MmIsAddressValid(getCpuClock)
          && (unsigned __int8)MmIsAddressValid((char *)getCpuClock + 7) )
        {
          if ( *getCpuClock >= MmSystemRangeStart )
          {
            _RAX = *((_QWORD *)infhookCore + 90115) + (unsigned int)OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK;
            _RCX = InternalGetCpuClock;
            __asm { xchg    rcx, [rax] }
            *((_QWORD *)infhookCore + 90114) = _RCX;
            v6 = 0;
          }
          else
          {
            v6 = 0xC0000001;
          }
        }
        else
        {
          v6 = 0xC0000001;
        }
      }
      else
      {
        v6 = 0xC0000001;
      }
    }
    else
    {
      v6 = 0xC0000001;
    }
  }
  else
  {
    v6 = 0xC0000001;
  }
  PsTerminateSystemThread(0);
}

NTSTATUS __stdcall EnableEtwLogger()
{
  NTSTATUS result; // eax
  NTSTATUS v1; // [rsp+20h] [rbp-18h]
  NTSTATUS v2; // [rsp+20h] [rbp-18h]

  v1 = IfhpModifyTraceSettings(1);
  if ( v1 >= 0 )
    goto LABEL_9;
  v2 = IfhpModifyTraceSettings(0);
  if ( v2 < 0 )
    return v2;
  v1 = IfhpModifyTraceSettings(1);
  if ( v1 >= 0 )
LABEL_9:
    result = v1;
  else
    result = v1;
  return result;
}

IfhModifyTraceSettings复制粘贴过于直球这里就不贴代码了,放个对比图:





主要流程:初始化infhookCore结构(应该是一个很大的结构体,具体成员就不逆了)

sub_2D210判断两个不明物体(无关紧要懒得逆)

寻找explorer.exe的PID

加载L"\\SystemRoot\\system32\\ntdll.dll"并搜索导出表,把nt函数全部保存进infhookcore里的一个表

NTSTATUS __stdcall InitializeInfhookCore()
{
  LARGE_INTEGER Interval; // [rsp+20h] [rbp-28h]
  NTSTATUS v2; // [rsp+28h] [rbp-20h]
  UNICODE_STRING DestinationString; // [rsp+30h] [rbp-18h]

  v2 = -1073741823;
  Interval.QuadPart = -30000000i64;
  if ( infhookCore && isZwTraceControlAvailable )
    return 0;
  while ( 1 )
  {
    if ( !infhookCore )
    {
      infhookCore = ExAllocatePoolWithTag(NonPagedPool, 720928ui64, 'hchk');
      if ( !infhookCore )
      {
        v2 = -1073741670;
        goto LABEL_26;
      }
      memset(infhookCore, 0, 0xB0020ui64);
    }
    if ( !*((_QWORD *)infhookCore + 90112) || !*((_QWORD *)infhookCore + 90113) )
    {
      v2 = sub_2D210((char *)infhookCore + 720896, (char *)infhookCore + 720904);
      if ( v2 < 0 || !*((_QWORD *)infhookCore + 90112) || !*((_QWORD *)infhookCore + 90113) )
      {
        v2 = -1073741823;
        goto LABEL_26;
      }
    }
    RtlInitUnicodeString(&DestinationString, L"explorer.exe");
    v2 = FindProcessByProcessName(&DestinationString, &g_ExplorerPID);
    if ( v2 >= 0 )
    {
      if ( g_ExplorerPID )
        break;
    }
    KeDelayExecutionThread(0, 0, &Interval);
  }
  v2 = LoadSSDTFunctionEntry();
  if ( v2 >= 0 )
  {
    v2 = LoadOffsetsVars();
    if ( v2 >= 0 )
    {
      v2 = LoadSSSDTFunctionEntry();
      if ( v2 >= 0 )
      {
        byte_3648D = 1;
        sub_2A640();
        ZwTraceControl = (__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD, _QWORD, _DWORD, _QWORD))MakeZwTraceControl();
        if ( ZwTraceControl )
        {
          isZwTraceControlAvailable = 1;
          v2 = 0;
        }
        else
        {
          v2 = -1073741823;
        }
      }
      else
      {
        v2 = -1073741823;
      }
    }
    else
    {
      v2 = -1073741823;
    }
  }
  else
  {
    v2 = -1073741823;
  }
LABEL_26:
  if ( v2 )
  {
    if ( infhookCore )
    {
      ExFreePoolWithTag(infhookCore, 0x6863686Bu);
      infhookCore = 0i64;
    }
  }
  return v2;
}

根据系统版本加载一些偏移

NTSTATUS __stdcall LoadOffsetsVars()
{
  NTSTATUS v1; // [rsp+20h] [rbp-18h]
  unsigned int v2; // [rsp+24h] [rbp-14h]

  v1 = 0;
  v2 = GetBuildNumber();
  if ( v2 > 14393 )
  {
    if ( v2 != 15063 && v2 != 16299 && v2 != 17134 && v2 != 17763 && v2 != 18362 )
      goto LABEL_18;
LABEL_17:
    LODWORD(OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK) = 40;
    offset_SystemCallNumber = 0x80i64;
    PerfGlobalGroupMask = GetPerfGlobalGroupMask();
    goto LABEL_18;
  }
  switch ( v2 )
  {
    case 14393u:
      goto LABEL_17;
    case 610u:
      LODWORD(OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK) = 24;
      offset_SystemCallNumber = 0x1F8i64;
      PerfGlobalGroupMask = GetPerfGlobalGroupMask2();
      break;
    case 620u:
      LODWORD(OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK) = 40;
      offset_SystemCallNumber = 0x80i64;
      PerfGlobalGroupMask = GetPerfGlobalGroupMask3();
      break;
    case 630u:
    case 10240u:
    case 10586u:
      goto LABEL_17;
  }
LABEL_18:
  if ( v2 > 18362 )
    v1 = FindOffsetsFor18383();
  return v1;
}

注意这里还会在KeReleaseSpinLock里面搜索PerfGlobalGroupMask

_int64 GetPerfGlobalGroupMask()
{
  _BYTE *v1; // [rsp+20h] [rbp-38h]
  unsigned int v2; // [rsp+28h] [rbp-30h]
  __int64 v3; // [rsp+30h] [rbp-28h]
  UNICODE_STRING DestinationString; // [rsp+40h] [rbp-18h]

  v2 = 0;
  v3 = 0i64;
  RtlInitUnicodeString(&DestinationString, L"KeReleaseSpinLock");
  v1 = MmGetSystemRoutineAddress(&DestinationString);
  if ( !v1 )
    return 0i64;
  while ( v2 < 0xA )
  {
    if ( v1[v2] == 0x40
      && v1[v2 + 1] == 0x53
      && v1[v2 + 2] == 0x48
      && (unsigned __int8)v1[v2 + 3] == 0x83
      && (unsigned __int8)v1[v2 + 6] == 0xF6
      && v1[v2 + 7] == 5 )
    {
      v3 = (__int64)&v1[*(unsigned int *)&v1[v2 + 8] + 7];
      if ( !(unsigned __int8)MmIsAddressValid(v3) || !(unsigned __int8)MmIsAddressValid(v3 + 15) )
        return 0i64;
      return v3;
    }
    ++v2;
  }
  return v3;
}





注意这个PerfGlobalGroupMask[2] & 0x40控制SYSTEM_CALL的etw记录是否开启

6789安全卫士为了不让自己的hook被关闭,会给这里监控并强制置位



LoadSSSDTFunctionEntry没什么可说的,和LoadSSDTFunctionEntry的唯一区别就是取entry之前先attach了explorer



从刚才获取的ssdt入口中取出ZwTraceControl(貌似6789安全卫士用的还是NtTraceControl?我没仔细看,但是如果是NtTraceControl的话我只能说这也太捞了吧,他不怕我蓝屏的吗?)

__int64 MakeZwTraceControl()
{
  __int64 result; // rax
  char *v1; // [rsp+20h] [rbp-18h]

  v1 = FindZwForSSDT("NtTraceControl");
  if ( v1 )
    result = *((_QWORD *)v1 + 42);
  else
    result = 0i64;
  return result;
}

获取ClckLoggerContext,根据版本不同获取方法还不一样

NTSTATUS __fastcall GetCkcl(unsigned int type, _QWORD *clck)
{
  NTSTATUS result; // eax
  unsigned int v3; // [rsp+20h] [rbp-18h]
  unsigned int typee; // [rsp+40h] [rbp+8h]
  _QWORD *clck_1; // [rsp+48h] [rbp+10h]

  clck_1 = clck;
  typee = type;
  v3 = GetBuildNumber();
  if ( v3 <= 14393 )
  {
    if ( v3 != 14393 )
    {
      switch ( v3 )
      {
        case 610u:
          return GetCkclWmiLoggerContext7601(typee, clck_1);
        case 620u:
          return GetCkclWmiLoggerContext9200(typee, clck_1);
        case 630u:
          return GetCkclWmiLoggerContext9600(typee, clck_1);
      }
      if ( v3 != 10240 && v3 != 10586 )
        goto LABEL_19;
    }
    return GetCkclWmiLoggerContext(typee, clck_1);
  }
  if ( v3 == 15063 || v3 == 16299 || v3 == 17134 || v3 == 17763 || v3 == 18362 )
    return GetCkclWmiLoggerContext(typee, clck_1);
LABEL_19:
  if ( v3 <= 18362 )
    result = 0xC0000001;
  else
    result = sub_2A0A0(typee, clck_1);
  return result;
}

7600 7601从EtwSendTraceBuffer里搜索WmipLoggerContext





9200(win8)9600(win8.1)也是同样的套路这里就不重复发了



win10上面使用经典的复制粘贴大法







这里不多说懂得都懂好吧

最后使用InterlockedExchange替换完getcpuclock指针初始化就算完成了

 getCpuClock = (_QWORD *)(*((_QWORD *)infhookCore + 90115)
                               + (unsigned int)OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK);
        if ( (unsigned __int8)MmIsAddressValid(getCpuClock)
          && (unsigned __int8)MmIsAddressValid((char *)getCpuClock + 7) )
        {
          if ( *getCpuClock >= MmSystemRangeStart )
          {
            _RAX = *((_QWORD *)infhookCore + 90115) + (unsigned int)OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK;
            _RCX = InternalGetCpuClock;
            __asm { xchg    rcx, [rax] }
            *((_QWORD *)infhookCore + 90114) = _RCX;
            v6 = 0;
          }

然后是它的保护线程

void __fastcall InitializeInfinityHookProtectThread(PVOID StartContext)
{
  LARGE_INTEGER Interval; // [rsp+30h] [rbp-28h]
  NTSTATUS v5; // [rsp+38h] [rbp-20h]
  LARGE_INTEGER Timeout; // [rsp+40h] [rbp-18h]
  __int64 ckcl; // [rsp+48h] [rbp-10h]

  Timeout.LowPart = 0;
  memset((char *)&Timeout.QuadPart + 4, 0, 4ui64);
  ckcl = 0i64;
  Interval.QuadPart = -10000000i64;
  if ( g_ThreadObject )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              v5 = KeWaitForSingleObject(&Event, Executive, 0, 0, &Timeout);
              if ( v5 != 0x102 )
              {
                PsTerminateSystemThread(0);
                return;
              }
              if ( infhookCore )
                break;
              KeDelayExecutionThread(0, 0, &Interval);
            }
            if ( *((_QWORD *)infhookCore + 90114) )
              break;
            KeDelayExecutionThread(0, 0, &Interval);
          }
          v5 = GetCkcl(2u, &ckcl);
          if ( v5 >= 0 )
            break;
          KeDelayExecutionThread(0, 0, &Interval);
        }
        if ( *((_QWORD *)infhookCore + 0x16003) != ckcl )
          break;
        if ( !*((_QWORD *)infhookCore + 0x16003) || !(unsigned __int8)MmIsAddressValid(*((_QWORD *)infhookCore + 90115)) )
          goto LABEL_27;
LABEL_16:
        if ( *(LARGE_INTEGER (**)())((unsigned int)OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK
                                   + *((_QWORD *)infhookCore + 90115)) != InternalGetCpuClock )
        {
          _RAX = *((_QWORD *)infhookCore + 0x16003) + (unsigned int)OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK;
          _RCX = InternalGetCpuClock;
          __asm { xchg    rcx, [rax] }
          *((_QWORD *)infhookCore + 90114) = _RCX;
        }
        if ( PerfGlobalGroupMask && !(*(_DWORD *)(PerfGlobalGroupMask + 8i64) & 0x40) )
          *((_QWORD *)infhookCore + 90115) = 0i64;
        else
LABEL_27:
          KeDelayExecutionThread(0, 0, &Interval);
      }
      v5 = EnableEtwLogger();
      if ( v5 >= 0 )
      {
        v5 = GetCkcl(2u, &ckcl);
        if ( v5 >= 0 )
        {
          *((_QWORD *)infhookCore + 90115) = ckcl;
          if ( *((_QWORD *)infhookCore + 90115) )
            goto LABEL_16;
          KeDelayExecutionThread(0, 0, &Interval);
        }
        else
        {
          KeDelayExecutionThread(0, 0, &Interval);
        }
      }
      else
      {
        KeDelayExecutionThread(0, 0, &Interval);
      }
    }
  }
}

流程大概是:

1、GetCkcl(2 获取clckloggercontext指针

2、如果infhookcore.clck指针不等于刚才获取的clck指针则重启clck logger(不等于说明有别人关闭了或者修改了clck logger)并设置 infhookcore.clck为新的clck logger

3、如果clck+offset_GetCpuClock处的函数指针不等于InternalGetCpuClock则替换函数指针为InternalGetCpuClock

4、如果PerfGlobalGroupMask[2] 不包含 0x40的bit(说明etw的SYSTEMCALL监控被人为关闭)则置infhookcore.clck为0,回到第2步(也就是自动重启clck logger

让我们看看 InternalGetCpuClock做了什么

LARGE_INTEGER InternalGetCpuClock()
{
  unsigned int walkTimes; // ecx
  char *hookEntry; // [rsp+20h] [rbp-58h]
  unsigned int j; // [rsp+30h] [rbp-48h]
  __int64 syscallFunction; // [rsp+48h] [rbp-30h]
  void **StackCurrent; // [rsp+50h] [rbp-28h]
  unsigned int walkStackOffset; // [rsp+60h] [rbp-18h]
  unsigned int syscallNumber; // [rsp+64h] [rbp-14h]
  void *retaddr; // [rsp+78h] [rbp+0h]

  j = 0;
  syscallNumber = GetSystemCallNumber();
  if ( (int)KeGetCurrentIrql() < 2 )
  {
    if ( ExGetPreviousMode() )
    {
      syscallFunction = GetSSDTEntryRoutine(syscallNumber);
      if ( syscallFunction )
      {
        hookEntry = GetSSDTHookEntry(syscallNumber);
        if ( hookEntry )
        {
          if ( *((_DWORD *)hookEntry + 65) || *((_DWORD *)hookEntry + 64) )
          {
            if ( (int)(unsigned __int8)hookEntry[332] <= 0 )
              walkStackOffset = 0;
            else
              walkStackOffset = 0x70;
            for ( StackCurrent = (void **)(__readgsqword(0x1A8u) - (walkStackOffset + 400i64));
                  StackCurrent > &retaddr;
                  --StackCurrent )
            {
              walkTimes = j++;
              if ( walkTimes >= 10 )
                break;
              if ( (unsigned __int8)MmIsAddressValid(StackCurrent) == 1
                && (unsigned __int8)MmIsAddressValid((char *)StackCurrent + 7) == 1
                && (void *)syscallFunction == *StackCurrent )
              {
                _RCX = NewSSDTRoutine;
                _RAX = StackCurrent;
                __asm { xchg    rcx, [rax] }
                return KeQueryPerformanceCounter(0i64);
              }
            }
          }
        }
      }
    }
  }
  return KeQueryPerformanceCounter(0i64);
}

__int64 GetSystemCallNumber()
{
  return *(_DWORD *)(offset_SystemCallNumber + PsGetCurrentThread()) & 0xFFFF;
}

__int64 __fastcall GetSSDTEntryRoutine(unsigned int syscallNumber)
{
  __int64 result; // rax
  char v2; // [rsp+20h] [rbp-18h]

  if ( syscallNumber < 0x1000 )
  {
    if ( syscallNumber < 0x400 )
      result = GetSSDTEntry(*((__int64 **)infhookCore + 90112), syscallNumber, &v2);
    else
      result = 0i64;
  }
  else if ( syscallNumber - 4096 < 0x400 )
  {
    result = GetSSDTEntry((__int64 *)(*((_QWORD *)infhookCore + 90113) + 32i64), syscallNumber - 4096, &v2);
  }
  else
  {
    result = 0i64;
  }
  return result;
}

首先:必须是来自用户模式的系统调用,并且irql小于DISPATCH_LEVEL

获取CurrentThread->SystemCallNumber 根据syscallnumber取ssdt function entry和hook entry(hookentry不一定有)

for ( StackCurrent = (void **)(__readgsqword(0x1A8u) - (walkStackOffset + 400i64));
                  StackCurrent > &retaddr;
                  --StackCurrent )
            {

从RspBase(gs:0x1A8)-0x70到_AddressOfReturnAddress进行栈遍历

找到(void *)syscallFunction == *StackCurrent的情况

则把 *StackCurrent替换为NewSSDTRoutine

NewSSDTRoutine 如下:

.text:0000000000030169 55                                                  push    rbp
.text:000000000003016A 48 8B EC                                            mov     rbp, rsp
.text:000000000003016D 9C                                                  pushfq
.text:000000000003016E 41 52                                               push    r10
.text:0000000000030170 48 81 EC C0 00 00 00                                sub     rsp, 0C0h
.text:0000000000030177 48 89 4D 10                                         mov     [rbp+arg_0], rcx
.text:000000000003017B 48 89 55 18                                         mov     [rbp+arg_8], rdx
.text:000000000003017F 4C 89 45 20                                         mov     [rbp+arg_10], r8
.text:0000000000030183 4C 89 4D 28                                         mov     [rbp+arg_18], r9
.text:0000000000030187 E8 C4 FF FF FF                                      call    GetSystemCallNumber
.text:000000000003018C 89 84 24 B8 00 00 00                                mov     [rsp+0D0h+var_18], eax
.text:0000000000030193 8B 8C 24 B8 00 00 00                                mov     ecx, [rsp+0D0h+var_18]
.text:000000000003019A 48 8D 55 10                                         lea     rdx, [rbp+arg_0]
.text:000000000003019E 4C 8D 84 24 B0 00 00 00                             lea     r8, [rsp+0D0h+var_20]
.text:00000000000301A6 E8 F5 95 FF FF                                      call    CallHookEntryRoutine
.text:00000000000301AB 83 F8 02                                            cmp     eax, 2
.text:00000000000301AE 48 8B 84 24 B0 00 00 00                             mov     rax, [rsp+0D0h+var_20]
.text:00000000000301B6 74 5B                                               jz      short loc_30213
.text:00000000000301B8 8B 8C 24 B8 00 00 00                                mov     ecx, [rsp+0D0h+var_18]
.text:00000000000301BF E8 CC 94 FF FF                                      call    GetSSDTEntryRoutine
.text:00000000000301C4 48 85 C0                                            test    rax, rax
.text:00000000000301C7 74 4A                                               jz      short loc_30213
.text:00000000000301C9 4C 8B D0                                            mov     r10, rax
.text:00000000000301CC 48 8D 75 30                                         lea     rsi, [rbp+arg_20]
.text:00000000000301D0 48 8D 7C 24 20                                      lea     rdi, [rsp+0D0h+var_B0]
.text:00000000000301D5 FC                                                  cld
.text:00000000000301D6 48 C7 C1 0E 00 00 00                                mov     rcx, 0Eh
.text:00000000000301DD F3 48 A5                                            rep movsq
.text:00000000000301E0 48 8B 4D 10                                         mov     rcx, [rbp+arg_0]
.text:00000000000301E4 48 8B 55 18                                         mov     rdx, [rbp+arg_8]
.text:00000000000301E8 4C 8B 45 20                                         mov     r8, [rbp+arg_10]
.text:00000000000301EC 4C 8B 4D 28                                         mov     r9, [rbp+arg_18]
.text:00000000000301F0 41 FF D2                                            call    r10
.text:00000000000301F3 48 89 84 24 B0 00 00 00                             mov     [rsp+0D0h+var_20], rax
.text:00000000000301FB 8B 8C 24 B8 00 00 00                                mov     ecx, [rsp+0D0h+var_18]
.text:0000000000030202 48 8D 55 10                                         lea     rdx, [rbp+arg_0]
.text:0000000000030206 4C 8B 84 24 B0 00 00 00                             mov     r8, [rsp+0D0h+var_20]
.text:000000000003020E E8 4D 96 FF FF                                      call    sub_29860
.text:0000000000030213
.text:0000000000030213                                     loc_30213:                              ; CODE XREF: NewSSDTRoutine+4D↑j
.text:0000000000030213                                                                             ; NewSSDTRoutine+5E↑j
.text:0000000000030213 48 8B 84 24 B0 00 00 00                             mov     rax, [rsp+0D0h+var_20]
.text:000000000003021B 48 81 C4 C0 00 00 00                                add     rsp, 0C0h
.text:0000000000030222 41 5A                                               pop     r10
.text:0000000000030224 9D                                                  popfq
.text:0000000000030225 5D                                                  pop     rbp
.text:0000000000030226 C3                                                  retn
.text:0000000000030226                                     NewSSDTRoutine  endp

hookentry里有八个函数指针(*(QWORD *)&hookEntry[16 * i + 8])当这个ssdt被调用时6789安全卫士就会帮我们call这八个entry (如果非0的话)

__int64 __fastcall CallHookEntryRoutine(unsigned int a1, __int64 a2, __int64 a3)
{
  unsigned int i; // [rsp+20h] [rbp-38h]
  char *hookEntry; // [rsp+30h] [rbp-28h]
  _QWORD *a3a; // [rsp+68h] [rbp+10h]
  __int64 a1a; // [rsp+70h] [rbp+18h]

  a1a = a3;
  a3a = (_QWORD *)a2;
  hookEntry = GetSSDTHookEntry(a1);
  if ( !hookEntry || !*((_DWORD *)hookEntry + 65) )
    return 1i64;
  for ( i = 0; i < 8; ++i )
  {
    if ( *(_QWORD *)&hookEntry[16 * i + 8]
      && (unsigned int)CallHookEntryRoutineInternal(
                         a1a,
                         *(__int64 (__fastcall **)(__int64, _QWORD, _QWORD, _QWORD))&hookEntry[16 * i + 8],
                         a3a) == 2 )
    {
      return 2i64;
    }
  }
  return 1i64;
}

__int64 __fastcall CallHookEntryRoutineInternal(__int64 a1, __int64 (__fastcall *fn)(__int64, _QWORD, _QWORD, _QWORD), _QWORD *a3)
{
  ULONG_PTR stackParameters[15]; // [rsp+20h] [rbp-A0h]

  qmemcpy(stackParameters, a3 + 3, sizeof(stackParameters));
  return fn(a1, *a3, a3[1], a3[2]);
}

如果CallHookEntryRoutine返回2的话就是拦截了这次系统调用,不调用原始函数

否则从infhookcore表中取出原始ssdt函数,把寄存器参数和栈参数恢复,call r10调用原始ssdt函数

.text:00000000000301C9 4C 8B D0                                            mov     r10, rax
.text:00000000000301CC 48 8D 75 30                                         lea     rsi, [rbp+arg_20]
.text:00000000000301D0 48 8D 7C 24 20                                      lea     rdi, [rsp+0D0h+var_B0]
.text:00000000000301D5 FC                                                  cld
.text:00000000000301D6 48 C7 C1 0E 00 00 00                                mov     rcx, 0Eh
.text:00000000000301DD F3 48 A5                                            rep movsq//memcpy恢复栈参数
.text:00000000000301E0 48 8B 4D 10                                         mov     rcx, [rbp+arg_0]//恢复寄存器参数
.text:00000000000301E4 48 8B 55 18                                         mov     rdx, [rbp+arg_8]
.text:00000000000301E8 4C 8B 45 20                                         mov     r8, [rbp+arg_10]
.text:00000000000301EC 4C 8B 4D 28                                         mov     r9, [rbp+arg_18]
.text:00000000000301F0 41 FF D2                                            call    r10 //原始SSDT函数


总结:这套代码好多地方都有蓝屏的隐患(比如 https://github.com/everdox/InfinityHook/issues/18 ),而且unistall的时候没法动态卸载驱动(什么?你不让用户卸载啊?那没事了)

喜讯:18950预览版已经把InfinityHook愉悦送走

6789安全卫士只看到了第二层,而他把微软想成了第一层,实际上微软在第五层



[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班开始招生!!

最后于 2020-3-26 13:16 被hzqst编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (21)
雪    币: 659
活跃值: 活跃值 (126)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mydvdf 活跃值 2020-3-26 13:33
2
0
大表哥牛逼
雪    币: 151
活跃值: 活跃值 (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
XSJJ 活跃值 2020-3-26 13:36
3
2
这波啊 这波是肉蛋葱鸡
雪    币: 3527
活跃值: 活跃值 (830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
boursonjane 活跃值 2020-3-26 13:50
4
0
前排占位,沙发自带
雪    币: 12297
活跃值: 活跃值 (948)
能力值: ( LV3,RANK:28 )
在线值:
发帖
回帖
粉丝
_重黎 活跃值 2020-3-26 14:02
5
0
xx卫士:下一个还真的是PG。
雪    币: 197
活跃值: 活跃值 (212)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdjytony 活跃值 2020-3-26 14:12
6
1
小飞:还是shark香吧
雪    币: 9751
活跃值: 活跃值 (2510)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
hzqst 活跃值 3 2020-3-26 14:57
7
0
XSJJ 这波啊 这波是肉蛋葱鸡[em_86]
这波啊,这波是CTRL+C V二连,他的一个不好的地方
雪    币: 4475
活跃值: 活跃值 (255)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
放学打我不 活跃值 1 2020-3-26 17:51
8
0
好几个大佬都走了.
雪    币: 388
活跃值: 活跃值 (252)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
wowocock 活跃值 1 2020-3-26 18:13
9
0
18950预览版已经把InfinityHook愉悦送走
最后于 2020-3-26 18:14 被wowocock编辑 ,原因:
雪    币: 8670
活跃值: 活跃值 (567)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
cvcvxk 活跃值 10 2020-4-4 16:15
10
0
wowocock 18950预览版已经把InfinityHook愉悦送走
欢声笑语中打出GG,用了8年的hook点被老外一朝爆料全部升天
雪    币: 44
活跃值: 活跃值 (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
古河面包店 活跃值 2020-4-8 11:02
11
0
cvcvxk 欢声笑语中打出GG,用了8年的hook点被老外一朝爆料全部升天
 = =
最后于 2020-4-8 11:15 被古河面包店编辑 ,原因:
雪    币: 86
活跃值: 活跃值 (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kongfubull 活跃值 2020-4-11 09:40
13
0
云里雾里
雪    币: 458
活跃值: 活跃值 (293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
青丝梦 活跃值 2020-4-11 10:26
15
1
精通一百种锁主页的方法
雪    币: 1397
活跃值: 活跃值 (276)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hekes 活跃值 2020-4-11 14:08
16
0
mark
雪    币: 66
活跃值: 活跃值 (273)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tmflxw 活跃值 2020-5-6 00:42
17
0
从刚才获取的ssdt入口中取出ZwTraceControl(貌似6789安全卫士用的还是NtTraceControl?我没仔细看,但是如果是NtTraceControl的话我只能说这也太捞了吧,他不怕我蓝屏的吗?)

这句话什么意思呢?为什么说使用NtTraceControl怕蓝屏? 我在7600版本上看了没有ZwTraceControl
雪    币: 243
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
星辰无大海 活跃值 2020-8-21 05:01
18
0
请问下,  使用 win7  7601 版本 NtTraceControl启动蓝屏, 可否告知是何原因,或者告知要往哪块分析去解决。  谢谢!
雪    币: 9751
活跃值: 活跃值 (2510)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
hzqst 活跃值 3 2020-8-21 11:01
19
0
星辰无大海 请问下, 使用 win7 7601 版本 NtTraceControl启动蓝屏, 可否告知是何原因,或者告知要往哪块分析去解决。 谢谢!
https://github.com/everdox/InfinityHook/issues/7  求求你们先看看原作者的github再来提问
雪    币: 243
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
星辰无大海 活跃值 2020-8-22 21:55
20
0
hzqst https://github.com/everdox/InfinityHook/issues/7 求求你们先看看原作者的github再来提问
谢谢表哥,问题已经得到了解决,刚入门不是很懂,以后会自己多看看
雪    币: 7
活跃值: 活跃值 (206)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ybt 活跃值 2020-12-29 16:10
21
0

挺郁闷的,我本来想自己逆下2345安全卫士的驱动,结果在Win7 x64虚拟机下,试了三次,都是安装卡死在进度98%,并附带电脑死机。重启后,发现压根没安装。。。

最后于 2020-12-29 16:10 被ybt编辑 ,原因:
雪    币: 2346
活跃值: 活跃值 (1841)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
低调putchar 活跃值 1 2020-12-30 22:45
22
0

    WIN10以下的系统还有一种获取WmipLoggerContext的方法,
就是从已导出的nt!EtwSendTraceBuffer函数中进行特征码暴搜,找到WmipLoggerContext相对于ntoskrnl.exe的偏移(RVA)从而计算得到WmipLoggerContext的地址, WmipLoggerContext[2]->GetCpuClock就是需要替换的了。 方法不错!嗯!哪阵可以还可以再用这个方法试下WIN10以下的系统!

    多看高手分析再加以实践就能不断得到提高!感谢前辈分享!

最后于 2020-12-30 22:56 被低调putchar编辑 ,原因:
游客
登录 | 注册 方可回帖
返回