从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