遍历指定PID进程的私有句柄表,如果发现其有DbgView.exe进程的EPROCESS则将其句柄权限进行修改,俗称句柄降权
这里有个注意点,因为我们的程序即使关闭了,它的EPROCESS还是会遍历到,只是它的EPROCESS结构中没有私有句柄表了,所以我们在遍历DbgView.exe进程时还需要检查下它的私有句柄表是否存在
驱动代码:
#include
#define My_Code CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCESS_VM_READ (0x0010) // winnt
#define PROCESS_VM_WRITE (0x0020) // winnt
BOOLEAN isThreadWork = TRUE;
ULONG PID;
PEPROCESS FindProcessByName(PWCH name);
typedef struct _DEVICE_EXTENSION {
UNICODE_STRING SymLinkName;
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;
typedef struct Hread {
ULONG Flage;
ULONG Addr;
ULONG WriteBufferAddr;
ULONG Size;
ULONG Pid;
}_Hread, * PtrHread;
struct _HANDLE_TABLE_ENTRY_INFO
{
ULONG AuditMask; //0x0
};
typedef struct _HANDLE_TABLE_ENTRY
{
union
{
VOID* Object; //0x0
ULONG ObAttributes; //0x0
struct _HANDLE_TABLE_ENTRY_INFO* InfoTable; //0x0
ULONG Value; //0x0
};
union
{
ULONG GrantedAccess; //0x4
struct
{
USHORT GrantedAccessIndex; //0x4
USHORT CreatorBackTraceIndex; //0x6
};
ULONG NextFreeTableEntry; //0x4
};
}HANDLE_TABLE_ENTRY, * PHANDLE_TABLE_ENTRY;
typedef BOOLEAN(NTAPI* EX_ENUMERATE_HANDLE_ROUTINE)(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter
);
BOOLEAN ExEnumHandleTable(
__in PVOID HandleTable,
__in EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
__in PVOID EnumParameter,
__out_opt PHANDLE Handle
);
BOOLEAN NTAPI enumRoutine(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter
)
{
if (HandleTableEntry)
{
PUCHAR x = (HandleTableEntry->Value & ~7);
ULONG_PTR object = (HandleTableEntry->Value & ~7) + 0x18; //0xfffffff8
UCHAR tindex = *(x + 0xc);
DbgPrintEx(77, 0, "[db]:index = %x EnumParameter=%x,object=%x\r\n", tindex, EnumParameter, object);
if (tindex == 0x7)
{
if (object == (ULONG_PTR)EnumParameter)
{
HandleTableEntry->GrantedAccess &= ~(PROCESS_VM_READ | PROCESS_VM_WRITE);
}
}
}
return FALSE;
}
VOID ProcessHandleResetPrivilege()
{
PEPROCESS DbgView_PEPROCESS = FindProcessByName(L"DBGVIEW.EXE");
while (isThreadWork)
{
PEPROCESS Process = NULL;
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)PID, &Process);
if (!NT_SUCCESS(status))
{
continue;
}
//遍历CE进程,循环句柄降权
ExEnumHandleTable(*(PULONG)((PUCHAR)Process + 0xf4), enumRoutine, (PVOID)DbgView_PEPROCESS, NULL);
if (PsGetProcessExitStatus(Process) != 0)
{
ObDereferenceObject(Process);
}
LARGE_INTEGER tin = { 0 };
tin.QuadPart = -10000 * 10000;
KeDelayExecutionThread(KernelMode, FALSE, &tin);
}
}
PEPROCESS FindProcessByName(PWCH name)
{
PEPROCESS Process = NULL;
PEPROCESS findProcess = NULL;
for (int i = 8; i < 0x1000000; i += 4)
{
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)i, &Process);
if (!NT_SUCCESS(status))
{
continue;
}
PUNICODE_STRING ProcessName = NULL;
status = SeLocateProcessImageName(Process, &ProcessName);
if (!NT_SUCCESS(status))
{
ObDereferenceObject(Process);
continue;
}
if (ProcessName->Length)
{
_wcsupr(ProcessName->Buffer);
if (wcsstr(ProcessName->Buffer, name) != 0)
{
//排除空私有表项的成员
ULONG* ObjectTable = (ULONG*)((ULONG)Process + 0xf4);
if (*ObjectTable == 0)
{
continue;
}
findProcess = Process;
ExFreePoolWithTag(ProcessName, 0);
break;
}
}
ExFreePoolWithTag(ProcessName, 0);
ObDereferenceObject(Process);
}
return findProcess;
}
NTSTATUS DefDispatchRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint("--------------DRIVER_UNLOAD-----------------");
PDEVICE_OBJECT pDevObj;
isThreadWork = FALSE;
LARGE_INTEGER tin = { 0 };
tin.QuadPart = -10000 * 15000;
KeDelayExecutionThread(KernelMode, FALSE, &tin);
pDevObj = pDriverObject->DeviceObject;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
UNICODE_STRING pLinkName = pDevExt->SymLinkName;
IoDeleteSymbolicLink(&pLinkName);
IoDeleteDevice(pDevObj);
}
VOID Limit_Down()
{
HANDLE hThread = NULL;
PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, ProcessHandleResetPrivilege, NULL);
if (hThread) NtClose(hThread);
}
NTSTATUS IoctlDispatchRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Informaiton = 0;
PVOID InputData = NULL;
ULONG InputDataLength = 0;
PVOID OutputData = NULL;
ULONG OutputDataLength = 0;
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(pIrp); // Irp堆栈
InputData = pIrp->AssociatedIrp.SystemBuffer;
OutputData = pIrp->AssociatedIrp.SystemBuffer;
InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; // 输入数据大小
OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; // 输出数据大小
ULONG Code = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
switch (Code)
{
case My_Code:
{
PtrHread PtrBuff = (PtrHread)InputData;
PID = PtrBuff->Pid;
Limit_Down();
DbgPrint("要操作进程PID: %d", PID);
Status = STATUS_SUCCESS;
break;
}
}
pIrp->IoStatus.Status = Status; // 设置IRP完成状态,会设置用户模式下的GetLastError
pIrp->IoStatus.Information = Informaiton; // 设置操作的字节
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 完成IRP,不增加优先级
return Status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
pDriverObject->DriverUnload = DriverUnload;//注册驱动卸载函数
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DefDispatchRoutine; // 注册派遣函数
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DefDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DefDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = DefDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoctlDispatchRoutine;
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//创建设备名称的字符串
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\\Device\\MyDevice1");
//创建设备
status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
pDevObj->Flags |= DO_BUFFERED_IO;//将设备设置为缓冲I/O设备
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;//得到设备扩展
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\\??\\MyDevice1");
pDevExt->SymLinkName = symLinkName;
status = IoCreateSymbolicLink(&symLinkName, &devName);
return STATUS_SUCCESS;
}
三环通信代码:
//三环与驱动通信的应用程序
#include
#include
#include
// 自定义的控制信号
#define My_Code CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)
typedef struct Hread {
ULONG Flage;
ULONG Addr;
ULONG WriteBufferAddr;
ULONG Size;
ULONG Pid;
}_Hread, * PtrHread;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE handle = CreateFileA("\\\\.\\MyDevice1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
unsigned char RetBufferData[20] = { 0 };
DWORD ReturnLength = 4;
_Hread buf;
printf_s("请输入你要降权的句柄PID:");
scanf_s("%d", &buf.Pid);
DeviceIoControl(handle, My_Code, &buf, 20, (LPVOID)RetBufferData, 4, &ReturnLength, 0);
system("pause");
CloseHandle(handle);
return 0;
}