0

ring0检测隐藏进程

| |
2008/09/17    22:30    315    GreyHawk 晴
标 题: 【原创】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

///////////////////////////不同的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;

}
////////////////////////////////////////////////////////////////////
收藏本文到网摘: 添加到“Google书签” 添加到“Yahoo收藏” 添加到“QQ书签” 添加到“百度搜藏” 添加到“新浪ViVi收藏夹” 添加到“Del.icio.us” 添加到“365天天网摘” 添加到“天极网摘” 添加到“POCO网摘” 添加到“和讯网摘” 添加到“Bolaa博客收录中心” 添加到“igooi网摘” 添加到“天下图摘”
Tags: , , , | 分类:代码诱惑 | 来源:本站原创 | 引用(0)
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]