PASS TesSafe

#include ntddk.h #define ThreadLength 0x190 //要保存的 NtOpenThread 原代码的长度 #define ProcessLength 0x184 //要保存的 NtOpenProcess 原代码的长度 #define DeviceLink L\\Device\\DNFCracker #define SymbolicLink L\\DosDevices\\DNFCracker #def

#include "ntddk.h"

#define ThreadLength 0x190 //要保存的 NtOpenThread 原代码的长度

#define ProcessLength 0x184 //要保存的 NtOpenProcess 原代码的长度

#define DeviceLink L"\\Device\\DNFCracker"

#define SymbolicLink L"\\DosDevices\\DNFCracker"

#define IOCTL_RESTORE (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x886, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef NTSTATUS (* NTOPENTHREAD)(

OUT PHANDLE ThreadHandle,

IN ACCESS_MASK DesiredAccess,

IN POBJECT_ATTRIBUTES ObjectAttributes,

IN OPTIONAL PCLIENT_ID ClientId

);

typedef NTSTATUS (* NTOPENPROCESS)(

OUT PHANDLE ProcessHandle,

IN ACCESS_MASK DesiredAccess,

IN POBJECT_ATTRIBUTES ObjectAttributes,

IN PCLIENT_ID ClientId

);

typedef struct _SERVICE_DESCRIPTOR_TABLE

{

PVOID ServiceTableBase;

PULONG ServiceCounterTableBase;

ULONG NumberOfService;

ULONG ParamTableBase;

}

SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

VOID Hook();

VOID Unhook();

NTOPENTHREAD OldThread;

NTOPENPROCESS OldProcess;

ULONG AddrRead, AddrWrite;

//原 NtReadVirtualMemory/NtWriteVirtualMemory 的前 16 字节代码

ULONG OrgRead[2], OrgWrite[2];

//保存 NtOpenThread/NtOpenProcess 代码

UCHAR MyThread[ThreadLength], MyProcess[ProcessLength];

NTSTATUS MyNtOpenThread(

PHANDLE ThreadHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)

{

ACCESS_MASK oDA;

OBJECT_ATTRIBUTES oOA;

CLIENT_ID oCID;

NTSTATUS statusF, statusT;

oDA = DesiredAccess;

oOA = *ObjectAttributes;

oCID = *ClientId;

statusF = OldThread(ThreadHandle, oDA, &oOA, &oCID);

statusT = ((NTOPENTHREAD)MyThread)(ThreadHandle, DesiredAccess, ObjectAttributes, ClientId);

return statusT;

}

NTSTATUS MyNtOpenProcess(

PHANDLE ProcessHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)

{

ACCESS_MASK oDA;

OBJECT_ATTRIBUTES oOA;

CLIENT_ID oCID;

NTSTATUS statusF, statusT;

oDA = DesiredAccess;

oOA = *ObjectAttributes;

oCID = *ClientId;

statusF = OldProcess(ProcessHandle, oDA, &oOA, &oCID);

statusT = ((NTOPENPROCESS)MyProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

return statusT;

}

NTSTATUS DispatchIoCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

ULONG ioControlCode;

ULONG inBufLength, outBufLength;

//PUCHAR InputBuffer, OutputBuffer;

NTSTATUS status = STATUS_SUCCESS;

PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;

outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

switch (ioControlCode)

{

case IOCTL_RESTORE:

//InputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;

//OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;

//恢复 NtReadVirtualMemory/NtWriteVirtualMemory 前 16 字节

*(PULONG)(*(PULONG)AddrRead) = OrgRead[0];

*(PULONG)(*(PULONG)AddrRead + 4) = OrgRead[1];

*(PULONG)(*(PULONG)AddrWrite) = OrgWrite[0];

*(PULONG)(*(PULONG)AddrWrite + 4) = OrgWrite[1];

Irp->IoStatus.Information = outBufLength;

break;

default:

DbgPrint("Unknown IOCTL: 0x%X (%04X)",

ioControlCode, IoGetFunctionCodeFromCtlCode(ioControlCode));

status = STATUS_INVALID_PARAMETER;

Irp->IoStatus.Information = 0;

}

//完成 IRP

Irp->IoStatus.Status = status;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

}

NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

Irp->IoStatus.Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Irp->IoStatus.Status;

}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)

{

UNICODE_STRING usLink;

/*ULONG i;

for (i = 0; i < ThreadLength; i += 4)

{

DbgPrint("%02x %02x %02x %02x\n", MyThread[i], MyThread[i + 1], MyThread[i + 2], MyThread[i + 3]);

DbgPrint("%02x %02x %02x %02x\n", MyProcess[i], MyProcess[i + 1], MyProcess[i + 2], MyProcess[i + 3]);

}

*/

Unhook();

DbgPrint("DNF Cracker Unloaded!");

RtlInitUnicodeString(&usLink, SymbolicLink);

IoDeleteSymbolicLink(&usLink);

IoDeleteDevice(DriverObject->DeviceObject);

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

NTSTATUS status;

PDEVICE_OBJECT DvcObj;

UNICODE_STRING usDevice, usLink;

PLIST_ENTRY pLE = (PLIST_ENTRY)DriverObject->DriverSection;

//隐藏驱动

pLE->Flink->Blink = pLE->Blink;

pLE->Blink->Flink = pLE->Flink;

DriverObject->DriverUnload = OnUnload;

//创建虚拟设备

RtlInitUnicodeString(&usDevice, DeviceLink);

status = IoCreateDevice(DriverObject, 0, &usDevice, FILE_DEVICE_UNKNOWN, 0, TRUE, &DvcObj);

if (!NT_SUCCESS(status))

{

DbgPrint("Failed to create device!\n");

return status;

}

//创建符号链接

RtlInitUnicodeString(&usLink, SymbolicLink);

status = IoCreateSymbolicLink(&usLink, &usDevice);

if (!NT_SUCCESS(status))

{

IoDeleteDevice(DriverObject->DeviceObject);

DbgPrint("Failed to create symbolic link!\n");

return status;

}

//调度函数分配

DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =

DriverObject->MajorFunction[IRP_MJ_CREATE] =

DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoCtrl;

Hook();

DbgPrint("DNF Cracker Loaded!");

return STATUS_SUCCESS;

}

// OrgRel 原相对跳转地址

// CurAbs 当前代码绝对地址

// MyAbs 替换代码绝对地址

// CodeLen 跳转代码占据的长度

// 返回值 到替换代码的相对地址

LONG GetRelAddr(LONG OrgRel, ULONG CurAbs, ULONG MyAbs) //, ULONG CodeLen)

{

ULONG TrgAbs;

TrgAbs = CurAbs + OrgRel; // + CodeLen; //目的地址

return TrgAbs - MyAbs;

}

// 保存原来整个函数的代码

// pCode 用来保存代码的数组的地址

// TrgAddr 要保存的函数的地址

// BufferLength 整个函数占用的大小

VOID BufferCode(PUCHAR pCode, ULONG TrgAddr, ULONG BufferLength)

{

ULONG cAbs, i;

LONG oRel, cRel;

memset(pCode, 0x90, BufferLength);

for (i = 0; i < BufferLength; i++)

{

cAbs = TrgAddr + i;

pCode[i] = *(PUCHAR)cAbs;

switch (*(PUCHAR)cAbs)

{

case 0x0F: //JXX NEAR X

if ((*(PUCHAR)(cAbs + 1) >= 0x80)&&(*(PUCHAR)(cAbs + 1) <= 0x8F))

{

oRel = *(PLONG)(cAbs + 2);

if ((oRel + cAbs + 6 > TrgAddr + BufferLength)||

(oRel + cAbs + 6 < TrgAddr)) //判断跳转是否在过程范围内

{

pCode[i + 1] = *(PUCHAR)(cAbs + 1);

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 2, &cRel, sizeof(LONG));

//DbgPrint("JXX: 0x%08X -> 0x%08X", cAbs, (ULONG)pCode + i);

i += sizeof(LONG) + 1;

}

}

break;

case 0xE8: //CALL

oRel = *(PLONG)(cAbs + 1);

if ((oRel + cAbs + 5 > TrgAddr + BufferLength)||

(oRel + cAbs + 5 < TrgAddr)) //判断跳转是否在过程范围内

{

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, sizeof(LONG));

//DbgPrint("CALL: 0x%08X -> 0x%08X", cAbs, (ULONG)pCode + i);

i += sizeof(LONG);

}

break;

case 0x80: //CMP BYTE PTR X

if (*(PUCHAR)(cAbs + 1) == 0x7D)

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), 3);

i += 3; continue;

}

break;

case 0xC2: //RET X

if (*(PUSHORT)(cAbs +1) == 0x10)

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));

i += sizeof(USHORT);

}

break;

/*case 0xE9: //JMP

oRel = *(PLONG)(cAbs + 1);

if (oRel + cAbs > TrgAddr + BufferLength)

{

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, sizeof(LONG));

i += 4;

}*/

}

if ((*(PUCHAR)cAbs == 0x39)||(*(PUCHAR)cAbs == 0x89)||(*(PUCHAR)cAbs == 0x8D))

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));

i += sizeof(USHORT); continue;

}

/*if ((*(PUCHAR)cAbs >= 0x70)&&(*(PUCHAR)cAbs <= 0x7F)&&(*(PUCHAR)(cAbs - 1) != 0xFF))

{

oRel = (LONG)(*(PCHAR)(cAbs + 1));

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, 1);

i++; continue;

}*/

}

}

VOID Hook()

{

ULONG AddrProcess, AddrThread;

AddrRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;

AddrWrite = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;

AddrThread = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;

AddrProcess = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

OldThread = (NTOPENTHREAD)(*(PULONG)AddrThread);

OldProcess = (NTOPENPROCESS)(*(PULONG)AddrProcess);

DbgPrint("MyThread:0x%08X OldThread:0x%08X", MyThread, OldThread);

DbgPrint("MyProcess:0x%08X OldProcess:0x%08X", MyProcess, OldProcess);

__asm

{

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

//记录 NtReadVirtualMemory/NtWriteVirtualMemory 前 16 字节

OrgRead[0] = *(PULONG)(*(PULONG)AddrRead);

OrgRead[1] = *(PULONG)(*(PULONG)AddrRead + 4);

OrgWrite[0] = *(PULONG)(*(PULONG)AddrWrite);

OrgWrite[1] = *(PULONG)(*(PULONG)AddrWrite + 4);

//保存原代码

BufferCode(MyThread, (ULONG)OldThread, ThreadLength);

BufferCode(MyProcess, (ULONG)OldProcess, ProcessLength);

//SSDT Hook

*(PULONG)AddrThread = (ULONG)MyNtOpenThread;

*(PULONG)AddrProcess = (ULONG)MyNtOpenProcess;

__asm

{

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

DbgPrint("Hooked!");

}

VOID Unhook()

{

ULONG AddrProcess, AddrThread;

AddrThread = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;

AddrProcess = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

__asm

{

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

//恢复 SSDT

*(PULONG)AddrThread = (ULONG)OldThread;

*(PULONG)AddrProcess = (ULONG)OldProcess;

__asm

{

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

DbgPrint("Unhooked!");

}

郑重声明:本文版权包含图片归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们(delete@yzlfxy.com)修改或删除,多谢。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

留言与评论(共有 0 条评论)
昵称:
匿名发表
   
验证码: