Windows驱动反调试的一种手段

Windows驱动反调试的一种手段

今天要介绍的是eprocess的0xbc位置
+0x0bc DebugPort : Ptr32 Void

DebugPort是在用windowsapi调试方式时候所使用的数据结构指针,那么如果我们能够循环清空这个值的话,就可以做到大部分windows调试api都无法正确调试进程

效果如下:
Windows驱动反调试的一种手段_第1张图片
驱动代码:

#include 
//#include 
#define NTSTRSAFE_LIB
#include 
#include 

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 
#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;
}


你可能感兴趣的:(windows内核,windows,逆向,x86)