Windows驱动反调试的一种手段
今天要介绍的是eprocess的0xbc位置
+0x0bc DebugPort : Ptr32 Void
DebugPort是在用windowsapi调试方式时候所使用的数据结构指针,那么如果我们能够循环清空这个值的话,就可以做到大部分windows调试api都无法正确调试进程
效果如下:
驱动代码:
#include <ntddk.h>
//#include <ntifs.h>
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#include <intrin.h>extern NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId,PEPROCESS* Process
);PDEVICE_OBJECT g_pDev = NULL;
UNICODE_STRING devName = { 0 };
UNICODE_STRING symName = { 0 };
DWORD32 g_idtNum = 0;
PVOID sharedMem;
BOOLEAN g_LoopDelDebugportRun = FALSE;
HANDLE g_LoopDelProcessThreadHandle = 0;VOID Unload(PDRIVER_OBJECT pDriver) {KdPrint(("unload"));if (g_LoopDelDebugportRun) {LARGE_INTEGER time = { 0 };time.QuadPart = -100 * 10 * 1000 * 10;//10秒g_LoopDelDebugportRun = FALSE;KeWaitForSingleObject(&g_LoopDelProcessThreadHandle, Executive, KernelMode,FALSE, &time);ZwClose(g_LoopDelProcessThreadHandle);}IoDeleteSymbolicLink(&symName);IoDeleteDevice(g_pDev);}typedef struct _IDTR {UINT16 limit;UINT16 base_low;UINT16 base_hight;
}IDTR, *PIDTR;
#define DEVICE_OBJECT_NAME L"\\Device\\systest"
#define DEVICE_LINK_NAME L"\\??\\systest"
#define MAKE_WORD(a,b) ((a) + (b << 16))
#define MAKE_BASE(a) (DWORD32)(((a >> 32) & 0x00000000ffff0000) + ((a & 0x000000000000ffff)))
#define IOCTL_SYS_INJECTIDT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, \METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SYS_MAKE_SHAREDPAGE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, \METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SYS_HIDEPROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, \METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SYS_DELDEBUGPORT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, \METHOD_BUFFERED, FILE_ANY_ACCESS)VOID LoopDelDebugport(PVOID context)
{LARGE_INTEGER time = { 0 };time.QuadPart = -100 * 10 * 1000 * 3;//3秒g_LoopDelDebugportRun = TRUE;PUINT32 port = context;while (g_LoopDelDebugportRun){*port = 0x0;KeDelayExecutionThread(KernelMode, FALSE, &time);}PsTerminateSystemThread(0);//销毁内核对象
}NTSTATUS DelProcDebport(UINT32 pid)
{PEPROCESS pEprocess = NULL;_asm {mov eax, fs: [0x124]mov eax, [eax + 0x220]mov pEprocess, eax}PLIST_ENTRY listHead = (PLIST_ENTRY)((PUCHAR)pEprocess + 0x88);if (listHead == NULL)return STATUS_UNSUCCESSFUL;PLIST_ENTRY next = listHead;//DbgBreakPoint();do{pEprocess = (PEPROCESS)((PUCHAR)next - 0x88);DWORD32 cpid = *(PDWORD32)((PUCHAR)pEprocess + 0x84);if (cpid == pid) {LPSTR name = NULL;name = (PUCHAR)pEprocess + 0x174;KdPrint(("该进程名称: %s\n", name));PVOID context = (PVOID)((PUCHAR)pEprocess + 0xbc);NTSTATUS status = PsCreateSystemThread(&g_LoopDelProcessThreadHandle,0, NULL, NULL, NULL, LoopDelDebugport, context);if (!NT_SUCCESS(status)) {KdPrint(("创建循环清空debugpoprt线程失败!\r\n"));return status;}KdPrint(("触发反调试线程成功!\n"));return STATUS_SUCCESS;}next = next->Flink;} while (next != NULL && listHead != next);return STATUS_UNSUCCESSFUL;
}NTSTATUS DeviceControl(PDEVICE_OBJECT pDev, PIRP pIrp)
{NTSTATUS status = STATUS_SUCCESS;ULONG_PTR Informaiton = 0;ULONG ioControlCode = 0;PVOID input = NULL;ULONG inputLen = 0;PVOID output = NULL;ULONG outputLen = 0;PIO_STACK_LOCATION pIoStackLocation = IoGetCurrentIrpStackLocation(pIrp);ioControlCode = pIoStackLocation->Parameters.DeviceIoControl.IoControlCode;input = pIrp->AssociatedIrp.SystemBuffer;output = pIrp->AssociatedIrp.SystemBuffer;inputLen = pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength;outputLen = pIoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;switch (ioControlCode){case IOCTL_SYS_DELDEBUGPORT:{DWORD32* data = (PDWORD32)input;UINT32 pid = data[0];status = DelProcDebport(pid);if (!NT_SUCCESS(status)) {KdPrint(("failed del process debugport!\n"));}break;}default:break;}pIrp->IoStatus.Status = status;pIrp->IoStatus.Information = Informaiton;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return status;
}NTSTATUS PassFunc(PDEVICE_OBJECT pDev, PIRP pIrp)
{pIrp->IoStatus.Information = 0;pIrp->IoStatus.Status = STATUS_SUCCESS;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS;
}NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {NTSTATUS status = STATUS_SUCCESS;pDriver->DriverUnload = Unload;for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++){pDriver->MajorFunction[i] = PassFunc;}pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;do{KdPrint(("begin\r\n"));//创建设备对象RtlInitUnicodeString(&devName, DEVICE_OBJECT_NAME);status = IoCreateDevice(pDriver, 0, &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDev);if (!NT_SUCCESS(status)) {KdPrint(("Create Dev Object Failed!\r\n"));break;}RtlInitUnicodeString(&symName, DEVICE_LINK_NAME);status = IoCreateSymbolicLink(&symName, &devName);if (!NT_SUCCESS(status)) {KdPrint(("Create Sym Link Failed!\r\n"));IoDeleteDevice(g_pDev);break;}g_pDev->Flags |= DO_BUFFERED_IO;} while (FALSE);return status;
}
三环代码:
// test1.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <windows.h>
#define DEVICE_LINK_NAME L"\\\\.\\systest"
#define IOCTL_SYS_INJECTIDT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, \METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SYS_MAKE_SHAREDPAGE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, \METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SYS_HIDEPROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, \METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SYS_DELDEBUGPORT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, \METHOD_BUFFERED, FILE_ANY_ACCESS)
int _tmain(int argc, _TCHAR* argv[])
{HANDLE devHandle = CreateFile(DEVICE_LINK_NAME,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if (devHandle == NULL || devHandle == INVALID_HANDLE_VALUE) {printf("open dev failed\n");return 0;}UINT32 pid = GetCurrentProcessId();DWORD returnLen = 0;BOOL IsOK = DeviceIoControl(devHandle,IOCTL_SYS_DELDEBUGPORT,&pid,sizeof(pid),&pid,sizeof(pid),&returnLen,NULL);CloseHandle(devHandle);devHandle = NULL;while(true){printf("test\n");Sleep(1000);}return 0;
}