首页
社区
课程
招聘
[旧帖] [原创]枚举进程:ring3->ring0(求邀请码) 0.00雪花
发表于: 2010-2-5 20:29 13694

[旧帖] [原创]枚举进程:ring3->ring0(求邀请码) 0.00雪花

2010-2-5 20:29
13694

用google搜索了几天相关内容的资料,将所提到的逐一实现。哎,不禁感叹自己太菜了。居然用了几天的时间。没啥新思想、内容,只是总结,当然还有其他方法没总结到。但经常提到的ring3下的快照、psapi的EnumProcesses、暴力OpenProcess;ring0下的ZwQuerySystemInformation、activprocess链、暴力搜索内存、PspCidTable、Csrss进程的ObjectTable、进程的SessionProcessList、ZwQuerySystemInformation的全局句柄表、hook SwapContext.就这么多吧,大牛飘过。算一个枚举进程的科普吧。废话不多说,直接上代码:

ring3:

1.ring3下的快照:

void main()
{
HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hSnap == INVALID_HANDLE_VALUE )
{
   cout<<"Create Toolhelp false"<<endl;
   return;
}
PROCESSENTRY32 pEntry32 = {0};
pEntry32.dwSize = sizeof(PROCESSENTRY32);
bool bRes = Process32First( hSnap, &pEntry32 );
int pNums = 0;
while( bRes )
{
   pNums++;
   cout<<"PID:"<<pEntry32.th32ProcessID<<"\t"<<"Path:"<<pEntry32.szExeFile<<endl;
   bRes = Process32Next( hSnap, &pEntry32 );
}
CloseHandle( hSnap );
cout<<"Process Nums:"<<pNums<<endl;

}

效果:


2.psapi的EnumProcesses

DWORD dProcessIds[1024] = {0};
DWORD dRet = 0;
DWORD dRes = 0;

dRes = EnumProcesses( dProcessIds, sizeof(dProcessIds), &dRet );
if( dRes == 0 )
{
   cout<<"EnumProcesses1 False"<<endl;
   return;
}
int ProcessNums = dRet/sizeof(DWORD);

for( int i = 0; i < ProcessNums; i++ )
   GetProcessPathById( dProcessIds[i] );

cout<<"Process Nums:"<<ProcessNums<<endl;
效果:


3.ring3下的暴力枚举:

RaisePrivileges();
for( int i = 0; i <0xffff; i++ )
{
   HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, i );
   if( hProcess )
   {
    char ProcessName[MAX_PATH] = {0};
    GetProcessImageFileName( hProcess, ProcessName, MAX_PATH );
    cout<<"PID:"<<i<<"\t"<<"Path:"<<ProcessName<<endl;
   }
}

效果:



ring0:

1.利用ZwQuerySystemInformation的第5号功能,获取系统进程表

NTSTATUS Status = STATUS_SUCCESS;
NtQuerySystemInformation( 5, pBuff, 0, &uRet );

pBuff = (PCHAR)ExAllocatePool( NonPagedPool, uRet );
pTemp = pBuff;

Status = NtQuerySystemInformation( 5, pBuff, uRet, NULL );
if( NT_SUCCESS(Status) )
{
  
   while( 1 )
   {
    PSYSTEM_PROCESS_INFORMATION pSystemProcessInfo = (PSYSTEM_PROCESS_INFORMATION)pTemp;
    RtlUnicodeStringToAnsiString( &ansi, &pSystemProcessInfo->ImageName, TRUE );
    DbgPrint("PId:%d\t", pSystemProcessInfo->ProcessId);
    DbgPrint("Path:%s\n", ansi.Buffer );
    RtlFreeAnsiString( &ansi );

    if( pSystemProcessInfo->NextEntryOffset == 0 )
     break;
    pTemp = pTemp+pSystemProcessInfo->NextEntryOffset;

   }

}

效果:


2.利用ZwQuerySystemInformation的第16号功能,获取系统进程表

void DisplayInfo()
{
NTSTATUS Status = STATUS_SUCCESS;
PCHAR pBuff = NULL;
ULONG uNums = 0;
ULONG uRet = 0;
PSYSTEM_HANDLE_INFORMATION_EX pSystemHandle = NULL;

pBuff = (PCHAR)ExAllocatePool( NonPagedPool, 100 );

Status = ZwQuerySystemInformation( 16, pBuff, 100, &uRet );
ExFreePool( pBuff );

pBuff = (PCHAR)ExAllocatePool( NonPagedPool, uRet );

Status = ZwQuerySystemInformation( 16, pBuff, uRet, NULL );
if( NT_SUCCESS(Status) )
{
   ULONG index = 0;
   LONG PId = -1;
   pSystemHandle = (PSYSTEM_HANDLE_INFORMATION_EX)pBuff;
   uNums = pSystemHandle->NumberOfHandles;

   for(; index < uNums; index++ )
   {
    if( pSystemHandle->Information[index].ProcessId != PId )
    {
     PId = pSystemHandle->Information[index].ProcessId;
     Display( pSystemHandle->Information[index].ProcessId );
    }
   }
   
}
else
{
   DbgPrint("NtQuerySystemInformation False");
   return;
}

效果:



3.利用进程的ActiveProcessList

void DisplayInfo()
{
PEPROCESS pEprocess = NULL, pTemp = NULL;
pEprocess = PsGetCurrentProcess();
pTemp = pEprocess;
do
{
   DbgPrint("PId:%d\t", *(PULONG)((ULONG)pTemp+0x084) );
   DbgPrint("Path:%s\n", (PUCHAR)((ULONG)pTemp+0x174 ));
   pTemp = (PEPROCESS)( (ULONG)(*(PULONG)((ULONG)pTemp+0x088)) - 0x088 );

} while ( pTemp != pEprocess );
}
效果:



4.ring0下暴力搜索内存

void DisplayInfo()
{
ULONG uStartAddr = 0x80000000;
PEPROCESS pCurrent = PsGetCurrentProcess();

// ULONG uPetAddr = (ULONG)PsGetProcessPeb( pCurrent );
DbgPrint("PId:%d\tPath:%s\n", *(PULONG)((ULONG)pCurrent+0x084), (PUCHAR)((ULONG)pCurrent+0x174));

for(; uStartAddr < (ULONG)pCurrent+0x800000; uStartAddr += 4 )
{
   ULONG uRet = IsValidAddr( uStartAddr );
   if( uRet == VALID_PAGE )
   {

    if( ( *(PULONG)uStartAddr & 0xffff0000) == 0x7ffd0000 )
    {
     if( IsRealProcess(uStartAddr - 0x1b0) )
     {
      PLARGE_INTEGER pExitTime = (PLARGE_INTEGER)(uStartAddr-0x1b0+0x078);
      if( pExitTime->QuadPart == 0 )
      {
       DbgPrint("PId:%d\tPath:%s\n", *(PULONG)(uStartAddr-0x1b0+0x084), (PUCHAR)(uStartAddr-0x1b0+0x174));
      }
     
      uStartAddr -= 4;
      uStartAddr += 0x25c;
     }
    }
   }
   else if( uRet == PDEINVALID )
   {
    uStartAddr -= 4;
    uStartAddr += 0x400000;
   }
   else
   {
    uStartAddr -= 4;
    uStartAddr += 0x1000;
   }

}
}

效果:


5.PspCidTable

void DisplayInfo()
{
ULONG pCidTableAddr = 0;
PHANDLE_TABLE pCidHandleTable = NULL;
PHANDLE_TABLE_ENTRY pTable1, *pTable2, **pTable3;
ULONG pRealHandleTable = 0;
ULONG level = 0;
ULONG uMax_Handle = 0;

pCidTableAddr = GetCidTableAddr();
pCidHandleTable = (PHANDLE_TABLE)(*(PULONG)pCidTableAddr);
level = (pCidHandleTable->TableCode) & 0x3;
pRealHandleTable = (pCidHandleTable->TableCode) & ~0x3;
uMax_Handle = pCidHandleTable->NextHandleNeedingPool;

switch( level )
{
case 0:
   {
    ULONG index = 0;
    pTable1 = (PHANDLE_TABLE_ENTRY)(pRealHandleTable);
    for( index = 0; index < MAX_ENT_CNT; index++ )
    {
     if( pTable1[index].Object != NULL )
     {
      ULONG pObject = (ULONG)(pTable1[index].Object) & ~7 ;
      if( MmIsAddressValid((PULONG)(pObject - 0x10)) )
      {
       POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject - 0x10));
       if( pType == *PsProcessType )
       {
        DbgPrint("PId:%d\tPath:%s\n", index*4, PsGetProcessImageFileName((PEPROCESS)pObject) );
       }
      }
     
     }
    }
    break;
   }
case 1:
   {
    ULONG index = 0;
    pTable2 = (PHANDLE_TABLE_ENTRY*)(pRealHandleTable);
    for( index = 0; index < uMax_Handle/(4*MAX_ENT_CNT); index++ )
    {
     pTable1 = pTable2[index];
     if( pTable1 == NULL )
      break;
     else
     {
      ULONG i = 0;
      for( i = 0; i < MAX_ENT_CNT; i++ )
      {
       if( pTable1[i].Object != NULL )
       {
        ULONG pObject = (ULONG)(pTable1[i].Object) & ~7;
        if( MmIsAddressValid( (PULONG)(pObject-0x10) ) )
        {
         POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject-0x10));
         if( pType == *PsProcessType )
         {
          DbgPrint("PId:%d\tPath:%s\n", index*MAX_ENT_CNT*4+i*4, PsGetProcessImageFileName((PEPROCESS)pObject) );
         }
        }
      
       }
      }
     }
    }
    break;
   }
case 2:
   {
    ULONG index = 0;
    pTable3 = (PHANDLE_TABLE_ENTRY**)(pRealHandleTable);
    for( index = 0; index < uMax_Handle/(MAX_ADD_CNT*MAX_ENT_CNT*4); index++ )
    {
     ULONG i = 0;
     pTable2 = (PHANDLE_TABLE_ENTRY*)((ULONG)pTable3[index] & ~0x3);
     if( pTable2 == NULL )
      break;
     for( i = 0; i < MAX_ADD_CNT; i++ )
     {
     
      pTable1 = pTable2[i];
      if( pTable1 == NULL )
       break;
      else
      {
       ULONG j = 0;
       for( j = 0; j < MAX_ENT_CNT; j++ )
       {
        if( pTable1[j].Object != NULL )
        {
         ULONG pObject = (ULONG)(pTable1[j].Object) & ~7;
         if( MmIsAddressValid( (PULONG)(pObject-0x10) ) )
         {
          POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject-0x10));
          if( pType == *PsProcessType )
          {
           DbgPrint("PId:%d\tPath:%s\n", index*MAX_ADD_CNT*MAX_ENT_CNT*4+i*MAX_ENT_CNT*4+j*4,\
            PsGetProcessImageFileName((PEPROCESS)pObject) );
          }
         }
        }
      

       }

      }
     }

    }

   }
   break;
}

}

效果:


6.Inline Hook KiSwapContext

_declspec(naked) void MySwapContext()
{
_asm
{
   pushad
    pushfd
    cli
}
_asm
{
   push esi
    push edi
    call ShowProcess
}

_asm
{
   sti
    popfd
    popad
}
_asm jmp DWORD PTR[pBackAddr]
  
}

效果:




7.Csrss进程中枚举进程


void DisplayInfo()
{
PEPROCESS pEProcess = NULL;

NTSTATUS Status = STATUS_SUCCESS;
PHANDLE_TABLE pObjectTable = NULL;
PHANDLE_TABLE_ENTRY table1, *table2, **table3;
ULONG level;
ULONG pRealHandleTable;
ULONG uHandleCount;

pEProcess = GetCsrssObject();

pObjectTable = (PHANDLE_TABLE)(*(PULONG)((ULONG)pEProcess + 0xc4));
level = pObjectTable->TableCode & 3;
pRealHandleTable = pObjectTable->TableCode & ~3;
uHandleCount = pObjectTable->NextHandleNeedingPool;
switch( level )
{
case 0:
   {
    ULONG index = 0;
    table1 = (PHANDLE_TABLE_ENTRY)pRealHandleTable;
    for( index = 0; index < MAX_ENT_CNT; index++ )
    {
     ULONG pObject = (ULONG)(table1[index].Object) & ~7;
     if( MmIsAddressValid( (PULONG)(pObject+0x8) ) )
     {
      POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject+0x8));
      if( pType == *PsProcessType )
      {
       PEPROCESS pAddr = (PEPROCESS)(pObject+0x18);
       DbgPrint("PId:%d\tPath:%s\n", *(PULONG)((ULONG)pAddr+0x84), (PUCHAR)((ULONG)pAddr+0x174) );
      }
     }
    }
    break;

   }
case 1:
   {
    ULONG index = 0;
    table2 = (PHANDLE_TABLE_ENTRY*)pRealHandleTable;
    for( index = 0; index < uHandleCount/MAX_ENT_CNT; index++ )
    {
     ULONG i = 0;
     table1 = table2[index];
     if( table1 == NULL )
      break;
     for( i = 0; i < MAX_ENT_CNT; i++ )
     {
      ULONG pObject = (ULONG)(table1[i].Object) & ~7;
      if( MmIsAddressValid( (PULONG)(pObject+0x8) ) )
      {
       POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject+0x8));
       if( pType == *PsProcessType )
       {
        ULONG pAddr = (ULONG)(pObject+0x18);
        DbgPrint("PId:%d\tPath:%s\n", *(PULONG)(pAddr+0x84), (PUCHAR)(pAddr+0x174) );
       }
      }

     }
   
    }
    break;
   }
case 2:
   {
    ULONG index = 0;
    table3 = (PHANDLE_TABLE_ENTRY**)pRealHandleTable;
    for( index = 0; index < uHandleCount/(MAX_ENT_CNT*MAX_ADD_CNT); index++ )
    {
     ULONG i = 0;
     table2 = table3[index];
     if( table2 == NULL )
      break;
     for( i = 0; i < MAX_ADD_CNT; i++ )
     {
      ULONG j = 0;
      table1 = table2[i];
      if( table1 == NULL )
       break;
      for( j = 0; j < MAX_ENT_CNT; j++ )
      {
       ULONG pObject = (ULONG)(table1[j].Object) & ~7;
       if( MmIsAddressValid( (PULONG)(pObject+0x8) ) )
       {
        POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject+0x8));
        if( pType == *PsProcessType )
        {
         ULONG pAddr = (ULONG)(pObject+0x18);
         DbgPrint("PId:%d\tPath:%s\n", *(PULONG)(pAddr+0x84), (PUCHAR)(pAddr+0x174) );
        }
       }
     
      }
     }
   
    }
    break;
   }
}

}
效果:



8.SessionProcessList枚举

void DisplayInfo()
{
PEPROCESS pEProcess = PsGetCurrentProcess();
PEPROCESS pTemp = pEProcess;
DbgPrint("PId:%d\tPath:%s\n", *(PULONG)((ULONG)pTemp+0x84), (PUCHAR)((ULONG)pTemp+0x174) );
    pTemp = (PEPROCESS)( *(PULONG)(*(PULONG)((ULONG)pTemp + 0x8c) + 0x4) - 0x88 );//取用户进程
pEProcess = pTemp;
do
{

   if( MmIsAddressValid(pTemp) )
   {
    DbgPrint("PId:%d\tPath:%s\n", *(PLONG)((LONG)pTemp+0x84), (PUCHAR)((ULONG)pTemp+0x174) );
    pTemp = (PEPROCESS)(*(PULONG)((ULONG)pTemp+0xb4) - 0xb4 );
   }
   else
    break;
  
} while ( pEProcess != pTemp );

}

效果:



就总结了这些。一直以来自己都是零零散散地学习,最近想系统地对内核进行学习,就先从进程开始了。下次再针对以上的枚举方法,进程隐藏。
ring0:
ring0.rar
ring3:
ring3.rar


[注意]APP应用上架合规检测服务,协助应用顺利上架!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (93)
雪    币: 695
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
总结的不错 ,顶一下
2010-2-5 21:23
0
雪    币: 410
活跃值: (214)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
3
哎,看来很没价值啊,都没人顶
2010-2-6 22:14
0
雪    币: 103
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看不明白,没法支持啊,希望楼主仔细说明啊!
2010-2-6 22:18
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
顶  很好...
2010-2-6 22:39
0
雪    币: 197
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
收藏,顶起  
  慢慢理解
2010-2-12 12:15
0
雪    币: 695
活跃值: (25)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
7
不错,支持下~
2010-2-12 15:27
0
雪    币: 196
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8

that's fine, i just want to analyze it
2010-2-12 15:47
0
雪    币: 6797
活跃值: (4451)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
9
总结得很好,顶一下,我也刚把这些东西学完,共同进步呀!
2010-2-12 16:19
0
雪    币: 437
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
总结得很好,顶一下,我也刚把这些东西学完,共同进步呀!
2010-2-13 19:05
0
雪    币: 47
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
看不懂呀
2010-2-21 00:23
0
雪    币: 431
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
先收藏 再慢慢学~~~
2010-2-21 01:06
0
雪    币: 2397
活跃值: (2310)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
13
菜鸟来学习了
2010-2-21 01:27
0
雪    币: 12864
活跃值: (4494)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
收藏一下~~不用到处找了~~谢谢
2010-2-21 04:21
0
雪    币: 5490
活跃值: (3879)
能力值: ( LV13,RANK:283 )
在线值:
发帖
回帖
粉丝
15
挺好的资料,谢谢分享.
2010-2-21 09:02
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
16
学习了,谢谢!
2010-2-21 09:11
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
17
学习了 支持
2010-2-21 11:28
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
总结的很细了
谢谢
2010-2-21 11:39
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
19
辛苦LZ !
2010-2-21 11:50
0
雪    币: 139
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
感谢楼主,学习中!
2010-2-21 11:58
0
雪    币: 381
活跃值: (140)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
21
总结的很好,
2010-2-21 14:47
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
批处理 列举进程的

@echo for each ps in getobject _ >ps.vbs
@echo ("winmgmts:\\.\root\cimv2:win32_process").instances_ >>ps.vbs
@echo wscript.echo ps.handle^&vbtab^&ps.name^&vbtab^&ps.executablepath:next >>ps.vbs
cscript //nologo ps.vbs & del ps.vbs
pause
2010-2-21 18:23
0
雪    币: 808
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
23
Good data...
2010-2-21 19:20
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
24
不错,支持继续...
2010-2-21 20:21
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
好东西.先收藏了再慢慢消化嘎
2010-2-23 15:56
0
游客
登录 | 注册 方可回帖
返回
//