周未闲下来写了个小东西,很久前应该就有暴力搜索EPROCESS查找隐藏进程了,我的跟那个思路差不多,只是先找线程再找进程。
这样一来效果肯定会比那个好,但效率也下来了。
程序中也附带了另外两种简单的枚举进程的方法。
个人感觉其实现在用隐藏进程技术的已经不多了,如果发现隐藏进程可以直接干掉。
还是查找隐藏驱动比较实用,等下个周未如果有时间再写个查找隐藏驱动的,包括POOL ROOTKIT。
#include "ntddk.h"
#include "../Include/BaseFunc.h"
#include "../Include/undocnt.h"
#include "../Include/kundocument.h"
BOOL GetProcessList1()
{
PROCESSTHREADSYSTEMINFO *pProcessInfo,*pProcessInfo2;
PEPROCESS pEProcess;
NTSTATUS status;
ULONG i=0;
PETHREAD pEThread=NULL;
THREADSYSINFO *pThreadInfo;
ULONG ProcessNum=0;
ULONG ThreadNum=0;
pProcessInfo2=pProcessInfo=GetInfoTable(SystemProcessThreadInfo);
if(!pProcessInfo)
return FALSE;
while(1)
{
if(pProcessInfo2->ProcessId)
{
status=PsLookupProcessByProcessId(pProcessInfo2->ProcessId,&pEProcess);
if(!NT_SUCCESS(status))
pEProcess=NULL;
ProcessNum++;
KdPrint(("-------------------PID:0x%.4x PEPRROCESS:0x%x %ws------------------\n",pProcessInfo2->ProcessId,(ULONG)pEProcess,pProcessInfo2->ProcessName.Buffer ));
pThreadInfo=pProcessInfo2->ThreadSysInfo;
for(i=0;i<pProcessInfo2->nThreads;i++)
{
ThreadNum++;
// status=PsLookupThreadByThreadId((ULONG)pThreadInfo[i].ClientId.UniqueThread,&pEThread);
// if(!NT_SUCCESS(status))
// pEThread=NULL;
// KdPrint(("TID:0x%x PETHREAD:0x%x \n",pThreadInfo[i].ClientId.UniqueThread,pEThread));
}
if(pEProcess)
ObDereferenceObject(pEProcess);
}
if(pProcessInfo2->RelativeOffset==0)
break;
pProcessInfo2=(PROCESSTHREADSYSTEMINFO *)((ULONG)pProcessInfo2+pProcessInfo2->RelativeOffset);
}
KdPrint(("进程数:%d 线程数:%d\n",ProcessNum,ThreadNum));
return TRUE;
}
BOOL GetProcessList2()
{
ULONG dwOldProcessID=-1;
HANDLEINFO *pHeadInfo;
SYSTEMHANDLEINFO *pSysHeadInfo;
ULONG i=0;
PEPROCESS pEProcess;
NTSTATUS status;
WCHAR ProcessPath[MAX_PATH];
UNICODE_STRING UniProcessPath;
ULONG ProcessNum=0;
pSysHeadInfo=GetInfoTable(SystemHandleInfo);
if(!pSysHeadInfo)
return FALSE;
RtlInitEmptyUnicodeString(&UniProcessPath,ProcessPath,MAX_PATH);
pHeadInfo=pSysHeadInfo->HandleInfo;
for(i=0;i<pSysHeadInfo->NumberOfHandles;i++)
{
if(pHeadInfo[i].Pid==dwOldProcessID)
continue;
dwOldProcessID=pHeadInfo[i].Pid;
status=PsLookupProcessByProcessId(dwOldProcessID,&pEProcess);
if(!NT_SUCCESS(status))
pEProcess=NULL;
ProcessNum++;
//GetProcessFullName(&UniProcessPath,dwOldProcessID,pEProcess);
KdPrint(("-------------------PID:0x%.4x PEPRROCESS:0x%.4x %s------------------\n",dwOldProcessID,(ULONG)pEProcess,GetProcessName(pEProcess) ));
if(pEProcess)
ObDereferenceObject(pEProcess);
}
KdPrint(("进程数:%d \n",ProcessNum));
return TRUE;
}
BOOL bIsList(LIST_ENTRY *pHead)
{
BOOL retval=FALSE;
LIST_ENTRY *pList;
__try
{
while(pList!=pHead)
pList=pList->Blink;
retval=TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return retval;
}
BOOL GetProcessList3()
{
ULONG Addr=0x80000000;
ULONG Value;
ULONG ThreadNum=0,ThreadNum2=0,ThreadNum3=0,ThreadNum4=0;
WCHAR Buffer[1024];
UNICODE_STRING Name;
ULONG i;
PETHREAD *pEThread;
PEPROCESS *pEProcess;
ULONG ProcessNum=0;
PEPROCESS Process;
BOOLEAN bIsExists;
ULONG ThreadType;
pEThread=ExAllocatePoolWithTag(PagedPool,sizeof(PETHREAD)*0x1024,POOL_TAG);
RtlZeroMemory(pEThread,sizeof(PETHREAD)*0x1024);
pEProcess=ExAllocatePoolWithTag(PagedPool,sizeof(PEPROCESS)*0x1024,POOL_TAG);
RtlZeroMemory(pEProcess,sizeof(PEPROCESS)*0x1024);
RtlInitEmptyUnicodeString(&Name,Buffer,1024);
ThreadType=*(ULONG *)((ULONG)PsGetCurrentThread()-0x10);
for(;Addr>=0x80000000;Addr+=4)//溢出后就小于0x80000000了 这个查找算法应该是还可以优化的,不知道为什么虚拟机不要一秒,真机要几十秒。
{
if(MmIsAddressValid((PVOID)Addr)==FALSE)
{
Addr+=PAGE_SIZE;
continue;
}
__try
{
Value=*(ULONG *)(Addr);
if(Value!=0x00700006)
continue;
ThreadNum2++;
Value=*(ULONG *)(Addr-0x10);
if(Value!=ThreadType)
continue;
ThreadNum3++;
Value=*(ULONG *)(Addr+0x10);
if(!bIsList((LIST_ENTRY *)Value))
continue;
pEThread[ThreadNum4]=(PETHREAD)(Addr);
Process=IoThreadToProcess(pEThread[ThreadNum4]);
bIsExists=FALSE;
for(i=ProcessNum-1;i<ProcessNum;i--)
{
if(pEProcess[i]==Process)
{
bIsExists=TRUE;
break;
}
}
if(!bIsExists)
pEProcess[ProcessNum++]=Process;
ThreadNum4++;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
//KdPrint(("except\n"));
Addr+=PAGE_SIZE-4;
}
}
for(i=0;i<ProcessNum;i++)
{
KdPrint(("-------------------PID:0x%.4x PEPRROCESS:0x%.4x %s------------------\n",GetProcessIdFromEProcess(pEProcess[i]),(ULONG)pEProcess[i],GetProcessName(pEProcess[i]) ));
}
//KdPrint(("线程数:%d %d %d %d 进程数:%d \n",ThreadNum,ThreadNum2,ThreadNum3,ThreadNum4,ProcessNum));
KdPrint(("线程数:%d 进程数:%d \n",ThreadNum4,ProcessNum));
ExFreePoolWithTag(pEProcess,POOL_TAG);
ExFreePoolWithTag(pEThread,POOL_TAG);
return TRUE;
}
//-----------------------------------------------------------
//---------------------------------------------------------------驱动结构函数
NTSTATUS DisPatchCreateClose(PDEVICE_OBJECT pDriverObj,PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
//服务停止时执行
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
KdPrint(("Driver unload\n"));
}
//DeviceIoControl 时执行
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
NTSTATUS status=STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack=IoGetCurrentIrpStackLocation(pIrp);
ULONG uIoControlCode=pIrpStack->Parameters.DeviceIoControl.IoControlCode;
PVOID pInputBuffer= pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
PVOID pOutputBuffer=pIrp->UserBuffer;
ULONG uInsize=pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG uOutsize=pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case 0:
break;
default:
status=STATUS_SUCCESS;
break;
}
if(status==STATUS_SUCCESS)
pIrp->IoStatus.Information=uOutsize;
else
pIrp->IoStatus.Information=0;
pIrp->IoStatus.Status=status;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT theDriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status=STATUS_SUCCESS;
ULONG i;
for(i= 0;i<IRP_MJ_MAXIMUM_FUNCTION;++i)
theDriverObject->MajorFunction[i] = DisPatchCreateClose;
theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchDeviceControl;
theDriverObject->DriverUnload = DriverUnload;
InitBaseFunc();
KdPrint(("ZwQuerySystemInformation法: \n"));
GetProcessList1();
KdPrint(("枚举句柄表法: \n"));
GetProcessList2();
KdPrint(("搜索KTHREAD法: \n"));
GetProcessList3();
return STATUS_SUCCESS;
}