链 接: http://bbs.pediy.com/showthread.php?t=106745
用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
1 void DisplayInfo() 2 { 3 PEPROCESS pEprocess = NULL, pTemp = NULL; 4 pEprocess = PsGetCurrentProcess(); 5 pTemp = pEprocess; 6 do 7 { 8 DbgPrint("PId:%d\t", *(PULONG)((ULONG)pTemp+0x084) ); 9 DbgPrint("Path:%s\n", (PUCHAR)((ULONG)pTemp+0x174 )); 10 pTemp = (PEPROCESS)( (ULONG)(*(PULONG)((ULONG)pTemp+0x088)) - 0x088 ); 11 12 } while ( pTemp != pEprocess ); 13 }
效果:
4.ring0下暴力搜索内存
1 void DisplayInfo() 2 { 3 ULONG uStartAddr = 0x80000000; 4 PEPROCESS pCurrent = PsGetCurrentProcess(); 5 6 // ULONG uPetAddr = (ULONG)PsGetProcessPeb( pCurrent ); 7 DbgPrint("PId:%d\tPath:%s\n", *(PULONG)((ULONG)pCurrent+0x084), (PUCHAR)((ULONG)pCurrent+0x174)); 8 9 for(; uStartAddr < (ULONG)pCurrent+0x800000; uStartAddr += 4 ) 10 { 11 ULONG uRet = IsValidAddr( uStartAddr ); 12 if( uRet == VALID_PAGE ) 13 { 14 if( ( *(PULONG)uStartAddr & 0xffff0000) == 0x7ffd0000 ) 15 { 16 if( IsRealProcess(uStartAddr - 0x1b0) ) 17 { 18 PLARGE_INTEGER pExitTime = (PLARGE_INTEGER)(uStartAddr-0x1b0+0x078); 19 if( pExitTime->QuadPart == 0 ) 20 { 21 DbgPrint("PId:%d\tPath:%s\n", *(PULONG)(uStartAddr-0x1b0+0x084), (PUCHAR)(uStartAddr-0x1b0+0x174)); 22 } 23 24 uStartAddr -= 4; 25 uStartAddr += 0x25c; 26 } 27 } 28 } 29 else if( uRet == PDEINVALID ) 30 { 31 uStartAddr -= 4; 32 uStartAddr += 0x400000; 33 } 34 else 35 { 36 uStartAddr -= 4; 37 uStartAddr += 0x1000; 38 } 39 } 40 }
效果:
5.PspCidTable
1 void DisplayInfo() 2 { 3 ULONG pCidTableAddr = 0; 4 PHANDLE_TABLE pCidHandleTable = NULL; 5 PHANDLE_TABLE_ENTRY pTable1, *pTable2, **pTable3; 6 ULONG pRealHandleTable = 0; 7 ULONG level = 0; 8 ULONG uMax_Handle = 0; 9 10 pCidTableAddr = GetCidTableAddr(); 11 pCidHandleTable = (PHANDLE_TABLE)(*(PULONG)pCidTableAddr); 12 level = (pCidHandleTable->TableCode) & 0x3; 13 pRealHandleTable = (pCidHandleTable->TableCode) & ~0x3; 14 uMax_Handle = pCidHandleTable->NextHandleNeedingPool; 15 16 switch( level ) 17 { 18 case 0: 19 { 20 ULONG index = 0; 21 pTable1 = (PHANDLE_TABLE_ENTRY)(pRealHandleTable); 22 for( index = 0; index < MAX_ENT_CNT; index++ ) 23 { 24 if( pTable1[index].Object != NULL ) 25 { 26 ULONG pObject = (ULONG)(pTable1[index].Object) & ~7 ; 27 if( MmIsAddressValid((PULONG)(pObject - 0x10)) ) 28 { 29 POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject - 0x10)); 30 if( pType == *PsProcessType ) 31 { 32 DbgPrint("PId:%d\tPath:%s\n", index*4, PsGetProcessImageFileName((PEPROCESS)pObject) ); 33 } 34 } 35 36 } 37 } 38 break; 39 } 40 case 1: 41 { 42 ULONG index = 0; 43 pTable2 = (PHANDLE_TABLE_ENTRY*)(pRealHandleTable); 44 for( index = 0; index < uMax_Handle/(4*MAX_ENT_CNT); index++ ) 45 { 46 pTable1 = pTable2[index]; 47 if( pTable1 == NULL ) 48 break; 49 else 50 { 51 ULONG i = 0; 52 for( i = 0; i < MAX_ENT_CNT; i++ ) 53 { 54 if( pTable1[i].Object != NULL ) 55 { 56 ULONG pObject = (ULONG)(pTable1[i].Object) & ~7; 57 if( MmIsAddressValid( (PULONG)(pObject-0x10) ) ) 58 { 59 POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject-0x10)); 60 if( pType == *PsProcessType ) 61 { 62 DbgPrint("PId:%d\tPath:%s\n", index*MAX_ENT_CNT*4+i*4, PsGetProcessImageFileName((PEPROCESS)pObject) ); 63 } 64 } 65 66 } 67 } 68 } 69 } 70 break; 71 } 72 case 2: 73 { 74 ULONG index = 0; 75 pTable3 = (PHANDLE_TABLE_ENTRY**)(pRealHandleTable); 76 for( index = 0; index < uMax_Handle/(MAX_ADD_CNT*MAX_ENT_CNT*4); index++ ) 77 { 78 ULONG i = 0; 79 pTable2 = (PHANDLE_TABLE_ENTRY*)((ULONG)pTable3[index] & ~0x3); 80 if( pTable2 == NULL ) 81 break; 82 for( i = 0; i < MAX_ADD_CNT; i++ ) 83 { 84 85 pTable1 = pTable2[i]; 86 if( pTable1 == NULL ) 87 break; 88 else 89 { 90 ULONG j = 0; 91 for( j = 0; j < MAX_ENT_CNT; j++ ) 92 { 93 if( pTable1[j].Object != NULL ) 94 { 95 ULONG pObject = (ULONG)(pTable1[j].Object) & ~7; 96 if( MmIsAddressValid( (PULONG)(pObject-0x10) ) ) 97 { 98 POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject-0x10)); 99 if( pType == *PsProcessType ) 100 { 101 DbgPrint("PId:%d\tPath:%s\n", index*MAX_ADD_CNT*MAX_ENT_CNT*4+i*MAX_ENT_CNT*4+j*4,\ 102 PsGetProcessImageFileName((PEPROCESS)pObject) ); 103 } 104 } 105 } 106 107 108 } 109 110 } 111 } 112 113 } 114 115 } 116 break; 117 } 118 119 120 }
效果:
6.Inline Hook KiSwapContext
1 _declspec(naked) void MySwapContext() 2 { 3 _asm 4 { 5 pushad 6 pushfd 7 cli 8 } 9 _asm 10 { 11 push esi 12 push edi 13 call ShowProcess 14 } 15 16 _asm 17 { 18 sti 19 popfd 20 popad 21 } 22 _asm jmp DWORD PTR[pBackAddr] 23 24 }
效果:
7.Csrss进程中枚举进程
1 void DisplayInfo() 2 { 3 PEPROCESS pEProcess = NULL; 4 5 NTSTATUS Status = STATUS_SUCCESS; 6 PHANDLE_TABLE pObjectTable = NULL; 7 PHANDLE_TABLE_ENTRY table1, *table2, **table3; 8 ULONG level; 9 ULONG pRealHandleTable; 10 ULONG uHandleCount; 11 12 pEProcess = GetCsrssObject(); 13 14 pObjectTable = (PHANDLE_TABLE)(*(PULONG)((ULONG)pEProcess + 0xc4)); 15 level = pObjectTable->TableCode & 3; 16 pRealHandleTable = pObjectTable->TableCode & ~3; 17 uHandleCount = pObjectTable->NextHandleNeedingPool; 18 switch( level ) 19 { 20 case 0: 21 { 22 ULONG index = 0; 23 table1 = (PHANDLE_TABLE_ENTRY)pRealHandleTable; 24 for( index = 0; index < MAX_ENT_CNT; index++ ) 25 { 26 ULONG pObject = (ULONG)(table1[index].Object) & ~7; 27 if( MmIsAddressValid( (PULONG)(pObject+0x8) ) ) 28 { 29 POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject+0x8)); 30 if( pType == *PsProcessType ) 31 { 32 PEPROCESS pAddr = (PEPROCESS)(pObject+0x18); 33 DbgPrint("PId:%d\tPath:%s\n", *(PULONG)((ULONG)pAddr+0x84), (PUCHAR)((ULONG)pAddr+0x174) ); 34 } 35 } 36 } 37 break; 38 39 } 40 case 1: 41 { 42 ULONG index = 0; 43 table2 = (PHANDLE_TABLE_ENTRY*)pRealHandleTable; 44 for( index = 0; index < uHandleCount/MAX_ENT_CNT; index++ ) 45 { 46 ULONG i = 0; 47 table1 = table2[index]; 48 if( table1 == NULL ) 49 break; 50 for( i = 0; i < MAX_ENT_CNT; i++ ) 51 { 52 ULONG pObject = (ULONG)(table1[i].Object) & ~7; 53 if( MmIsAddressValid( (PULONG)(pObject+0x8) ) ) 54 { 55 POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject+0x8)); 56 if( pType == *PsProcessType ) 57 { 58 ULONG pAddr = (ULONG)(pObject+0x18); 59 DbgPrint("PId:%d\tPath:%s\n", *(PULONG)(pAddr+0x84), (PUCHAR)(pAddr+0x174) ); 60 } 61 } 62 63 } 64 65 } 66 break; 67 } 68 case 2: 69 { 70 ULONG index = 0; 71 table3 = (PHANDLE_TABLE_ENTRY**)pRealHandleTable; 72 for( index = 0; index < uHandleCount/(MAX_ENT_CNT*MAX_ADD_CNT); index++ ) 73 { 74 ULONG i = 0; 75 table2 = table3[index]; 76 if( table2 == NULL ) 77 break; 78 for( i = 0; i < MAX_ADD_CNT; i++ ) 79 { 80 ULONG j = 0; 81 table1 = table2[i]; 82 if( table1 == NULL ) 83 break; 84 for( j = 0; j < MAX_ENT_CNT; j++ ) 85 { 86 ULONG pObject = (ULONG)(table1[j].Object) & ~7; 87 if( MmIsAddressValid( (PULONG)(pObject+0x8) ) ) 88 { 89 POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject+0x8)); 90 if( pType == *PsProcessType ) 91 { 92 ULONG pAddr = (ULONG)(pObject+0x18); 93 DbgPrint("PId:%d\tPath:%s\n", *(PULONG)(pAddr+0x84), (PUCHAR)(pAddr+0x174) ); 94 } 95 } 96 97 } 98 } 99 100 } 101 break; 102 } 103 } 104 105 }
效果:
8.SessionProcessList枚举
1 void DisplayInfo() 2 { 3 PEPROCESS pEProcess = PsGetCurrentProcess(); 4 PEPROCESS pTemp = pEProcess; 5 DbgPrint("PId:%d\tPath:%s\n", *(PULONG)((ULONG)pTemp+0x84), (PUCHAR)((ULONG)pTemp+0x174) ); 6 pTemp = (PEPROCESS)( *(PULONG)(*(PULONG)((ULONG)pTemp + 0x8c) + 0x4) - 0x88 );//取用户进程 7 pEProcess = pTemp; 8 do 9 { 10 11 if( MmIsAddressValid(pTemp) ) 12 { 13 DbgPrint("PId:%d\tPath:%s\n", *(PLONG)((LONG)pTemp+0x84), (PUCHAR)((ULONG)pTemp+0x174) ); 14 pTemp = (PEPROCESS)(*(PULONG)((ULONG)pTemp+0xb4) - 0xb4 ); 15 } 16 else 17 break; 18 19 } while ( pEProcess != pTemp ); 20 21 }
效果:
就总结了这些。一直以来自己都是零零散散地学习,最近想系统地对内核进行学习,就先从进程开始了。下次再针对以上的枚举方法,进程隐藏。