|
以前做文件保护写过object type,dispatch hook,文件过滤驱动。
一直没在ntfs驱动的做手脚,昨天突然来兴趣了,于是。。。
在一天+一夜内,通过nt4src中的ntfs+windbg+ida。
对ntfs的删除文件流程(IRP_MJ_SET_INFORMATION的例程),以及xcb的结构了解了一通。
流程如下:
NtfsFsdSetInformation---->NtfsCommonSetInformation---->NtfsSetDispositionInfo
最后在NtfsSetDispositionInfo里,我发现了MmFlushImageSection这个导出函数,调用如下:- if (!MmFlushImageSection( &Scb->NonpagedScb->SegmentObject,
- MmFlushForDelete ))
复制代码 很容易想到hook,于是就有了下面的代码:- #include <wdm.h>
- #include <windef.h>
- NTSTATUS
- DriverEntry( PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegisterPath
- );
-
- #pragma alloc_text(INIT, DriverEntry)
- //////////////////////////////////////////////////
- //global
- /////////////////////////////////////////////////
- PVOID g_section_pointer;
- PVOID g_orig_address;
- BYTE origcode[5] = {0};
- BOOL isHook = FALSE;
- typedef enum _MMFLUSH_TYPE {
- MmFlushForDelete,
- MmFlushForWrite
- } MMFLUSH_TYPE;
- ///////////////////////////////////////////////
- //function
- //////////////////////////////////////////////
- VOID WPON()
- {
- __asm{
- mov eax,cr0
- or eax,0x10000
- mov cr0,eax
- STI
- }
-
- }
- VOID WPOFF()
- {
- __asm{
- cli
- mov eax, cr0
- and eax,not 0x10000
- mov cr0,eax
- }
-
- }
- __declspec(naked)
- BOOLEAN
- fake_MmFlushImageSection (
- __in PSECTION_OBJECT_POINTERS SectionPointer,
- __in MMFLUSH_TYPE FlushType
- )
- {
- _asm
- {
- mov edi,edi
- push ebp
- mov ebp,esp
- push eax
- mov eax,SectionPointer
- cmp eax, g_section_pointer
- jnz laborig
- mov eax, FlushType
- test eax,eax
- jnz laborig
- pop eax
- mov eax, 0
- jmp labret
- laborig:
- pop eax
- mov eax, g_orig_address
- add eax, 5
- jmp eax
- labret:
- pop ebp
- ret 8
- }
- }
- VOID
- HookMmFlushImageSection()
- {
- UNICODE_STRING hook_function;
- PVOID hook_addr;
- BYTE jmpcode[5] = {0xe9, 0x00, 0x00, 0x00, 0x00};
- ULONG distance;
-
- //获得MmFlushImageSection地址
- RtlInitUnicodeString( &hook_function, L"MmFlushImageSection" );
- hook_addr = MmGetSystemRoutineAddress( &hook_function );
- g_orig_address = hook_addr;
- //计算偏移量
- distance = (ULONG)fake_MmFlushImageSection - (ULONG)hook_addr - 5;
- RtlCopyMemory( jmpcode + 1, (BYTE*)&distance , 4);
-
- KdBreakPoint();
- //开始hook
- WPOFF();
- RtlCopyMemory( origcode, (BYTE*)g_orig_address, 5);
- RtlCopyMemory( (BYTE*)g_orig_address, jmpcode, 5 );
- isHook = TRUE;
- WPON();
- }
- VOID
- DriverUnload(IN PDRIVER_OBJECT DriverObject )
- {
- if (isHook == TRUE)
- RtlCopyMemory( (BYTE*)g_orig_address, origcode, 5);
- }
- NTSTATUS
- DriverEntry( PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegisterPath
- )
- {
- UNICODE_STRING protect_path;
- HANDLE profile_handle;
- PFILE_OBJECT profile_obj;
- OBJECT_ATTRIBUTES obja;
- IO_STATUS_BLOCK io_status;
- NTSTATUS status = STATUS_SUCCESS;
-
- DriverObject->DriverUnload = DriverUnload;
-
- RtlInitUnicodeString( &protect_path, L"\\??\\c:\\ywledoc.txt" );
- InitializeObjectAttributes( &obja,
- &protect_path,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
- status = ZwCreateFile( &profile_handle,
- FILE_ANY_ACCESS,
- &obja,
- &io_status,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_OPEN,
- FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS |
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NO_INTERMEDIATE_BUFFERING,
- NULL,
- 0);
- if (!NT_SUCCESS(status)) {
- KdPrint(("XCB @ DriverEntry : IoCreateFile Error %08x\n", status));
- return STATUS_SUCCESS;
- }
-
- status = ObReferenceObjectByHandle( profile_handle,
- FILE_READ_DATA,
- NULL,
- KernelMode,
- &profile_obj,
- NULL);
- if (!NT_SUCCESS(status)) {
- KdPrint(("XCB @ DriverEntry : ObReferenceObjectByHandle Error %08x\n", status));
- return STATUS_SUCCESS;
- }
-
- KdPrint(("XCB @ DriverEntry : file_object is %08x\n", profile_obj));
- g_section_pointer = profile_obj->SectionObjectPointer;
-
- HookMmFlushImageSection();
-
- return STATUS_SUCCESS;
- }
复制代码 虽然网上有类似的代码,但是本代码是作者独自编写的,思路也是自己想出来的。所以,我把它归为原创一类去了。 |
|