-
-
[讨论]解锁Irp文件占坑的方法
-
发表于: 2023-10-4 20:03 3511
-
先上链接: https://bbs.kanxue.com/thread-257384.htm
1.很简单 只用调用一个函数 NtfsDecrementCleanupCounts这个函数
上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | VOID NtfsDecrementCleanupCounts ( IN PSCB Scb, IN PLCB Lcb OPTIONAL, IN BOOLEAN NonCachedHandle ) / * + + Routine Description: This procedure decrements the cleanup counts for the associated data structures and if necessary it also start to cleanup associated internal attribute streams Arguments: Scb - Supplies the Scb used in this operation Lcb - Optionally supplies the Lcb used in this operation NonCachedHandle - Indicates this handle is for a user non - cached handle. Return Value: None . 翻译: 此过程减少关联数据结构的清理计数 如果有必要,它还会开始清理关联的内部属性流 论据: Scb - 提供此操作中使用的 Scb Lcb - 可选择提供此操作中使用的 Lcb NonCachedHandle - 指示此句柄用于用户非缓存句柄。 - - * / { PVCB Vcb = Scb - >Vcb; ASSERT_SCB( Scb ); ASSERT_FCB( Scb - >Fcb ); ASSERT_VCB( Scb - >Fcb - >Vcb ); ASSERT_OPTIONAL_LCB( Lcb ); / / / / First we decrement the appropriate cleanup counts / / if (ARGUMENT_PRESENT(Lcb)) { Lcb - >CleanupCount - = 1 ; } InterlockedDecrement( &Scb - >CleanupCount ); Scb - >Fcb - >CleanupCount - = 1 ; if (NonCachedHandle) { Scb - >NonCachedCleanupCount - = 1 ; } InterlockedDecrement( &Vcb - >CleanupCount ); / / / / Now if the Fcb's cleanup count is zero that indicates that we are / / done with this Fcb from a user handle standpoint and we should / / now scan through all of the Scb's that are opened under this / / Fcb and shutdown any internal attributes streams we have open . / / For example, EAs and ACLs. We only need to do one. The domino effect / / will take of the rest. / / if (Scb - >Fcb - >CleanupCount = = 0 ) { PSCB NextScb; / / / / Remember if we are dealing with a system file and return immediately. / / if (NtfsSegmentNumber( &Scb - >Fcb - >FileReference ) < FIRST_USER_FILE_NUMBER && NtfsSegmentNumber( &Scb - >Fcb - >FileReference ) ! = ROOT_FILE_NAME_INDEX_NUMBER) { return ; } for (NextScb = CONTAINING_RECORD(Scb - >Fcb - >ScbQueue.Flink, SCB, FcbLinks); &NextScb - >FcbLinks ! = &Scb - >Fcb - >ScbQueue; NextScb = CONTAINING_RECORD( NextScb - >FcbLinks.Flink, SCB, FcbLinks )) { / / / / Skip the root index on the volume. / / if (SafeNodeType( NextScb ) = = NTFS_NTC_SCB_ROOT_INDEX) { continue ; } / / / / If we have an index with children then break out. / / if ((SafeNodeType( NextScb ) = = NTFS_NTC_SCB_INDEX) && !IsListEmpty( &NextScb - >ScbType.Index.LcbQueue )) { break ; } / / / / If there is an internal stream then dereference it and get out. / / if (NextScb - >FileObject ! = NULL) { NtfsDeleteInternalAttributeStream( NextScb, (BOOLEAN) (Scb - >Fcb - >LinkCount = = 0 ) ); break ; } } } / / / / And return to our caller / / return ; } |
IDA 的代码显示 win7x64 ntfs.sys NtfsDecrementCleanupCounts 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | __int64 __fastcall NtfsDecrementCleanupCounts(__int64 a1, __int64 a2, __int64 a3, __int64 a4, int a5) { __int64 v5; / / r10 __int64 result; / / rax __int64 v8; / / rcx unsigned __int16 * v9; / / rdx __int64 v10; / / rdx v5 = * (_QWORD * )(a2 + 0x78 ); if ( a3 ) - - * (_DWORD * )(a3 + 0xCC ); if ( ( * (_BYTE * )( * (_QWORD * )(a2 + 112 ) + 4i64 ) & 4 ) ! = 0 ) return ((__int64 (__fastcall * )(__int64, __int64, __int64, __int64))sub_2A1A4)(a1, a2, a3, a4); _InterlockedAdd((volatile signed __int32 * )(a2 + 0x88 ), 0xFFFFFFFF ); result = * (_QWORD * )(a2 + 0x70 ); _InterlockedAdd((volatile signed __int32 * )(result + 0x10 ), 0xFFFFFFFF ); if ( (_DWORD)a4 ) - - * (_DWORD * )(a2 + 0x84 ); if ( a5 ) { result = * (_QWORD * )(a2 + 0x70 ); - - * (_DWORD * )(result + 0xEC ); } _InterlockedAdd((volatile signed __int32 * )(v5 + 0xD8 ), 0xFFFFFFFF ); v8 = * (_QWORD * )(a2 + 112 ); if ( ! * (_DWORD * )(v8 + 16 ) ) { v9 = 0i64 ; if ( (((unsigned int )&loc_200FF + 1 ) & * (_DWORD * )(v8 + 4 )) = = 0 || * (_DWORD * )(v8 + 8 ) = = 5 ) { while ( 1 ) { v10 = v9 ? * ((_QWORD * )v9 + 12 ) : * (_QWORD * )(v8 + 48 ); result = v8 + 48 ; if ( v10 = = v8 + 48 ) break ; v9 = (unsigned __int16 * )(v10 - 96 ); if ( !v9 ) break ; result = * v9; if ( (_WORD)result ! = 1796 && * ((_DWORD * )v9 + 43 ) ! = 32 ) { if ( * ((_DWORD * )v9 + 34 ) ) return result; if ( (_WORD)result = = 1795 ) { result = (__int64)(v9 + 252 ); if ( * (_QWORD * )result ! = result ) return result; } if ( * ((_QWORD * )v9 + 24 ) && !_bittest((const signed __int32 * )v9 + 32 , 0xAu ) ) return ((__int64 (__fastcall * )(__int64, unsigned __int16 * , bool , _QWORD))NtfsDeleteInternalAttributeStream)( a1, v9, * (_WORD * )(v8 + 164 ) = = 0 , 0i64 ); } } } } return result; } |
3. 我的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | typedef VOID( * __fastcall pNtfsDecrementCleanupCounts)(__int64 a1, __int64 a2, __int64 * a3, int a4, int a5); pNtfsDecrementCleanupCounts NtfsDecrementCleanupCounts = NULL; / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @FunctionName : brief * @Author : Thanatos * @Date : 2023 / 10 / 4 19 : 38 * @Inparam : WCHAR * szPath 路径 * @Outparam : * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / NTSTATUS TestXCBFunction(WCHAR * szPath) { NtfsDecrementCleanupCounts = 0xFFFFF88001261660 ; IO_STATUS_BLOCK ioStatus; HANDLE handle; WCHAR tmppath[MAX_PATH] = { 0 }; wcscpy(tmppath, L "\\??\\" ); wcscat(tmppath, szPath); UNICODE_STRING uDeletePathName; RtlInitUnicodeString(&uDeletePathName, tmppath); OBJECT_ATTRIBUTES objAttributes = { 0 }; InitializeObjectAttributes(&objAttributes, &uDeletePathName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); NTSTATUS ntStatus = ZwCreateFile( &handle, SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, &objAttributes, &ioStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (NT_SUCCESS(ntStatus)) { PFILE_OBJECT FileObject; ntStatus = ObReferenceObjectByHandle(handle, DELETE, * IoFileObjectType, KernelMode, &FileObject, NULL); if (!NT_SUCCESS(ntStatus)) { ZwClose(handle); return ntStatus; } if (MmIsAddressValid(NtfsDecrementCleanupCounts)) { PVOID pSCB = FileObject - >FsContext; PVOID pCCB = FileObject - >FsContext2; NtfsDecrementCleanupCounts( 0 , pSCB, 0 , FileObject - >Flags & 8 , 0 ); } else { ntStatus = STATUS_INVALID_PARAMETER; } ObDereferenceObject(FileObject); ZwClose(handle); } kprintf( "ntStatus %ws %x\n" , szPath, ntStatus); return ntStatus; } |
第一次写。。。不知道怎么去描述
赞赏
他的文章
看原图
赞赏
雪币:
留言: