暴力搜索KTHREAD查找隐藏进程

周未闲下来写了个小东西,很久前应该就有暴力搜索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;
}
 

  • 相关文章:
  • quote 1.langouster
  • 想了想ObjectType判断最好还是要去掉,不然上别人当。
    Value=*(ULONG *)(Addr-0x10);
    if(Value!=ThreadType)
    continue;
    要保险点就再加几个LIST的检查
  • 2008-12-07 20:17:20 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Copyright langouster. Some Rights Reserved.   苏ICP备06046736号   

本站点由 Z-Blog 2.0 bate Build 构建,基于 Glued Ideas Subtle 主题,由 zx.asd 移植并创新.