RING0级暴力搜索内存检测系统隐藏进程(或ROOTKIT)(实测可运行) .

来源:互联网 发布:淘宝优惠券shipinwj 编辑:程序博客网 时间:2024/06/07 10:28

最近期末答辩不知道写什么好,就写一个安全软件吧。软件使用驱动和C++编写,大概多数安全软件都是这样吧。
时间关系,就不说那么多了,直接入正题吧。
在此先感谢“伊丽_杀_白”、“堕落天才”、“antirootkit”等提供的优秀文章,我只是在他们基础之上修改了一下。

伊丽_杀_白    暴力搜索内存空间检测隐藏进程:
http://bbs.xdnice.com/thread-377796-1-1.html

堕落天才        ring0检测隐藏进程:http://bbs.pediy.com/showthread.php?t=44243

antirootkit        枚举隐藏进程for ring0(搜索内存大法):http://hi.baidu.com/antirootkit/blog/item/d2314b5c94772040fbf2c00b.html 

原理:
大概流程图如下,当然我修改了部分。




下面看代码吧,没时间了,等下十点还要上课,有不明白的可以留言。我会解答的。
 
不过这种方法还是很容易躲过,详细就不公布出来了,看来还是要找另外一种方法了。

 

 

 

#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;}