?? processenum.c
字號:
//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 + -