sherwood5 发表于 2017-6-1 12:52:05

ARK之进程枚举

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<<"PID:"<<pEntry32.th32ProcessID<<"\t"<<"Path:"<<pEntry32.szExeFile<<endl;
   bRes = Process32Next( hSnap, &pEntry32 );
}
CloseHandle( hSnap );
cout<<"Process Nums:"<<pNums<<endl;


}



2.PsApi EnumProcess
DWORD dProcessIds = {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<<"Process Nums:"<<ProcessNums<<endl;



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("PId:%d\t", pSystemProcessInfo->ProcessId);
    DbgPrint("Path:%s\n", ansi.Buffer );
    RtlFreeAnsiString( &ansi );


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


   }


}

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.ProcessId != PId )
    {
   PId = pSystemHandle->Information.ProcessId;
   Display( pSystemHandle->Information.ProcessId );
    }
   }
   
}
else
{
   DbgPrint("NtQuerySystemInformation False");
   return;
}


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 = {0};
    GetProcessImageFileName( hProcess, ProcessName, MAX_PATH );
    cout<<"PID:"<<i<<"\t"<<"Path:"<<ProcessName<<endl;
   }
}

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



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


        }
}


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.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*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;
   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 & ~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.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_ADD_CNT*MAX_ENT_CNT*4+i*MAX_ENT_CNT*4+j*4,\
            PsGetProcessImageFileName((PEPROCESS)pObject) );
          }
         }
      }
      


       }


      }
   }


    }


   }
   break;
}




}


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;
   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.ObjectTypeNumber == 21) //Port object
   {
       InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

       cid.UniqueProcess = (HANDLE)Handles->Information.ProcessId;
       cid.UniqueThread = 0;

       if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
       {
         if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information.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.ProcessId;
             }
         }

         ZwClose(hObject);
         }

         ZwClose(Process);
       }
   }
   }

   ExFreePool(Handles);
   return CsrId;
}


枚举
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.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;
   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;
   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.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;
   }
}


}



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 );


}


其他一些参考链接:
http://bbs.pediy.com/showthread.php?p=153453
页: [1]
查看完整版本: ARK之进程枚举