看流星社区

 找回密码
 注册账号
查看: 1526|回复: 0

ARK之进程枚举

[复制链接]

该用户从未签到

发表于 2017-6-1 12:52:05 | 显示全部楼层 |阅读模式
A.进程
1.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS) /  Process32First / Process32Next
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<<&quotID:"<<pEntry32.th32ProcessID<<"\t"<<&quotath:"<<pEntry32.szExeFile<<endl;
   bRes = Process32Next( hSnap, &pEntry32 );
}
CloseHandle( hSnap );
cout<<&quotrocess Nums:"<<pNums<<endl;


}[/code]



2.PsApi EnumProcess
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 );


cout<<&quotrocess Nums:"<&ltrocessNums<<endl;
[/code]


3.ZwQuerySystemInformation(SystemProcessesAndThreadsInformation)5号 和16号功能SystemProcessesAndThreadsInformation
代码是R0的 但R3也可以使用
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(&quotId:%d\t", pSystemProcessInfo-&gtrocessId);
    DbgPrint(&quotath:%s\n", ansi.Buffer );
    RtlFreeAnsiString( &ansi );


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


   }


}[/code]

16号功能:
void EnumProcessBy_16()
{
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;
}[/code]


4.EnumWindows / GetWindowThreadProcessId
只能枚举窗口进程
5.for(; ; ) OpenProcess 内核中也可以使用 通过PsLookupProcessByProcessId得到EPROCESS
//需提权
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<<&quotID:"<<i<<"\t"<<&quotath:"<<ProcessName<<endl;
   }
}[/code]

6.活动链 ActiveProcessList
硬编码了 也可以不用硬编码,可以通过在DriverEntry中使用PsGetCurrentProcess得到system的EPROCESS 然后向下搜索system字符串 搜到后减去EPROCESS BASE就得到了offset
void EnumProcess()
{
        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 );
}
[/code]


7.R0 暴力搜索内存
这里设计搜索的内存大小,x86下 只要搜0x80000000~0xFFFFFFFF 也能很快跑完
但在x64下,内核的地址太大了
那如果搜0xfffffa800000000~0xfffffffffffffff这么大的内存,10分钟都搜不玩
我们可以在DriverEntry中获取system的EPROCESS PsGetCurrentProcess的EPROCESS 然后向上向下搜索2G空间 一般都能找到
另一个问题是EPROCESS的识别
一般PEB可以当做一个判断的地方
CreateTime
.....
还可以在EPROCESS向上搜 OBJECTTYPE的typeID 需要注意的是在win10中 这个typeid是随机固定值
假如有一个进程的typeid是10 那么其他进程的typeid也是10 但这个10是每次启动都不一样,那么我们需要先知道这个值
方法也是在DriverEntry中获得system的EPROCESS 想上找到typeid 即可


可以参考 搜索高端内存枚举进程 自行百度
void EnumProcess()
{
        ULONG uStartAddr = 0x80000000;
        PEPROCESS pCurrent = PsGetCurrentProcess();
        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;
           }


        }
}
[/code]

8.PspCidTable 句柄表
x64的可以看我的另一篇文章 没多大变化
也可以看
4280190
void EnumProcessByPspCidTable()
{
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.Object != NULL )
       {
        ULONG pObject = (ULONG)(pTable1.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;
      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;
}




}
[/code]

9.Inline Hook KiSwapContext
因为在x64下不能hook 就不写了
10.通过Csrss.exe枚举进程
显示获得Csrss.exe进程
需要注意不同系统中ObjectTypeNumber可能不同 这里21是Port object
Csrss.exe的特征是有一个符号\\Windows\\ApiPort
其实这个并不是真的通过Csrss.exe来枚举进程,而是通过EPROCESS下的HANDLE_TABLE下的TableCode来枚举的
真正是通过Csrss.exe枚举进程可以参考
http://lwglucky.blog.51cto.com/1228348/349259
http://bbs.pediy.com/showthread.php?t=89708
HANDLE GetCsrPid()
{
   HANDLE Process, hObject;
   HANDLE CsrId = (HANDLE)0;
   OBJECT_ATTRIBUTES obj;
   CLIENT_ID cid;
   UCHAR Buff[0x100];
   POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
   PSYSTEM_HANDLE_INFORMATION_EX Handles;
   ULONG r;
  
   Handles = GetInfoTable(SystemHandleInformation);
  
   if (!Handles) return CsrId;
  
   for (r = 0; r < Handles->NumberOfHandles; r++)
   {
     if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
     {
       InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
  
       cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
       cid.UniqueThread = 0;
  
       if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
       {
         if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
         {
           if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
           {
             if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
             {
               CsrId = (HANDLE)Handles->Information[r].ProcessId;
             }
           }
  
           ZwClose(hObject);
         }
  
         ZwClose(Process);
       }
     }
   }
  
   ExFreePool(Handles);
   return CsrId;
}
[/code]

枚举
void EnumProcessByCsr_TableCode()
{
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.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;
      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;
   }
}


}[/code]



11.SessionProcessList枚举
这个硬编码太多,不推荐
void EnumProcessBySessionProcessList()
{
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 );


}
[/code]

其他一些参考链接:
http://bbs.pediy.com/showthread.php?p=153453
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 15:56

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表