hfloveyy
驱动牛犊
驱动牛犊
  • 注册日期2007-12-11
  • 最后登录2008-05-30
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:1987回复:1

fsd inline hook IRP_MJ_DIRECTORY_CONTROL

楼主#
更多 发布于:2008-05-17 22:52
fsd inline hook IRP_MJ_DIRECTORY_CONTROL 在完成例程中隐藏了文件会bosd 注释掉hidefile就正常了 想了很久 觉得可能是同步问题 希望大家帮我看看 谢谢了
#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;

typedef struct tag_QUERY_DIRECTORY
{
  ULONG Length;
  PUNICODE_STRING FileName;
  FILE_INFORMATION_CLASS FileInformationClass;
  ULONG FileIndex;
} QUERY_DIRECTORY, *PQUERY_DIRECTORY;


NTSYSAPI NTSTATUS
ObReferenceObjectByName(
                        IN PUNICODE_STRING ObjectPath,
                        IN ULONG Attributes,
                        IN PACCESS_STATE PassedAccessState OPTIONAL,
                        IN ACCESS_MASK DesiredAccess OPTIONAL,
                        IN POBJECT_TYPE ObjectType,
                        IN KPROCESSOR_MODE AccessMode,
                        IN OUT PVOID ParseContext OPTIONAL,
                        OUT PVOID *ObjectPtr);

typedef    NTSTATUS    (*OLDIRPMJDIRECTORYCONTROL)(IN PDEVICE_OBJECT,IN PIRP);



NTSTATUS HookFastFat();//hook fastfat.sys
NTSTATUS MyCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context);//完成示例
VOID write();//写入补丁
VOID write_back();//写回补丁
NTAPI MyDirectoryControl();//这个函数将inline在IRP_MJ_DIRECTORY_CONTROL之前
NTSTATUS Check();//测试一下  其实是硬编码 如果想应用在不同平台 需要改进


PDRIVER_OBJECT    pFile=NULL;//fastfat的PDRIVER_OBJECT
OLDIRPMJDIRECTORYCONTROL    OldIrpMjDirectoryControl;//原来的MajorFunction[IRP_MJ_DIRECTORY_CONTROL]
BOOL hook;//hook标志
PIO_STACK_LOCATION    irpStack;
DWORD                context;

// This is our unload function
BOOLEAN
HideFile(IN OUT PFILE_BOTH_DIR_INFORMATION DirInfo, IN PULONG lpBufLenth)
{
    ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
    UNICODE_STRING uniFileName;
    PFILE_BOTH_DIR_INFORMATION currentDirInfo = DirInfo;
    PFILE_BOTH_DIR_INFORMATION lastDirInfo = NULL;
    ULONG offset = 0;
    ULONG position = 0;
    ULONG newLenth = *lpBufLenth;
    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 -= *lpBufLenth - position;
                }
                else
                {
                    currentDirInfo->NextEntryOffset = 0;
                    *lpBufLenth = 0;
                    return TRUE;
                }
            }
            else
            {
                RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset);
                newLenth -= offset;
                position += offset;
            }
        }
        else
        {
            position += offset;
            lastDirInfo = currentDirInfo;
            currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)currentDirInfo + offset);
        }
    } while (0 != offset);
    *lpBufLenth = newLenth;
    return TRUE;
}

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )

{

    DbgPrint("OnUnload called\n");
    if (hook)
    {
        write_back();
    }
    //这里我用的方法是inline hook 还可以用下面方法hook IRP
    /*if (OldIrpMjDirectoryControl&&pFile)
    {
        InterlockedExchange((PLONG)&pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL],(LONG)OldIrpMjDirectoryControl);
    }*/

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,

                    IN PUNICODE_STRING theRegistryPath)

{
        NTSTATUS ntStatus;
        DbgPrint("I loaded!");
        ntStatus=HookFastFat();
        if(!NT_SUCCESS(ntStatus))
            return    ntStatus;
      // Initialize the pointer to the unload function

      // in the DriverObject

        theDriverObject->DriverUnload  = OnUnload;

        return STATUS_SUCCESS;

}
//hook fastfat.sys
NTSTATUS HookFastFat()
{
    char *p;
    int    i;
    NTSTATUS ntStatus;
    UNICODE_STRING    sFastFat;
    WCHAR    FastFatBuffer[]=L"\\FileSystem\\Fastfat";
    RtlInitUnicodeString(&sFastFat,FastFatBuffer);
    //得到pFile
    ntStatus=ObReferenceObjectByName(&sFastFat,
                                    OBJ_CASE_INSENSITIVE,NULL,0,
                                    ( POBJECT_TYPE )IoDriverObjectType,
                                    KernelMode,NULL,&pFile);
    
    if(!NT_SUCCESS(ntStatus))
        return ntStatus;
    //保持一下旧的MajorFunction[IRP_MJ_DIRECTORY_CONTROL]
    OldIrpMjDirectoryControl=pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL];
    //p=(char *)OldIrpMjDirectoryControl;
    //函数地址change hook
    /*if (OldIrpMjDirectoryControl)
    {
        InterlockedExchange((PLONG)&pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL],(LONG)MyControl);
    }*/
    //DbgPrint("%08X",p);
    /*for(i=0;i<7;i++)
    {
        DbgPrint("-0x%02X",(unsigned char)p);
    }*/
    //在此处将补丁写入 将hook标志置TRUE
    if(NT_SUCCESS(Check()))
    {
        DbgPrint(" check SUCCESS");
        write();
        hook=TRUE;
    }
    else
        DbgPrint(" check UNSUCCESSFUL");
    return    ntStatus;
}
//测试一下
NTSTATUS Check()
{
    int i=0;
    char *p=(char *)OldIrpMjDirectoryControl;
    char c[]={0x6a,0x18,0x68,0x20,0x3d,0xd8,0xf9};
    for(;i<7;i++)
    {
        DbgPrint("-0x%02X",(unsigned char)p);
        if(p!=c)
        {
            return STATUS_UNSUCCESSFUL;
        }
    }
    return STATUS_SUCCESS;
}

//写入补丁
VOID write()
{
    KIRQL oldIrql;
    char *actual_function=(char *)OldIrpMjDirectoryControl;
    char *non_paged_memory;
    unsigned long detour_address;
    unsigned long reentry_address;
    int i = 0;
    //jmp 11223344
    char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00 };
    //要返回的地址是原来地址+7
    reentry_address = ((unsigned long)OldIrpMjDirectoryControl) + 7;
    //分配空间 要是NonPagedPool
    non_paged_memory = ExAllocatePool(NonPagedPool,1024);
    //将补丁写入non_paged_memory
    for(i=0;i<1024;i++)
    {
        ((unsigned char *)non_paged_memory) = ((unsigned char *)MyDirectoryControl);
    }
    //将地址保持在detour_address
    detour_address = (unsigned long)non_paged_memory;
    //将11223344替换为真正补丁地址
    *( (unsigned long *)(&newcode[1]) ) = detour_address;

    //将AAAAAAAA替换为真正的返回地址
    for(i=0;i<1024;i++)
    {
        if( (0xAA == ((unsigned char *)non_paged_memory)) &&
            (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) ) = reentry_address;
            break;
        }
    }
    oldIrql = KeRaiseIrqlToDpcLevel();
    //写入补丁了
    __asm
    {
            push eax
            mov  eax, CR0
            and  eax, 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }

    for(i=0;i < 7;i++)
    {
        actual_function = newcode;
    }

    __asm
    {
            push eax
            mov  eax, CR0
            or  eax, NOT 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }
    KeLowerIrql(oldIrql);
}
//写回
VOID write_back()
{
    KIRQL oldIrql;
    char *actual_function=(char *)OldIrpMjDirectoryControl;
    //将原来的指令写回 此处用的硬编码
    char c[]={0x6a,0x18,0x68,0x20,0x3d,0xd8,0xf9};
    int i;
    oldIrql = KeRaiseIrqlToDpcLevel();
    __asm
    {
            push eax
            mov  eax, CR0
            and  eax, 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }

    for(i=0;i < 7;i++)
    {
        actual_function = c;
    }

    __asm
    {
            push eax
            mov  eax, CR0
            or  eax, NOT 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }
    KeLowerIrql(oldIrql);
}
//此处为naked 函数 防止编译器放入额外操作码
__declspec(naked) NTAPI MyDirectoryControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    irpStack=IoGetCurrentIrpStackLocation(Irp);    
    irpStack->Control = 0;
    irpStack->Control = SL_INVOKE_ON_SUCCESS;
    irpStack->Control |= SL_INVOKE_ON_ERROR;
    irpStack->Control |= SL_INVOKE_ON_CANCEL;
    irpStack->CompletionRoutine=(PIO_COMPLETION_ROUTINE)MyCompletionRoutine;
        __asm
    {        
        // exec missing instructions
        push    18h
        push    0F9D83D20h
    }
        // 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
    }
}
//CompletionRoutine
NTSTATUS MyCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)
{
    //HideFile(Irp->UserBuffer,  &((PQUERY_DIRECTORY)&irpStack->Parameters)->Length);
  
    DbgPrint("MyCompletionRoutine called");
    return Irp->IoStatus.Status;
}
hfloveyy
驱动牛犊
驱动牛犊
  • 注册日期2007-12-11
  • 最后登录2008-05-30
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-05-22 17:47
没人理我呢  自己小顶一下 继续等待大牛帮助
游客

返回顶部