首页  >  文章  >  数据库  >  PASS TesSafe

PASS TesSafe

WBOY
WBOY原创
2016-06-07 15:05:441016浏览

#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

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

cAbs = TrgAddr + i; 

pCode[i] = *(PUCHAR)cAbs; 

switch (*(PUCHAR)cAbs) 

case 0x0F: //JXX NEAR X 

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

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

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

(oRel + cAbs + 6

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

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

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!"); 

}

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn