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