⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processenum.c

📁 使用内核方法检测隐藏的进程
💻 C
📖 第 1 页 / 共 2 页
字号:
//Author  :n0bele
//HomePage:www.antiprotect.com


#include<ntddk.h>
#include <windef.h> 
#include "processenum.h"

///////////////////////////不同的windows版本下面的偏移值不同

#define  EPROCESS_SIZE       0x0 //EPROCESS结构大小
#define  PEB_OFFSET          0x1
#define  FILE_NAME_OFFSET    0x2
#define  PROCESS_LINK_OFFSET 0x3
#define  PROCESS_ID_OFFSET   0x4
#define  EXIT_TIME_OFFSET    0x5

#define  OBJECT_HEADER_SIZE  0x018
#define  OBJECT_TYPE_OFFSET  0x008
////////////////////////// 

#define PDE_INVALID 2 
#define PTE_INVALID 1 
#define VALID 0 


Processinfo* pProcessPtr = NULL;
int nProcessCount = 0;

ULONG     pebAddress;         //PEB地址的前半部分
PEPROCESS pSystem;            //system进程
ULONG     pObjectTypeProcess; //进程对象类型

ULONG   VALIDpage(ULONG addr) ;  //该函数直接复制自 Ring0下搜索内存枚举隐藏进程
BOOLEAN IsaRealProcess(ULONG i); //该函数复制自 Ring0下搜索内存枚举隐藏进程
VOID    WorkThread(IN PVOID pContext);
//ULONG   GetPebAddress();          //得到PEB地址前半部分
VOID    EnumProcess();            //枚举进程
VOID    ShowProcess(ULONG pEProcess); //显示结果
DWORD	GetPlantformDependentInfo(DWORD	eprocessflag);
#define SYSNAME    "System"
ULONG	ProcessNameOffset = 0; //进程名偏移量
ULONG   GetProcessNameOffset();
BOOLEAN GetProcess(PCHAR Name);

void EnumProcess2();

WCHAR gDeviceName[]=L"\\Device\\safepsenum";
WCHAR gDosDeviceName[]=L"\\??\\safepsenum";

NTSTATUS SafePsEnumCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS SafePsEnumClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS
MyDeviceControl (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp );

/////////////////////////////////////////////////////////
VOID    OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	NTSTATUS status;
	UNICODE_STRING DosDeviceName;
	RtlInitUnicodeString(&DosDeviceName,gDosDeviceName);
	if(DriverObject->DeviceObject)
		IoDeleteDevice(DriverObject->DeviceObject);
	status = IoDeleteSymbolicLink(&DosDeviceName);
	if(status)	
		DbgPrint("IoDeleteSymbolicLink Return %0x\n",status);	

	if (pProcessPtr)
	{
		ExFreePool(pProcessPtr);
	}
}

/////////////////////////////////////////////////////////
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
	HANDLE hThread; 
	UNICODE_STRING DeviceName;
	UNICODE_STRING DosDeviceName;
	PDEVICE_OBJECT pDeviceObject=NULL;
	NTSTATUS Status;
 
	pSystem    = PsGetCurrentProcess();
//	pebAddress = GetPebAddress();
    pebAddress = 0x7FFD0000;       //取了一个通用的低位地址
	ProcessNameOffset = GetProcessNameOffset();
 
	pObjectTypeProcess = *(PULONG)((ULONG)pSystem - OBJECT_HEADER_SIZE +OBJECT_TYPE_OFFSET);  

	DbgPrint("type: %d \n", pObjectTypeProcess);


	DriverObject -> DriverUnload = OnUnload;
	DriverObject->MajorFunction[IRP_MJ_CREATE]         = SafePsEnumCreate;
	DriverObject->MajorFunction[IRP_MJ_CLOSE]          = SafePsEnumClose;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceControl;

	RtlInitUnicodeString(&DeviceName,gDeviceName);
	RtlInitUnicodeString(&DosDeviceName,gDosDeviceName);
	IoCreateDevice(DriverObject,0,&DeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceObject);
	pDeviceObject->Flags|=DO_BUFFERED_IO;
	Status = IoCreateSymbolicLink(&DosDeviceName,&DeviceName);
	if(Status)
		DbgPrint("IoCreateSymbolicLink Return %0x\n",Status);
	
	nProcessCount = 0;
	// 测试固定获取最大为1024
	pProcessPtr =  ExAllocatePoolWithTag(NonPagedPool, 1024*sizeof(Processinfo), 'HpcM');

	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////
NTSTATUS SafePsEnumCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{	
 	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////
NTSTATUS SafePsEnumClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
 	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////
/*
ULONG  GetPebAddress()
{
	ULONG Address;
	PEPROCESS pEProcess;

	//由于system进程的peb总是零 我们只有到其他进程去找了
	pEProcess = (PEPROCESS)((ULONG)((PLIST_ENTRY)((ULONG)pSystem + PROCESS_LINK_OFFSET))->Flink - PROCESS_LINK_OFFSET);
	Address   = *(PULONG)((ULONG)pEProcess + PEB_OFFSET);

	return (Address & 0xFFFF0000);  
}
*/
///////////////////////////////////////////////////////
VOID EnumProcess()
{
	ULONG  uSystemAddress = (ULONG)pSystem;
	ULONG  i;
	ULONG  Address;
	ULONG  ret;

	nProcessCount = 0;
 
	for(i = 0x80000000; i < uSystemAddress; i += 4) {//system进程的EPROCESS地址就是最大值了
		
		ret = VALIDpage(i); 

		if (ret == VALID) { 
		 
			Address = *(PULONG)i;
			if (( Address & 0xFFFF0000) == 0x7FFD0000) {//每个进程的PEB地址都是在差不多的地方,地址前半部分是相同的       
				
				if(IsaRealProcess(i)) { 
				
					ShowProcess(i - GetPlantformDependentInfo(PEB_OFFSET)); 

					i += GetPlantformDependentInfo(EPROCESS_SIZE);                
				} 
			} 
		}
		else if(ret == PTE_INVALID) { 
			
			i -=4; 
			i += 0x1000;//4k 
		}
		else { 

		  i-=4; 
		  i+= 0x400000;//4mb 
		} 
	}

 	ShowProcess(uSystemAddress);//system的PEB总是零 上面的方法是枚举不到的 不过我们用PsGetCurrentProcess就能得到了
}

/////////////////////////////////////////////////////////
VOID    ShowProcess(ULONG pEProcess)
{
	PLARGE_INTEGER ExitTime;
	ULONG PID;
	PUCHAR pFileName;
	
	ExitTime = (PLARGE_INTEGER)(pEProcess + GetPlantformDependentInfo(EXIT_TIME_OFFSET));  

	if(ExitTime->QuadPart != 0) //已经结束的进程的ExitTime为非零	
		return ;

	PID = *(PULONG)(pEProcess + GetPlantformDependentInfo(PROCESS_ID_OFFSET));
	pFileName = (PUCHAR)(pEProcess + GetPlantformDependentInfo(FILE_NAME_OFFSET));

 	pProcessPtr[nProcessCount].pEProcess = pEProcess;
	pProcessPtr[nProcessCount].PId = PID;
	strcpy(pProcessPtr[nProcessCount].Name, pFileName);	 

	nProcessCount++;
}

/////////////////////////////////////////////////////////////
ULONG VALIDpage(ULONG addr) 
{ 
	ULONG pte; 
	ULONG pde; 

	pde = 0xc0300000 + (addr>>22)*4; 
	if((*(PULONG)pde & 0x1) != 0){ 
	//large page 
	if((*(PULONG)pde & 0x80) != 0){ 
		return VALID; 
	} 
	pte = 0xc0000000 + (addr>>12)*4; 
	if((*(PULONG)pte & 0x1) != 0){ 
		return VALID; 
	}else{ 
		return PTE_INVALID; 
	} 
	} 
	return PDE_INVALID; 
} 

////////////////////////////////////////////////////////////////
BOOLEAN IsaRealProcess(ULONG i) 
{ 
	NTSTATUS STATUS; 
	PUNICODE_STRING pUnicode; 
	UNICODE_STRING Process; 
	ULONG pObjectType; 
	ULONG ObjectTypeAddress; 

	if (VALIDpage(i- GetPlantformDependentInfo(PEB_OFFSET)) != VALID){ 
		return FALSE; 
	} 

	ObjectTypeAddress = i - GetPlantformDependentInfo(PEB_OFFSET) - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET ;

	if (VALIDpage(ObjectTypeAddress) == VALID){ 
		pObjectType = *(PULONG)ObjectTypeAddress; 
	}else{ 
		return FALSE; 
	} 

	if (pObjectTypeProcess == pObjectType){ //确定ObjectType是Process类型
		return TRUE; 
	} 
	return FALSE; 
} 
////////////////////////////////////////////////////////////////////
#define		DWORD	unsigned long

NTSTATUS
MyDeviceControl (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp
    )
{

    PIO_STACK_LOCATION  io_stack;
    NTSTATUS            status;

	Irp->IoStatus.Information = 0;
    io_stack = IoGetCurrentIrpStackLocation(Irp);

	if (io_stack->MajorFunction==IRP_MJ_DEVICE_CONTROL) 
	{
		switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
		{
		case IOCTL_GETPROCESSPTR:
			{
			 	EnumProcess();
			//	EnumProcess2();
				RtlCopyMemory((unsigned char*)Irp->UserBuffer, (unsigned char*)&nProcessCount, sizeof(DWORD));
				RtlCopyMemory((unsigned char*)Irp->UserBuffer+sizeof(DWORD), (unsigned char*)pProcessPtr, nProcessCount*sizeof(Processinfo));
				Irp->IoStatus.Information = nProcessCount*sizeof(Processinfo)+sizeof(DWORD);
			}
		}
	}
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

//---------------------------------------------------------------------- 
// 
// GetProcessNameOffset 
// 
// In an effort to remain version-independent, rather than using a 
// hard-coded into the KPEB (Kernel Process Environment Block), we 
// scan the KPEB looking for the name, which should match that 
// of the GUI process 
// 
//---------------------------------------------------------------------- 
ULONG GetProcessNameOffset() 
{ 
    PEPROCESS       curproc; 
    int             i; 
    DbgPrint(("GetProcessNameOffset\n")); 
    curproc = PsGetCurrentProcess(); 

    // 
    // Scan for 12KB, hopping the KPEB never grows that big! 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -