标 题:
【原创】ring0检测隐藏进程
作 者: 堕落天才 时 间: 2007-05-10,13:28 链 接: http://bbs.pediy.com/showthread.php?t=44243 //网上得到一篇好文章 Ring0下搜索内存枚举隐藏进程 ,但是拿里面的代码来使用的时候发现并没有太多效果 //于是修改之,终于实现了最初的目标 //由于直接搜索内存,跟系统调度没什么关系,所以能够枚举到各种方法隐藏的进程 包括断链、抹PspCidTable... //甚至能枚举到已经"死掉"的进程,本程序通过进程的ExitTime来判断进程是不是已经结束 //除非能够把EProcess结构修改掉,但这个实现难度可能比较大,不知有没有哪位大侠试过(PID我修改过),欢迎讨论 // //作者:堕落天才 //时间:2007年5月10日 //参考: uty Ring0下搜索内存枚举隐藏进程 http://www.cnxhacker.net/Article/show/3412.html //下面代码在XP SP2测试通过 #include<ntddk.h> ///不同的windows版本下面的偏移值不同 #define EPROCESS_SIZE 0x25C //EPROCESS结构大小 #define PEB_OFFSET 0x1B0 #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 0x008 #define PDE_INVALID 2 #define PTE_INVALID 1 #define VALID 0 ULONG pebAddress; //PEB地址的前半部分 PEPROCESS pSystem; //system进程 ULONG pObjectTypeProcess; //进程对象类型 ULONG VALIDpage(ULONG addr) ; //该函数直接复制自 Ring0下搜索内存枚举隐藏进程 BOOLEAN IsaRealProcess(ULONG i); //该函数复制自 Ring0下搜索内存枚举隐藏进程 VOID WorkThread(IN PVOID pContext); ULONG GetPebAddress(); //得到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; pSystem = PsGetCurrentProcess(); pebAddress = GetPebAddress(); pObjectTypeProcess = *(PULONG)((ULONG)pSystem - 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); } ULONG GetPebAddress() { ULONG Address; PEPROCESS pEProcess; //由于system进程的peb总是零 我们只有到其他进程去找了 pEProcess = (PEPROCESS)((ULONG)((PLIST_ENTRY)((ULONG)pSystem + PROCESS_LINK_OFFSET))->Flink - PROCESS_LINK_OFFSET); Address = *(PULONG)((ULONG)pEProcess + PEB_OFFSET); return (Address & 0xFFFF0000); } /// VOID EnumProcess() { ULONG uSystemAddress = (ULONG)pSystem; ULONG i; ULONG Address; ULONG ret; DbgPrint("-------------------------------------------"); DbgPrint("EProcess PID ImageFileName"); DbgPrint("---------------------------------"); for(i = 0x80000000; i < uSystemAddress; i += 4){//system进程的EPROCESS地址就是最大值了 ret = VALIDpage(i); if (ret == VALID){ Address = *(PULONG)i; if (( Address & 0xFFFF0000) == pebAddress){//每个进程的PEB地址都是在差不多的地方,地址前半部分是相同的 if(IsaRealProcess(i)){ ShowProcess(i - PEB_OFFSET); i += EPROCESS_SIZE; } } }else if(ret == PTE_INVALID){ i -=4; i += 0x1000;//4k }else{ i-=4; i+= 0x400000;//4mb } } ShowProcess(uSystemAddress);//system的PEB总是零 上面的方法是枚举不到的 不过我们用PsGetCurrentProcess就能得到了 DbgPrint("-------------------------------------------"); } / 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); DbgPrint("0x%08X %04d %s",pEProcess,PID,pFileName); } / ULONG VALIDpage(ULONG addr) { ULONG pte; ULONG pde; pde = 0xc0300000 + (addr>>22)*4; if((*(PULONG)pde & 0x1) != 0){ //large page if((*(PULONG)pde & 0x80) != 0){ return VALID; } pte = 0xc0000000 + (addr>>12)*4; if((*(PULONG)pte & 0x1) != 0){ return VALID; }else{ return PTE_INVALID; } } return PDE_INVALID; } BOOLEAN IsaRealProcess(ULONG i) { NTSTATUS STATUS; PUNICODE_STRING pUnicode; UNICODE_STRING Process; ULONG pObjectType; ULONG ObjectTypeAddress; if (VALIDpage(i- PEB_OFFSET) != VALID){ return FALSE; } ObjectTypeAddress = i - PEB_OFFSET - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET ; if (VALIDpage(ObjectTypeAddress) == VALID){ pObjectType = *(PULONG)ObjectTypeAddress; }else{ return FALSE; } if(pObjectTypeProcess == pObjectType){ //确定ObjectType是Process类型 return TRUE; } return FALSE; } |
ring0检测隐藏进程
最新推荐文章于 2024-09-21 14:27:22 发布