首页
社区
课程
招聘
[求助]ZwQuerySystemInformation隐藏进程前为什么要先脱钩?
发表于: 2016-4-25 20:27 5290

[求助]ZwQuerySystemInformation隐藏进程前为什么要先脱钩?

2016-4-25 20:27
5290
通过API代码修改的方式Hook了ZwQuerySystemInformation

但是不理解为啥呢么在删除进程链表之前要先脱钩执行一次ZwQuerySystemInformation

代码如下
NTSTATUS WINAPI NewZwQuerySystemInformation(
  SYSTEM_INFORMATION_CLASS SystemInformationClass,
  PVOID SystemInformation,
  ULONG SystemInformationLength,
  PULONG ReturnLength)
{
  NTSTATUS status;
  FARPROC pFunc;
  PSYSTEM_PROCESS_INFORMATION pCur, pPrev;
  char szProcName[MAX_PATH] = { 0, };

  //开始之前先脱钩
  unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, g_pOrgBytes);

  //通过GetProcAddress调用原始API
  pFunc = GetProcAddress(GetModuleHandleA(DEF_NTDLL), DEF_ZWQUERYSYSTEMINFORMATION);
  status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
  if (status != STATUS_SUCCESS)
    goto __NTQUERYSYSTEMINFORMATION_END;

  //仅针对SystemProcessInformation类型操作
  if (SystemInformationClass == SystemProcessInformation)
  {
    //SYSTEM_PROCESS_INFORMATION类型转换
    //pCur是单向链表的头
    pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;

    //开始遍历链表
    while (TRUE)
    {
      
      if (pCur->Reserved2[1] != NULL)
      {
        //比较进程名字是否是我们的目的进程
        if (!_tcsicmp((PWSTR)pCur->Reserved2[1], g_szProcName))
        {
          //如果是,判断是否位于链表尾部
          //如果在链表尾部,就把前一个节点的Next设为0,直接丢弃掉目的进程的信息
          //如果不是尾部,则需要跳过目的进程,方法是让前一个的Next指向目的进程的后一个进程,而不是指向目的进程
          if (pCur->NextEntryOffset == 0)
            pPrev->NextEntryOffset = 0;
          else
            pPrev->NextEntryOffset += pCur->NextEntryOffset;
        }
        else
          //更新前一个节点
          pPrev = pCur;
      }

      //如果遍历完链表,则退出
      if (pCur->NextEntryOffset == 0)
        break;

      //更新当前节点,得到下一个节点的位置
      pCur = (PSYSTEM_PROCESS_INFORMATION)((ULONGLONG)pCur + pCur->NextEntryOffset);
    }
  }
__NTQUERYSYSTEMINFORMATION_END:
  hook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, (PROC)NewZwQuerySystemInformation, g_pOrgBytes);
  return status;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 112
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这个写法太蛋疼了吧,就算是写Inline HOOK也不要脱钩啊,
总的来说在NewNtQuerySystemInformation中调用原始NtQuerySystemInformation获取到信息后,操作返回信息结构的链表就ok了,SSDT HOOK不行么?
2016-4-25 21:07
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我才开始API Hook这一块,还没有接触到SSDT Hook。
您的意思我不太明白,能够稍微清楚些么。
这段代码假如跳过脱钩后执行原始API的那一步,直接遍历链表为什么不行呢?
链表不是以参数的形式传入的嘛
执行原始API的目的何在?
2016-4-25 21:21
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
脱钩的意义在于走一次原始流程, 对下层函数返回的结果动手脚, 再返回给上层
只是脱钩的方法比较low, 很少有人那么干
试想一下, 你钩了这个函数, 还需要调用原函数, 不脱钩的话还会走到自己的函数里, 这不就是死递归了吗
2016-4-25 21:36
0
雪    币: 96
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
一般的hook 都需要脱钩-执行代码-安装钩子。
这是HOOK流程,调用函数前要还原函数头。
2016-4-25 21:41
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢,我懂了。请问下较为流行的ZwquerySystemInformation钩取方式是什么,希望改进下代码
2016-4-25 21:54
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢,我懂了
2016-4-25 22:01
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
方法1: 把你做hook时覆盖掉的指令拷贝的别的地方(称作P1), 在P1后添加JMP指令跳到原函数你覆盖指令的后面
例子, 被hook后的流程为
JMP 过滤函数 // 假设你覆盖掉了C1和C2指令
C3
C4
.......
而P1的流程为
C1
C2
JMP C3的地址
这样你在过滤函数里直接CALL P1就可以调用原函数, 绕过了你的inline hook, 而且不用脱钩
缺点是如果大家都钩在同一个位置, 崩溃

方法2: 直接DUMP完整函数出来, 再INLINE, 需要的时候CALL DUMP出来的函数, 不走原始代码.
自己凑个DISASM库就能搞出来
个人感觉没啥缺点, 就是DUMP的解析要稳定, 否则修正的地址不对的话也是会崩溃的
而且没有方法1的冲突问题
2016-4-25 22:39
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
另外, 我说的方法仅适用于在函数头部第一句指令下钩子的情况
2016-4-25 22:45
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
多谢,受教了
2016-4-25 23:12
0
雪    币: 286
活跃值: (67)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
xjj
11
直接HOOK函数的尾部,在ret前,这个时候你要的信息已经执行完,你可以直接处理你要断链的信息,然后返回

这样就不用考虑HOOK->UNHOOK->HOOK了
2016-4-26 09:43
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
但是如何知道函数的长度呢?
2016-4-26 16:05
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
13
脱钩是一种非常Low的做法。。。一般都是直接走Trampoline的
2016-4-26 19:13
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
脱钩这样的HOOK方法貌似是单核年代     也就是0几年初那会  常见的方式
      进入双核年代就没人这么干了      流程重复  安全性低         如果是内核这样搞很容易蓝
2016-5-3 10:10
0
雪    币: 12
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
确实很少见了..网上随便找几个hook库看看就好了,
这种确实有点危险,
2016-5-6 08:27
0
雪    币: 441
活跃值: (1060)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
16
mark
2016-5-19 13:43
0
雪    币: 0
活跃值: (954)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
17
SSDT ZwQuerySystemInformation Patch
2016-5-19 13:45
0
游客
登录 | 注册 方可回帖
返回
//