ring0级暴力搜索内存检测系统隐藏进程(或Rootkit)

来源:互联网 发布:unity 棋牌源码 编辑:程序博客网 时间:2024/05/29 08:38
#include<ntddk.h>//EPROCESS结构大小,我的系统是XP SP3,所以0x260,不过经过测试,这里设置成比实际EPROCESS小也是没问题的#define  EPROCESS_SIZE       0x260 #define  PEB_OFFSET          0x1B0        //PEB偏移,下面就不注释了#define  FILE_NAME_OFFSET    0x174#define  PROCESS_LINK_OFFSET 0x088#define  PROCESS_ID_OFFSET   0x084#define  EXIT_TIME_OFFSET    0x078#define  OBJECT_HEADER_SIZE  0x018#define  OBJECT_TYPE_OFFSET  0x008ULONG        ulPebAddress;                        //PEB地址的前半部分ULONG        ulStartAddress, ulEndAddress;        //起始,结束地址ULONG        ulObjectType;                        //进程对象类型BOOLEAN        IsaRealProcess(ULONG pEprocess);    //该函数判断是否真的是进程VOID        WorkThread(IN PVOID pContext);        //新开线程防止系统顿卡VOID        UpdateEndStartPebAddress();            //更新首尾地址和PEB地址VOID        EnumProcess();                        //枚举进程VOID        ShowProcess(ULONG pEProcess);        //显示进程信息VOID OnUnload(IN PDRIVER_OBJECT DriverObject){}NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){    HANDLE hThread;    DriverObject -> DriverUnload = OnUnload;    UpdateEndStartPebAddress();    ulObjectType = *(PULONG)((ULONG)ulEndAddress - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET);    PsCreateSystemThread(&hThread,        (ACCESS_MASK)0,        NULL,         (HANDLE)0,         NULL,         WorkThread,         NULL );     return STATUS_SUCCESS;}//////////////////////////////////////////////VOID WorkThread(IN PVOID pContext){     EnumProcess();    PsTerminateSystemThread(STATUS_SUCCESS);}////////////////////////////////////////////////////////VOID UpdateEndStartPebAddress(){    ULONG ulEProcessAddress = (ULONG)IoGetCurrentProcess();    ULONG pEProcess;    //IoGetCurrentProcess返回的是System进程EPROCESS结构地址,此处已经是搜索结束处。    ulStartAddress = ulEndAddress = ulEProcessAddress;    ulEProcessAddress = (ULONG)(((PLIST_ENTRY)(ulEProcessAddress + PROCESS_LINK_OFFSET))->Flink) - PROCESS_LINK_OFFSET;    ulPebAddress = *(PULONG)(ulEProcessAddress + PEB_OFFSET) & 0xFFFF0000;    while (ulEProcessAddress != ulEndAddress)     {        //遍历EPROCESS结构,找到最小地址处        ulEProcessAddress = (ULONG)(((PLIST_ENTRY)(ulEProcessAddress + PROCESS_LINK_OFFSET))->Flink) - PROCESS_LINK_OFFSET;        if (ulStartAddress > ulEProcessAddress)            ulStartAddress = ulEProcessAddress;    }}///////////////////////////////////////////////////////VOID EnumProcess(){    ULONG  i;    ULONG nCount = 2;    ULONG  Address;    ULONG  ret;    KdPrint(("-------------------------------------------\r\n"));    KdPrint(("EProcess    PID    ImageFileName\r\n"));    KdPrint(("-------------------------------------------\r\n"));    //系统空闲进程的检测方法有点特殊,只作参考    ShowProcess(*(PULONG)(ulStartAddress + PROCESS_ID_OFFSET));    //system的PEB总是零 上面的方法是枚举不到的 不过我们用PsGetCurrentProcess就能得到了    ShowProcess(ulEndAddress);    for(i = ulStartAddress; i < ulEndAddress; i += 4) {//system进程的EPROCESS地址就是最大值了        if (MmIsAddressValid((PVOID)i)) {            Address = *(PULONG)i;            if (( Address & 0xFFFF0000) == ulPebAddress){//每个进程的PEB地址都是在差不多的地方,地址前半部分是相同的                       if (IsaRealProcess(i)) {                    ShowProcess(i - PEB_OFFSET);                    i -= 4;                    i += EPROCESS_SIZE;                    nCount ++;                }            }        } else {            i -= 4;            i += 0x5000000;//5M        }    }        KdPrint(("-------------------------------------------\r\n"));    KdPrint(("=====   Total Processes count:%3d   =======\r\n", nCount));    KdPrint(("-------------------------------------------\r\n"));}/////////////////////////////////////////////////////////VOID ShowProcess(ULONG pEProcess){    PLARGE_INTEGER ExitTime;    ULONG PID;    PUCHAR pFileName;    ExitTime = (PLARGE_INTEGER)(pEProcess + EXIT_TIME_OFFSET);    if(ExitTime->QuadPart != 0) //已经结束的进程的ExitTime为非零        return ;    PID = *(PULONG)(pEProcess + PROCESS_ID_OFFSET);    pFileName = (PUCHAR)(pEProcess + FILE_NAME_OFFSET);    KdPrint(("0x%08X  %04d   %s\r\n",pEProcess,PID,pFileName));}////////////////////////////////////////////////////////////////BOOLEAN IsaRealProcess(ULONG pEprocess){    NTSTATUS STATUS;    PUNICODE_STRING pUnicode;    UNICODE_STRING Process;    ULONG pObjectType;    ULONG ObjectTypeAddress;    if (!MmIsAddressValid((PVOID)(pEprocess - PEB_OFFSET)))        return FALSE;    ObjectTypeAddress = pEprocess - PEB_OFFSET - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET ;    if (MmIsAddressValid((PVOID)ObjectTypeAddress)) {        pObjectType = *(PULONG)ObjectTypeAddress;    } else {        return FALSE;    }    if(ulObjectType == pObjectType) {//确定ObjectType是Process类型        return TRUE;    }    return FALSE;}