当前位置: 首页 > ai >正文

从Ntfs!NtfsReadMftRecord函数到Ntfs!NtfsMapStream函数从0x274a到0xc4312800

第一部分:计算文件记录的偏移,然后调用函数NtfsMapStream


VOID
NtfsReadMftRecord (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PMFT_SEGMENT_REFERENCE SegmentReference,
    IN BOOLEAN CheckRecord,
    OUT PBCB *Bcb,
    OUT PFILE_RECORD_SEGMENT_HEADER *FileRecord,
    OUT PLONGLONG MftFileOffset OPTIONAL
    )
{

    try {

        //
        //  Capture the Segment Reference and make sure the Sequence Number is 0.
        //

        FileOffset = NtfsFullSegmentNumber( SegmentReference );

        //
        //  Calculate the file offset in the Mft to the file record segment.
        //

        FileOffset = LlBytesFromFileRecords( Vcb, FileOffset );

        //
        //  Pass back the file offset within the Mft.
        //

        if (ARGUMENT_PRESENT( MftFileOffset )) {

            *MftFileOffset = FileOffset;
        }

        //
        //  Try to read it from the normal Mft.
        //

        try {

            NtfsMapStream( IrpContext,
                           Vcb->MftScb,
                           FileOffset,
                           Vcb->BytesPerFileRecordSegment,
                           Bcb,
                           (PVOID *)FileRecord );

#define NtfsFullSegmentNumber(fr)   ( (*(ULONGLONG UNALIGNED *)(fr)) & 0xFFFFFFFFFFFF )

#define LlBytesFromFileRecords(V,F) (               \
    Int64ShllMod32((F), (CCHAR)(V)->MftShift)       \
)

    [+0x11c] MftShift         : 0xa [Type: unsigned long]

0x274a

00    10 01    11 01    00 10        10 00 0000 0000
9b2800

1: kd> ?274a*400
Evaluate expression: 10299392 = 009d2800


第二部分://下面关注0x009d2800是如何被使用的,18位之前是索引,18位是相对于va的偏移。

1: kd> p
Ntfs!NtfsReadMftRecord+0xb6:
f71da4da e89b71f9ff      call    Ntfs!NtfsMapStream (f717167a)
1: kd> t
Ntfs!NtfsMapStream:
f717167a 55              push    ebp
1: kd> kc
 #
00 Ntfs!NtfsMapStream
01 Ntfs!NtfsReadMftRecord
02 Ntfs!NtfsReadFileRecord
03 Ntfs!NtfsLookupInFileRecord
04 Ntfs!NtfsNonCachedResidentRead
05 Ntfs!NtfsCommonRead
06 Ntfs!NtfsFsdRead
07 nt!IofCallDriver
08 nt!IopPageReadInternal
09 nt!IoAsynchronousPageRead
0a nt!MiPfExecuteReadList
0b nt!MmPrefetchPages
0c nt!CcPfPrefetchSections
0d nt!CcPfBootWorker
0e nt!PspSystemThreadStartup
0f nt!KiThreadStartup

1: kd> dv
     IrpContext = 0x8980e2d8
            Scb = 0x8962ee68
     FileOffset = 0n10299392=0x009d2800        //下面关注0x009d2800
         Length = 0x400
            Bcb = 0xf705f87c
         Buffer = 0xf705f8b0

    //
    //  Call the cache manager to map the data.  This call may raise, but
    //  will never return an error (including CANT_WAIT).
    //

    if (!CcMapData( Scb->FileObject,
                    (PLARGE_INTEGER)&FileOffset,
                    Length,
                    TRUE,
                    Bcb,
                    Buffer )) {


    [+0x030] FileName         : "\$Mft" [Type: _UNICODE_STRING]

第三部分:得到SharedCacheMap结构地址

1: kd> t
nt!CcMapData:
80bf9768 6a30            push    30h
1: kd> kc
 #
00 nt!CcMapData
01 Ntfs!NtfsMapStream
02 Ntfs!NtfsReadMftRecord
03 Ntfs!NtfsReadFileRecord
04 Ntfs!NtfsLookupInFileRecord
05 Ntfs!NtfsNonCachedResidentRead
06 Ntfs!NtfsCommonRead
07 Ntfs!NtfsFsdRead
08 nt!IofCallDriver
09 nt!IopPageReadInternal
0a nt!IoAsynchronousPageRead
0b nt!MiPfExecuteReadList
0c nt!MmPrefetchPages
0d nt!CcPfPrefetchSections
0e nt!CcPfBootWorker
0f nt!PspSystemThreadStartup
10 nt!KiThreadStartup
1: kd> dv
     FileObject = 0x898f2860
     FileOffset = 0xf705f7b0 {10299392}
         Length = 0x400
          Flags = 1
            Bcb = 0xf705f87c
         Buffer = 0xf705f8b0
     SavedState = 0
             ch = 0x80 ''
 ReceivedLength = 0xf705f7b0
         Thread = 0x009d2c00
 SharedCacheMap = 0xffffffff
 BeyondLastByte = {150323855360}
      PageCount = 0x23
        TempBcb = 0x00000030


此例程尝试映射缓存中的指定文件数据。
返回指向缓存中所需数据的指针。
如果呼叫者不想阻止此呼叫,则
Wait应显示为FALSE。
如果Wait被提供为FALSE,并且
目前无法提供所请求的数据
阻塞,则此例程将返回FALSE。然而,如果
数据可以立即在缓存中访问,并且没有阻塞
必需,此例程返回TRUE,并带有指向数据的指针。

请注意,调用此例程并将Wait设置为TRUE时
比使用Wait提供FALSE的调用快得多,因为
在Wait TRUE的情况下,我们只需确保数据已映射
为了返回。
 
修改仅映射的数据是违法的,实际上可能会导致
严重的问题。在所有情况下都不可能检查这一点,

但是,CcSetDirtyPinnedata可能会实现一些断言来检查
这个。如果调用者希望修改它只映射的数据,那么
它必须*首先*调用CcPinMappedData。

在任何情况下,调用者必须随后调用CcUnpinData。
当然,如果CcPinRead或CcPreparePinWrite被称为多个
对于相同的数据,CcUnpinData必须被称为相同的数字
时代。
 
返回的Buffer指针有效,直到数据被取消固定,在
在这一点上,进一步使用指针是无效的。此缓冲区指针
如果调用CcPinMappedData,则将保持有效。
 
请注意,在某些情况下(如Wait显示为FALSE或更多)
但是,此例程实际上可能会固定数据
来电者不必担心,事实上也不正确
关于这个。


    if (FlagOn(Flags, MAP_WAIT)) {

        CcMapDataWait += 1;

        //
        //  Initialize the indirect pointer to our miss counter.
        //

        CcMissCounter = &CcMapDataWaitMiss;

    } else {

   //
    //  Get pointer to SharedCacheMap.
    //

    SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;0x89811620

1: kd> dx -r1 ((ntkrnlmp!_FILE_OBJECT *)0x898f2860)
((ntkrnlmp!_FILE_OBJECT *)0x898f2860)                 : 0x898f2860 [Type: _FILE_OBJECT *]
    [+0x000] Type             : 5 [Type: short]
    [+0x002] Size             : 112 [Type: short]
    [+0x004] DeviceObject     : 0x89811788 : Device for "\Driver\Ftdisk" [Type: _DEVICE_OBJECT *]
    [+0x008] Vpb              : 0x89909178 [Type: _VPB *]
    [+0x00c] FsContext        : 0x8962ee68 [Type: void *]
    [+0x010] FsContext2       : 0x0 [Type: void *]
    [+0x014] SectionObjectPointer : 0x8990d7c4 [Type: _SECTION_OBJECT_POINTERS *]
1: kd> dx -r1 ((ntkrnlmp!_SECTION_OBJECT_POINTERS *)0x8990d7c4)
((ntkrnlmp!_SECTION_OBJECT_POINTERS *)0x8990d7c4)                 : 0x8990d7c4 [Type: _SECTION_OBJECT_POINTERS *]
    [+0x000] DataSectionObject : 0x8959a210 [Type: void *]
    [+0x004] SharedCacheMap   : 0x89811620 [Type: void *]
    [+0x008] ImageSectionObject : 0x0 [Type: void *]

0x89811620


1: kd> dt SHARED_CACHE_MAP 0x89811620
nt!SHARED_CACHE_MAP
   +0x000 NodeTypeCode     : 0n767
   +0x002 NodeByteSize     : 0n304
   +0x004 OpenCount        : 1
   +0x008 FileSize         : _LARGE_INTEGER 0xa2bc00
   +0x010 BcbList          : _LIST_ENTRY [ 0x8980e7a8 - 0x8980e700 ]
   +0x018 SectionSize      : _LARGE_INTEGER 0xb00000
   +0x020 ValidDataLength  : _LARGE_INTEGER 0x7fffffff`ffffffff
   +0x028 ValidDataGoal    : _LARGE_INTEGER 0x7fffffff`ffffffff
   +0x030 InitialVacbs     : [4] (null)
   +0x040 Vacbs            : 0x8980e650  -> 0x899885b8 _VACB
   +0x044 FileObject       : 0x898f2860 _FILE_OBJECT
   +0x048 ActiveVacb       : (null)
   +0x04c NeedToZero       : (null)
   +0x050 ActivePage       : 0
   +0x054 NeedToZeroPage   : 0
   +0x058 ActiveVacbSpinLock : 0
   +0x05c VacbActiveCount  : 0
   +0x060 DirtyPages       : 0x6e
   +0x064 SharedCacheMapLinks : _LIST_ENTRY [ 0x8980e924 - 0x894b6814 ]
   +0x06c Flags            : 0x605
   +0x070 Status           : 0n0
   +0x074 Mbcb             : (null)
   +0x078 Section          : 0xe129af98 Void
   +0x07c CreateEvent      : (null)


    if ((TempVacb = GetVacb( SharedCacheMap, FileOffset )) == NULL) {

        TempVacb = CcGetVacbMiss( SharedCacheMap, FileOffset, &OldIrql );

    } else {

//
//  Define a few macros for manipulating the Vacb array.
//

#define GetVacb(SCM,OFF) (                                                                \
    ((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) ?                            \
    CcGetVacbLargeOffset((SCM),(OFF).QuadPart) :                                          \
    (SCM)->Vacbs[(OFF).LowPart >> VACB_OFFSET_SHIFT]                                      \
)


0xb00000
#define VACB_SIZE_OF_FIRST_LEVEL         (1 << (VACB_OFFSET_SHIFT + VACB_LEVEL_SHIFT))

#define VACB_OFFSET_SHIFT                (18)
#define VACB_LEVEL_SHIFT                  (7)


0010 0000 0000 0000 0000 0000 0000
2000000


1: kd> dx -id 0,0,899a2278 -r1 ((ntkrnlmp!_VACB * *)0x8980e650)
((ntkrnlmp!_VACB * *)0x8980e650)                 : 0x8980e650 [Type: _VACB * *]
    0x899885b8 [Type: _VACB *]
1: kd> dx -id 0,0,899a2278 -r1 ((ntkrnlmp!_VACB *)0x899885b8)
((ntkrnlmp!_VACB *)0x899885b8)                 : 0x899885b8 [Type: _VACB *]
    [+0x000] BaseAddress      : 0xc46c0000 [Type: void *]
    [+0x004] SharedCacheMap   : 0x89811620 [Type: _SHARED_CACHE_MAP *]
    [+0x008] Overlay          [Type: __unnamed]
    [+0x010] LruList          [Type: _LIST_ENTRY]


第四部分:得到虚拟地址,由两部分组成,一个是基址0xc4300000一个是偏移地址VacbOffset12800

1: kd> p
nt!CcMapData+0x84:
80bf97ec e88f10e2ff      call    nt!CcGetVirtualAddress (80a1a880)
1: kd> t
nt!CcGetVirtualAddress:
80a1a880 55              push    ebp
1: kd> kc
 #
00 nt!CcGetVirtualAddress
01 nt!CcMapData
02 Ntfs!NtfsMapStream
03 Ntfs!NtfsReadMftRecord
04 Ntfs!NtfsReadFileRecord
05 Ntfs!NtfsLookupInFileRecord
06 Ntfs!NtfsNonCachedResidentRead
07 Ntfs!NtfsCommonRead
08 Ntfs!NtfsFsdRead
09 nt!IofCallDriver
0a nt!IopPageReadInternal
0b nt!IoAsynchronousPageRead
0c nt!MiPfExecuteReadList
0d nt!MmPrefetchPages
0e nt!CcPfPrefetchSections
0f nt!CcPfBootWorker
10 nt!PspSystemThreadStartup
11 nt!KiThreadStartup

1: kd> dv
 SharedCacheMap = 0x89811620
     FileOffset = {10299392}
           Vacb = 0xf705f754
 ReceivedLength = 0xf705f748
     VacbOffset = 0x80a1a880
        OldIrql = 0x00 ''


1: kd> dx -r1 ((ntkrnlmp!_SHARED_CACHE_MAP *)0x89811620)
((ntkrnlmp!_SHARED_CACHE_MAP *)0x89811620)                 : 0x89811620 [Type: _SHARED_CACHE_MAP *]
    [+0x000] NodeTypeCode     : 767 [Type: short]
    [+0x002] NodeByteSize     : 304 [Type: short]
    [+0x004] OpenCount        : 0x1 [Type: unsigned long]
    [+0x008] FileSize         : {10664960} [Type: _LARGE_INTEGER]
    [+0x010] BcbList          [Type: _LIST_ENTRY]
    [+0x018] SectionSize      : {11534336} [Type: _LARGE_INTEGER]
    [+0x020] ValidDataLength  : {9223372036854775807} [Type: _LARGE_INTEGER]
    [+0x028] ValidDataGoal    : {9223372036854775807} [Type: _LARGE_INTEGER]
    [+0x030] InitialVacbs     [Type: _VACB * [4]]
    [+0x040] Vacbs            : 0x8980e650 [Type: _VACB * *]

1: kd> dd 0x8980e650
8980e650  899885b8 89988000 89988570 89988630
8980e660  899884b0 00000000 89988618 899885d0
8980e670  89988678 89988558 89988510 89988450
8980e680  89988228 899883a8 00000000 89988258
8980e690  00000000 89988600 899885a0 00000000
8980e6a0  89988060 899886a8 89988468 00000000
8980e6b0  89988078 00000000 00000000 89988390
8980e6c0  00000000 00000000 00000000 00000000
1: kd> dd 899885b8
899885b8  c46c0000 89811620 00000000 00000000
899885c8  89988070 899880a0 c4580000 89811620
899885d8  001c0000 00000000 899884c0 899885f8
899885e8  c4280000 89465008 00000000 00000000
899885f8  899885e0 89988688 c4340000 89811620
89988608  00440000 00000000 89988130 899883a0
89988618  c45c0000 89811620 00180000 00000000
89988628  89988520 899883d0 c4680000 89811620
1: kd> dt _VACB 899885b8
nt!_VACB
   +0x000 BaseAddress      : 0xc46c0000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x89988070 - 0x899880a0 ]

第五部分:GetVacb宏定义的作用是得到_VACB结构的地址899880a8

#define GetVacb(SCM,OFF) (                                                                \
    ((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) ?                            \
    CcGetVacbLargeOffset((SCM),(OFF).QuadPart) :                                          \
    (SCM)->Vacbs[(OFF).LowPart >> VACB_OFFSET_SHIFT]                                      \    esi=00000027
)

#define VACB_OFFSET_SHIFT                (18)

009d2800

1001 1101 0010 1000 0000 0000

                      01 0010 1000 0000 0000

1001 11
10    01 11
0x27

    if ((TempVacb = GetVacb( SharedCacheMap, FileOffset )) == NULL) {

1: kd> p
nt!CcGetVirtualAddress+0xaa:
80a1a92a 8b4740          mov     eax,dword ptr [edi+40h]
1: kd> p
nt!CcGetVirtualAddress+0xad:
80a1a92d c1ee12          shr     esi,12h
1: kd> r
eax=8980e650 ebx=898116f0 ecx=80b16100 edx=00000000 esi=009d2800 edi=89811620

1: kd> p
nt!CcGetVirtualAddress+0xb0:
80a1a930 8b34b0          mov     esi,dword ptr [eax+esi*4]
1: kd> r
eax=8980e650 ebx=898116f0 ecx=80b16100 edx=00000000 esi=00000027 edi=89811620
eip=80a1a930 esp=f705f6f8 ebp=f705f70c iopl=0         nv up ei pl nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000206
nt!CcGetVirtualAddress+0xb0:
80a1a930 8b34b0          mov     esi,dword ptr [eax+esi*4] ds:0023:8980e6ec=899880a8
1: kd> p
nt!CcGetVirtualAddress+0xb3:
80a1a933 85f6            test    esi,esi
1: kd> r
eax=8980e650 ebx=898116f0 ecx=80b16100 edx=00000000 esi=899880a8 edi=89811620

1: kd> dd 0x8980e650+27*4
8980e6ec  899880a8 899882a0 00000000 00000000
8980e6fc  00000000 89811630 8944e018 894a3628

1: kd> dt _VACB 899880a8
nt!_VACB
   +0x000 BaseAddress      : 0xc4300000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x80b1cb60 - 0x899883b8 ]


1: kd> dt _VACB 0x899883b8-10
nt!_VACB
   +0x000 BaseAddress      : 0xc3500000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x899880b8 - 0x89988010 ]

        if (TempVacb->Overlay.ActiveCount == 0) {
            SharedCacheMap->VacbActiveCount += 1;
        }


TempVacb = GetVacb( SharedCacheMap, FileOffset ))    =899880a8


1: kd> dt _VACB 899880a8
nt!_VACB
   +0x000 BaseAddress      : 0xc4300000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x80b1cb60 - 0x899883b8 ]

1: kd> dx -id 0,0,899a2278 -r1 (*((ntkrnlmp!__unnamed *)0x899880b0))
(*((ntkrnlmp!__unnamed *)0x899880b0))                 [Type: __unnamed]
    [+0x000] FileOffset       : {10223617} [Type: _LARGE_INTEGER]
    [+0x000] ActiveCount      : 0x1 [Type: unsigned short]

#define CcMoveVacbToReuseTail(V)        RemoveEntryList( &(V)->LruList );                 \
                                        InsertTailList( &CcVacbLru, &(V)->LruList );


1: kd> x nt!CcVacbLru
80b1cb60          nt!CcVacbLru = struct _LIST_ENTRY [ 0x89988028 - 0x899880b8 ]
1: kd> dx -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x80b1cb60))
(*((ntkrnlmp!_LIST_ENTRY *)0x80b1cb60))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x89988028 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x899880b8 [Type: _LIST_ENTRY *]

1: kd> p
nt!CcGetVirtualAddress+0xec:
80a1a96c 894804          mov     dword ptr [eax+4],ecx
1: kd> r
eax=899880b8 ebx=898116f0 ecx=899883b8


第六部分:

    CcMoveVacbToReuseTail( TempVacb );

1: kd> x nt!CcVacbLru
80b1cb60          nt!CcVacbLru = struct _LIST_ENTRY [ 0x89988028 - 0x899883b8 ]
1: kd> dx -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x80b1cb60))
(*((ntkrnlmp!_LIST_ENTRY *)0x80b1cb60))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x89988028 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x899883b8 [Type: _LIST_ENTRY *]
1: kd> dx -r1 ((ntkrnlmp!_LIST_ENTRY *)0x899883b8)
((ntkrnlmp!_LIST_ENTRY *)0x899883b8)                 : 0x899883b8 [Type: _LIST_ENTRY *]
    [+0x000] Flink            : 0x899880b8 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x89988010 [Type: _LIST_ENTRY *]


1: kd> dt _VACB 899880a8
nt!_VACB
   +0x000 BaseAddress      : 0xc4300000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x80b1cb60 - 0x899883b8 ]

1: kd> dv
 SharedCacheMap = 0x898116f0
     FileOffset = {10299392}
           Vacb = 0xf705f754
 ReceivedLength = 0xf705f748
     VacbOffset = 0x12800
        OldIrql = 0x00 ''

    ULONG VacbOffset = FileOffset.LowPart & (VACB_MAPPING_GRANULARITY - 1);

#define VACB_MAPPING_GRANULARITY         (0x40000)

3FFFF
0x9d2800

1001 1101 0010 1000 0000 0000
             01 0010 1000 0000 0000
12800    正确                VacbOffset = 0x12800

    //
    //  Now form all outputs.
    //

    *Vacb = TempVacb;


1: kd> dd 0xf705f754
f705f754  899880a8


    return (PVOID)((PCHAR)TempVacb->BaseAddress + VacbOffset);
}
0xc4300000+12800=0xc4312800

1: kd> dt _VACB 899880a8
nt!_VACB
   +0x000 BaseAddress      : 0xc4300000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x80b1cb60 - 0x899883b8 ]


第七部分:Loop to touch each page,把对应的页面加载到内存

1: kd> p
nt!CcGetVirtualAddress+0x198:
80a1aa18 c21400          ret     14h
1: kd> r
eax=c4312800


1: kd> dv
     FileObject = 0x898f2860
     FileOffset = 0xf705f7b0 {10299392}
         Length = 0x400
          Flags = 1
            Bcb = 0xf705f87c
         Buffer = 0xf705f8b0

1: kd> dx -r1 ((ntkrnlmp!void * *)0xf705f8b0)
((ntkrnlmp!void * *)0xf705f8b0)                 : 0xf705f8b0 [Type: void * *]
    0xc4312800 [Type: void *]


 BeyondLastByte = {35}

1: kd> dx -r1 -nv (*((ntkrnlmp!_LARGE_INTEGER *)0xf705f734))
(*((ntkrnlmp!_LARGE_INTEGER *)0xf705f734))                 : {35} [Type: _LARGE_INTEGER]
    [+0x000] LowPart          : 0x23 [Type: unsigned long]
    [+0x004] HighPart         : 0 [Type: long]
    [+0x000] u                [Type: __unnamed]
    [+0x000] QuadPart         : 35 [Type: __int64]

            //
            //  Loop to touch each page
            //

            BeyondLastByte.LowPart = 0;
dv
 BeyondLastByte = {0}


            while (PageCount != 0) {

                MmSetPageFaultReadAhead( Thread, PageCount - 1 );

                ch = *((volatile UCHAR *)(*Buffer) + BeyondLastByte.LowPart);

                BeyondLastByte.LowPart += PAGE_SIZE;
                PageCount -= 1;
            }

1: kd> p
nt!CcMapData+0x11c:
80bf9884 4b              dec     ebx
1: kd> r
eax=0000000f ebx=00000001

1: kd> p
nt!CcMapData+0x132:
80bf989a 8b09            mov     ecx,dword ptr [ecx]
1: kd> r
eax=0000000f ebx=00000000 ecx=f705f8b0 edx=00000000 esi=8989e020 edi=f705f7b0
eip=80bf989a esp=f705f728 ebp=f705f774 iopl=0         nv up ei ng nz ac po cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000293
nt!CcMapData+0x132:
80bf989a 8b09            mov     ecx,dword ptr [ecx]  ds:0023:f705f8b0=c4312800
1: kd> p
nt!CcMapData+0x134:
80bf989c 8b55c0          mov     edx,dword ptr [ebp-40h]
1: kd> r
eax=0000000f ebx=00000000 ecx=c4312800

1: kd> db c4312800
c4312800  46 49 4c 45 30 00 03 00-8b 63 78 07 00 00 00 00  FILE0....cx.....


dv
             ch = 0x46 'F'

    volatile UCHAR ch;

1: kd> dt _VACB 0x899880a8
nt!_VACB
   +0x000 BaseAddress      : 0xc4300000 Void
   +0x004 SharedCacheMap   : 0x89811620 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x80b1cb60 - 0x899883b8 ]
1: kd> dt _VACB 0x899880a8+18
nt!_VACB
   +0x000 BaseAddress      : 0xc3440000 Void
   +0x004 SharedCacheMap   : 0x89455a68 _SHARED_CACHE_MAP
   +0x008 Overlay          : __unnamed
   +0x010 LruList          : _LIST_ENTRY [ 0x89988298 - 0x89988160 ]


1: kd> p
nt!CcMapData+0x15c:
80bf98c4 8b45e0          mov     eax,dword ptr [ebp-20h]
1: kd> p
nt!CcMapData+0x15f:
80bf98c7 40              inc     eax
1: kd> p
nt!CcMapData+0x160:
80bf98c8 8b4d18          mov     ecx,dword ptr [ebp+18h]
1: kd> r
eax=899880a9 ebx=00000000 ecx=f705f764 edx=00000000 esi=8989e020 edi=f705f7b0


    *(PCHAR *)&TempBcb += 1;
    *Bcb = TempBcb;        899880a9


1: kd> dv
     FileObject = 0x898f2860
     FileOffset = 0xf705f7b0 {10299392}

            Bcb = 0xf705f87c
1: kd> dx -r1 ((ntkrnlmp!void * *)0xf705f87c)
((ntkrnlmp!void * *)0xf705f87c)                 : 0xf705f87c [Type: void * *]
    0x899880a9 [Type: void *]


    //
    //  Call the cache manager to map the data.  This call may raise, but
    //  will never return an error (including CANT_WAIT).
    //

    if (!CcMapData( Scb->FileObject,
                    (PLARGE_INTEGER)&FileOffset,
                    Length,
                    TRUE,
                    Bcb,
                    Buffer )) {

1: kd> p
Ntfs!NtfsMapStream+0xaf:
f7171729 84c0            test    al,al
1: kd> dv
     IrpContext = 0x8980e2d8
            Scb = 0x8962ee68
     FileOffset = 0n10299392
         Length = 0x400
            Bcb = 0xf705f87c
         Buffer = 0xf705f8b0
1: kd> dx -id 0,0,899a2278 -r1 ((Ntfs!void * *)0xf705f87c)
((Ntfs!void * *)0xf705f87c)                 : 0xf705f87c [Type: void * *]
    0x899880a9 [Type: void *]
1: kd> dx -id 0,0,899a2278 -r1 ((Ntfs!void * *)0xf705f8b0)
((Ntfs!void * *)0xf705f8b0)                 : 0xf705f8b0 [Type: void * *]
    0xc4312800 [Type: void *]


第九部分:最终结果:FileRecord    0xc4312800


1: kd> dv
      IrpContext = 0x8980e2d8
             Vcb = 0x898f1100
SegmentReference = 0xe160dcd8
     CheckRecord = 0x01 ''
             Bcb = 0xf705f87c
      FileRecord = 0xf705f8b0
1: kd> dx -id 0,0,899a2278 -r1 ((Ntfs!_FILE_RECORD_SEGMENT_HEADER * *)0xf705f8b0)
((Ntfs!_FILE_RECORD_SEGMENT_HEADER * *)0xf705f8b0)                 : 0xf705f8b0 [Type: _FILE_RECORD_SEGMENT_HEADER * *]
    0xc4312800 [Type: _FILE_RECORD_SEGMENT_HEADER *]
1: kd> dx -id 0,0,899a2278 -r1 ((Ntfs!_FILE_RECORD_SEGMENT_HEADER *)0xc4312800)
((Ntfs!_FILE_RECORD_SEGMENT_HEADER *)0xc4312800)                 : 0xc4312800 [Type: _FILE_RECORD_SEGMENT_HEADER *]
    [+0x000] MultiSectorHeader [Type: _MULTI_SECTOR_HEADER]
    [+0x008] Lsn              : {125330315} [Type: _LARGE_INTEGER]
    [+0x010] SequenceNumber   : 0x1 [Type: unsigned short]
    [+0x012] ReferenceCount   : 0x1 [Type: unsigned short]
    [+0x014] FirstAttributeOffset : 0x38 [Type: unsigned short]
    [+0x016] Flags            : 0x1 [Type: unsigned short]
    [+0x018] FirstFreeByte    : 0x180 [Type: unsigned long]
    [+0x01c] BytesAvailable   : 0x400 [Type: unsigned long]
    [+0x020] BaseFileRecordSegment [Type: _MFT_SEGMENT_REFERENCE]
    [+0x028] NextAttributeInstance : 0x5 [Type: unsigned short]
    [+0x02a] SegmentNumberHighPart : 0x0 [Type: unsigned short]
    [+0x02c] SegmentNumberLowPart : 0x274a [Type: unsigned long]
    [+0x030] UpdateArrayForCreateOnly [Type: unsigned short [1]]

#define NtfsSegmentNumber(fr)       NtfsUnsafeSegmentNumber( fr )
#define NtfsFullSegmentNumber(fr)   ( (*(ULONGLONG UNALIGNED *)(fr)) & 0xFFFFFFFFFFFF )
#define NtfsUnsafeSegmentNumber(fr) ((fr)->SegmentNumberLowPart)

1: kd> ?0x274a*400
Evaluate expression: 10299392 = 009d2800

http://www.xdnf.cn/news/7553.html

相关文章:

  • SAR ADC 比较器寄生电容对性能的影响
  • 镜像管理(2)Dockerfile总结
  • 技术问答:PHP、JAVA和Go的垃圾回收机制有哪些区别
  • HarmonyOS5云服务技术分享--云函数创建配置指南
  • 软考软件评测师——黑盒测试测试方法
  • python 判断远程windows系统中某进程号是否还在
  • 电商运营数据分析指南之流量指标
  • lambda架构和kappa架构区别
  • 【Unity网络编程知识】协议生成工具Protobuf
  • 05 接口自动化-框架封装思想建立之httprunner框架(中)
  • Qt 控件发展历程 + 目标(1)
  • <uniapp><vuex><状态管理>在uniapp中,如何使用vuex实现数据共享与传递?
  • 基于“岗课赛证”融通的农业物联网专业教学方案
  • Ⅱ 链表 episode3
  • 自回归图像编辑 EditAR: Unified Conditional Generation with Autoregressive Models
  • 力扣第5题:最长回文子串(动态规划)
  • 【全解析】EN18031标准下的NMM网络监控机制
  • css使用clip-path属性切割显示可见内容
  • 【MySQL】第七弹——复习总结 视图
  • SSRF(服务器端请求伪造)基本原理靶场实现
  • CVE-2017-4971源码分析与漏洞复现
  • 谈谈对《加密算法》的理解
  • 零售智能执行大模型架构设计:从空间建模到上下文推理,再到智能Agent
  • DB31/T 1552-2025《居民电子健康档案应用系统等级评估指南》:上海地方标准全面解析
  • 什么是VR展示?VR展示的用途
  • 数据库4——存储过程及游标
  • leetcode 合并区间 java
  • ajax post请求 解决自动再get请求一次
  • 黑马Java基础笔记-13常用查找算法
  • 山东大学软件学院项目实训-基于大模型的模拟面试系统-Vditor编辑器上传图片