#include
typedef struct _SDT
{
PULONG ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
PUCHAR ParamTableBase;
}SDT, *PSDT;
typedef
NTSTATUS
(__stdcall *ZWSETINFORMATIONFILE)(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass);
extern "C" PSDT KeServiceDescriptorTable; //ntoskrnl.exe导出的
PULONG pFuncSDT; //原函数地址在SSDT中的位置
ZWSETINFORMATIONFILE OriZwSetInformationFile; //原函数地址
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject);
VOID Hook();
VOID UnHook();
NTSTATUS MyZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass);
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegPath)
{
pDriverObject->DriverUnload = DriverUnload;
Hook();
return STATUS_SUCCESS;
}
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
UnHook();
}
VOID Hook()
{
UNICODE_STRING strFuncName;
RtlInitUnicodeString(&strFuncName, L"ZwSetInformationFile");
pFuncSDT = KeServiceDescriptorTable->ServiceTableBase +
*PULONG((PUCHAR)MmGetSystemRoutineAddress(&strFuncName) + 1);
OriZwSetInformationFile = ZWSETINFORMATIONFILE(*pFuncSDT);
DbgPrint("OriZwSetInformationFile:%x\r\n", OriZwSetInformationFile);
__asm
{
cli
mov eax,cr0
and eax,not 10000h //清除cr0的WP位
mov cr0,eax
}
*pFuncSDT = (ULONG)MyZwSetInformationFile;
DbgPrint("---Hook---\r\n");
__asm
{
mov eax,cr0
or eax,10000h //恢复cr0的WP位
mov cr0,eax
sti
}
}
VOID UnHook()
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*pFuncSDT = (ULONG)OriZwSetInformationFile;
DbgPrint("---UnHook---\r\n");
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
NTSTATUS MyZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
PFILE_OBJECT pFileObject;
NTSTATUS ret = ObReferenceObjectByHandle(FileHandle, GENERIC_READ,
*IoFileObjectType, KernelMode, (PVOID*)&pFileObject, 0);
if (NT_SUCCESS(ret))
{
UNICODE_STRING uDosName;
ret = IoVolumeDeviceToDosName(pFileObject->DeviceObject, &uDosName); //XP and later
if (NT_SUCCESS(ret))
{
if (!_wcsicmp(pFileObject->FileName.Buffer, L"\\test.txt") &&
!_wcsicmp(uDosName.Buffer, L"C:"))
{
ExFreePool(uDosName.Buffer);
return STATUS_ACCESS_DENIED;
}
ExFreePool(uDosName.Buffer);
}
}
return OriZwSetInformationFile(FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass);
}