PASS TesSafe

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

你可能感兴趣的:(职场,pass,休闲,tessafe)