SSDT替换ZwSetInformationFile实现保护某文件不被删除

#include <ntddk.h>
 
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);
}

你可能感兴趣的:(object,String,File,Class,include,hook)