Home  >  Article  >  Database  >  PASS TesSafe

PASS TesSafe

WBOY
WBOYOriginal
2016-06-07 15:05:441016browse

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

}

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn