ring0 暴力枚举进程
原理:遍历进程ID,然后openprocess,能打开的都枚举出来
ring0 :
#include "EnumProcessByForce.h" extern char* PsGetProcessImageFileName(PEPROCESS EProcess); extern POBJECT_TYPE* PsProcessType; NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath) { PDEVICE_OBJECT DeviceObject; NTSTATUS Status; int i = 0; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; RtlInitUnicodeString(&DeviceName, DEVICE_NAME); RtlInitUnicodeString(&LinkName, LINK_NAME); Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(Status)) { return Status; } Status = IoCreateSymbolicLink(&LinkName, &DeviceName); if (!NT_SUCCESS(Status)) { //销毁设备对象 IoDeleteDevice(DeviceObject); DeviceObject = NULL; return Status; } DriverObject->DriverUnload = UnloadDriver; //设置派遣函数 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DefaultPassThrough; } DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControlDispatch; //DeviceIoControl(DeviceObject) } NTSTATUS DefaultPassThrough(PDEVICE_OBJECT DeviceObject, PIRP Irp) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给IO管理器,IO_NO_INCREMENT不增加优先级 return STATUS_SUCCESS; } void UnloadDriver(PDRIVER_OBJECT DriverObject) { PDEVICE_OBJECT DeviceObject = NULL; PDEVICE_OBJECT v1 = NULL; UNICODE_STRING LinkName; RtlInitUnicodeString(&LinkName, LINK_NAME); IoDeleteSymbolicLink(&LinkName); DeviceObject = DriverObject->DeviceObject; v1 = DeviceObject; while (DeviceObject != NULL) { v1 = DeviceObject->NextDevice; IoDeleteDevice(DeviceObject); DeviceObject = v1; } } NTSTATUS DeviceControlDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS Status = STATUS_SUCCESS; ULONG IoControlCode = 0; PVOID InputBuffer = NULL; PVOID OutputBuffer = NULL; ULONG32 InputLength = 0; ULONG32 OutputLength = 0; char BufferData[MAX_PATH] = { 0 }; ULONG BufferLength = MAX_PATH; PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; switch (IoControlCode) //IO控制码 { case CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID: { InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer; //CopyBuffer InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; //功能 if (InputLength == sizeof(ULONG) && InputBuffer != NULL&&OutputLength == MAX_PATH) { Status = EnumProcessByForce(*((PULONG)InputBuffer), BufferData, &BufferLength); if (NT_SUCCESS(Status)) { memcpy((char*)OutputBuffer, BufferData, BufferLength); } else { BufferLength = 0; } } } default: { break; } } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = BufferLength; //指示有多少内存向Ring3拷贝 //最后派遣函数将IRP请求结束,通过IoCompleteRequest IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给IO管理器 return STATUS_SUCCESS; } NTSTATUS EnumProcessByForce(ULONG ProcessID, char* BufferData, ULONG* BufferLength) { //进程的名称存储在进程的EProcess当前 NTSTATUS Status = STATUS_UNSUCCESSFUL; PEPROCESS EProcess = NULL; Status = PsLookupProcessByProcessId((HANDLE)ProcessID, &EProcess); if (!NT_SUCCESS(Status)) { return Status; } //判断是否有效 if (IsRealProcess(EProcess) == TRUE) { ObDereferenceObject(EProcess); if (strlen(PsGetProcessImageFileName(EProcess)) < *BufferLength) { *BufferLength = strlen(PsGetProcessImageFileName(EProcess)); } else { *BufferLength = *BufferLength - 1; } memcpy(BufferData, PsGetProcessImageFileName(EProcess), *BufferLength); return STATUS_SUCCESS; } return Status; } BOOLEAN IsRealProcess(PEPROCESS EProcess) { ULONG_PTR ObjectType; ULONG_PTR ObjectTypeAddress; ULONG_PTR ProcessType = ((ULONG_PTR)*PsProcessType); //系统导出的全局变量 if (ProcessType && EProcess && MmIsAddressValid((PVOID)(EProcess))) { ObjectType = KeGetObjectType((PVOID)EProcess); //通过EProcess 获得进程对象特征码 if (ObjectType && ProcessType == ObjectType) { return TRUE; } } return FALSE; } ULONG_PTR KeGetObjectType(PVOID ObjectBody) { ULONG_PTR ObjectType = NULL; pfnObGetObjectType ObGetObjectType = NULL; /* kd> u ObGetObjectType nt!ObGetObjectType: 840a8b68 8bff mov edi,edi 840a8b6a 55 push ebp 840a8b6b 8bec mov ebp,esp 840a8b6d 8b4508 mov eax,dword ptr [ebp+8] 840a8b70 0fb640f4 movzx eax,byte ptr [eax-0Ch] 840a8b74 8b04858035f983 mov eax,dword ptr nt!ObTypeIndexTable (83f93580)[eax*4] 840a8b7b 5d pop ebp 840a8b7c c20400 ret 4 */ if (!MmIsAddressValid || !ObjectBody || !MmIsAddressValid(ObjectBody)) { return NULL; } ObGetObjectType = (pfnObGetObjectType)GetFunctionAddressByName(L"ObGetObjectType"); if (ObGetObjectType) { ObjectType = ObGetObjectType(ObjectBody); } return ObjectType; } PVOID GetFunctionAddressByName(WCHAR *FunctionName) { UNICODE_STRING v1; PVOID FunctionAddress = NULL; if (FunctionName && wcslen(FunctionName) > 0) { RtlInitUnicodeString(&v1, FunctionName); FunctionAddress = MmGetSystemRoutineAddress(&v1); //在系统第一个模块ntoskrnl.exe 导出表中搜索 } return FunctionAddress; } //对派遣函数的简单处理 //大部分的IRP都源于文件I / O处理的API,如CreateFile、ReadFile等。处理这些IRP最简单的方法是在相应的派遣函数中, //将IRP的状态设置成功,然后结束IRP的请求(使用IoCompleteRequest),并让派遣函数返回成功。
ring3 :
#include "stdafx.h" #include "EnumProcessForceRing3.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 唯一的应用程序对象 #include#include #include