nt!CcFlushCache函数分析之nt!CcFindBcb
nt!CcFindBcb函数分析
第一部分:
1: kd> p
nt!CcAcquireByteRangeForWrite+0x377:
80a13c49 e866e4ffff call nt!CcFindBcb (80a120b4)
1: kd> t
nt!CcFindBcb:
80a120b4 55 push ebp
1: kd> kc
#
00 nt!CcFindBcb
01 nt!CcAcquireByteRangeForWrite
02 nt!CcFlushCache
03 Ntfs!LfsFlushLfcb
04 Ntfs!LfsFlushToLsnPriv
05 Ntfs!LfsWriteLfsRestart
06 Ntfs!LfsWriteRestartArea
07 Ntfs!NtfsCheckpointVolume
08 Ntfs!NtfsCheckpointAllVolumes
09 nt!ExpWorkerThread
0a nt!PspSystemThreadStartup
0b nt!KiThreadStartup
1: kd> dv
SharedCacheMap = 0x89469530
FileOffset = 0xf78d2768 {7884800}
BeyondLastByte = 0xf78d26c8 {7888896}
Bcb = 0xf78d26fc
Found = 0x00 ''
1: kd> ?0n7884800
Evaluate expression: 7884800 = 00785000
第二部分:
//
// Get address of Bcb listhead that is *after* the Bcb we are looking for,
// for backwards scan. It is important that we fail in the forward
// direction so that we are looking in the right segment of the Bcb list.
//
BcbList = GetBcbListHead( SharedCacheMap, FileOffset->QuadPart + SIZE_PER_BCB_LIST, TRUE );
[+0x018] SectionSize : {67108864} [Type: _LARGE_INTEGER]
1: kd> ?0n67108864
Evaluate expression: 67108864 = 04000000
#define BEGIN_BCB_LIST_ARRAY (0x200000)
#define SIZE_PER_BCB_LIST (VACB_MAPPING_GRANULARITY * 2)
#define BCB_LIST_SHIFT (VACB_OFFSET_SHIFT + 1)
#define VACB_OFFSET_SHIFT (18)
#define VACB_LEVEL_SHIFT (7)
#define VACB_SIZE_OF_FIRST_LEVEL (1 << (VACB_OFFSET_SHIFT + VACB_LEVEL_SHIFT))
#define GetBcbListHead(SCM,OFF,FAILSUCC) ( \
(((SCM)->SectionSize.QuadPart > BEGIN_BCB_LIST_ARRAY) && \
FlagOn((SCM)->Flags, MODIFIED_WRITE_DISABLED)) ? \
(((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) ? \
CcGetBcbListHeadLargeOffset((SCM),(OFF),(FAILSUCC)) : \
(((OFF) >= (SCM)->SectionSize.QuadPart) ? &(SCM)->BcbList : \
((PLIST_ENTRY)((SCM)->Vacbs) + (((SCM)->SectionSize.QuadPart + (OFF)) >> BCB_LIST_SHIFT)))) : \
&(SCM)->BcbList \
)
10 0000 0000 0000 0000 0000 0000
2000000
CcGetBcbListHeadLargeOffset((SCM),(OFF),(FAILSUCC))
1: kd> p
nt!CcFindBcb+0x1d:
80a120d1 3d00002000 cmp eax,200000h
1: kd> p
nt!CcFindBcb+0x22:
80a120d6 7665 jbe nt!CcFindBcb+0x89 (80a1213d)
1: kd> r
eax=04000000
1: kd> p
nt!CcFindBcb+0x30:
80a120e4 3d00000002 cmp eax,2000000h
1: kd> p
nt!CcFindBcb+0x35:
80a120e9 7619 jbe nt!CcFindBcb+0x50 (80a12104)
1: kd> r
eax=04000000
第三部分:nt!CcGetBcbListHeadLargeOffset
1: kd> kc
#
00 nt!CcGetBcbListHeadLargeOffset
01 nt!CcFindBcb
02 nt!CcAcquireByteRangeForWrite
03 nt!CcFlushCache
04 Ntfs!LfsFlushLfcb
05 Ntfs!LfsFlushToLsnPriv
06 Ntfs!LfsWriteLfsRestart
07 Ntfs!LfsWriteRestartArea
08 Ntfs!NtfsCheckpointVolume
09 Ntfs!NtfsCheckpointAllVolumes
0a nt!ExpWorkerThread
0b nt!PspSystemThreadStartup
0c nt!KiThreadStartup
1: kd> dv
SharedCacheMap = 0x89469530
FileOffset = 0n8409088
FailToSuccessor = 0x01 ''
SavedLevels = 0x80a189aa
SavedVacbArrays = struct _VACB **[7]
Shift = 8
SavedIndexes = unsigned long [7]
Level = 0
1: kd> ?0n8409088
Evaluate expression: 8409088 = 00805000
#define SIZE_PER_BCB_LIST (VACB_MAPPING_GRANULARITY * 2)
#define VACB_MAPPING_GRANULARITY (0x40000)
80000+00785000=00805000
1: kd> dx -r1 ((ntkrnlmp!_VACB * *)0x89469320)
((ntkrnlmp!_VACB * *)0x89469320) : 0x89469320 [Type: _VACB * *]
0x894d1008 [Type: _VACB *]
1: kd> dx -r1 ((ntkrnlmp!_VACB *)0x894d1008)
((ntkrnlmp!_VACB *)0x894d1008) : 0x894d1008 [Type: _VACB *]
[+0x000] BaseAddress : 0x89988018 [Type: void *]
[+0x004] SharedCacheMap : 0x0 [Type: _SHARED_CACHE_MAP *]
[+0x008] Overlay [Type: __unnamed]
[+0x010] LruList [Type: _LIST_ENTRY]
第四部分:
Shift = VACB_OFFSET_SHIFT + VACB_LEVEL_SHIFT; 25
#define VACB_OFFSET_SHIFT (18)
#define VACB_LEVEL_SHIFT (7)
do {
Level += 1;
Shift += VACB_LEVEL_SHIFT;
} while (SharedCacheMap->SectionSize.QuadPart > ((LONGLONG)1 << Shift));
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x46:
80a189f0 8345fc07 add dword ptr [ebp-4],7
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x4a:
80a189f4 8b4dfc mov ecx,dword ptr [ebp-4]
1: kd> r
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=89469530 edi=89469320
eip=80a189f4 esp=f78d2610 ebp=f78d2660 iopl=0 nv up ei pl nz ac po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000212
nt!CcGetBcbListHeadLargeOffset+0x4a:
80a189f4 8b4dfc mov ecx,dword ptr [ebp-4] ss:0010:f78d265c=00000020
1: kd> dd f78d2660-4
f78d265c 00000020
dv
Shift = 0x20
Level = 1
if (FileOffset >= ((LONGLONG)1 << Shift)) {
return &SharedCacheMap->BcbList;
}
//
// Now descend the tree to the bottom level to get the caller's Bcb ListHead.
//
Shift -= VACB_LEVEL_SHIFT; 25 0x2000000
do {
//
// Calculate the index into the Vacb block for this level.
//
Index = (ULONG)(FileOffset >> Shift); =0
ASSERT(Index <= VACB_LAST_INDEX_FOR_LEVEL);
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x9d:
80a18a47 83fe7f cmp esi,7Fh
1: kd> r
eax=00000000 ebx=00000000 ecx=00000019 edx=00000000 esi=00000000 edi=89469320
第五部分:
//
// Get block address for next level.
//
NextVacbArray = (PVACB *)VacbArray[Index]; 894d1008
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0xb8:
80a18a62 8b1cb7 mov ebx,dword ptr [edi+esi*4]
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0xbb:
80a18a65 33c9 xor ecx,ecx
1: kd> r
eax=00000000 ebx=894d1008 ecx=00000019 edx=00000000 esi=00000000 edi=89469320
1: kd> dd 89469320
89469320 894d1008 00000000 00000000 00000000
89469330 00000000 00000000 00000000 00000000
89469340 00000000 00000000 00000000 00000000
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x13c:
80a18ae6 e825b10d00 call nt!_allshl (80af3c10)
1: kd> r
eax=00000001 ebx=894d1008 ecx=00000019 edx=00000000 esi=00000000 edi=894d1008
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x141:
80a18aeb 83e801 sub eax,1
1: kd> r
eax=02000000
1: kd> r
eax=01ffffff ebx=894d1008 ecx=00000019 edx=00000000 esi=00000000 edi=894d1008
eip=80a18af1 esp=f78d2610 ebp=f78d2660 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
nt!CcGetBcbListHeadLargeOffset+0x147:
80a18af1 21450c and dword ptr [ebp+0Ch],eax ss:0010:f78d266c=00805000
1: kd> dd f78d2660+c
f78d266c 00805000
1ff ffff 0080 5000
1: kd> dv
SharedCacheMap = 0x89469530
FileOffset = 0n8409088
1: kd> dv
SharedCacheMap = 0x89469530
FileOffset = 0n8409088
FailToSuccessor = 0x01 ''
SavedLevels = 1
SavedVacbArrays = struct _VACB **[7]
Shift = 0x12
Index = (ULONG)(FileOffset >> Shift);
return (PLIST_ENTRY)((PCHAR)&VacbArray[Index & ~1] + VACB_LEVEL_BLOCK_SIZE);
}
80 5000
1000 0000 1001 0000 0000 0000
1000 0000 1001 0000 0000 0000
10 00 00
0x20
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x161:
80a18b0b 8b4dfc mov ecx,dword ptr [ebp-4]
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x164:
80a18b0e e81db10d00 call nt!_allshr (80af3c30)
1: kd> r
eax=00805000 ebx=894d1008 ecx=00000012 edx=00000000 esi=00000000 edi=894d1008
eip=80a18b0e esp=f78d2610 ebp=f78d2660 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
nt!CcGetBcbListHeadLargeOffset+0x164:
80a18b0e e81db10d00 call nt!_allshr (80af3c30)
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x169:
80a18b13 83e0fe and eax,0FFFFFFFEh
1: kd> r
eax=00000020
#define VACB_LEVEL_BLOCK_SIZE ((1 << VACB_LEVEL_SHIFT) * sizeof(PVOID))
#define VACB_LEVEL_SHIFT (7)
1000 0000 00
10 00 00 00 00
200
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x16c:
80a18b16 8d848300020000 lea eax,[ebx+eax*4+200h]
1: kd> r
eax=00000020 ebx=894d1008
1: kd> r
eax=894d1288
1: kd> dd 894d1008+80+200
894d1288 898f1298 894d1290 894d1288 894d1298
894d1298 894d1290 894d12a0 894d1298 894d12a8
第六部分:
1: kd> p
nt!CcFindBcb+0x4e:
80a12102 eb3c jmp nt!CcFindBcb+0x8c (80a12140)
1: kd> r
eax=894d1288
1: kd> dt _bcb 0x898f1298-10
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n765
+0x002 Dirty : 0x1 ''
+0x003 Reserved : 0 ''
+0x004 ByteLength : 0x1000
+0x008 FileOffset : _LARGE_INTEGER 0x787000
+0x010 BcbLinks : _LIST_ENTRY [ 0x8962bcf8 - 0x894d1288 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x788000
+0x020 OldestLsn : _LARGE_INTEGER 0x0
+0x028 NewestLsn : _LARGE_INTEGER 0x0
+0x030 Vacb : 0x89988498 _VACB
+0x034 PinCount : 1
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x89469530 _SHARED_CACHE_MAP
+0x074 BaseAddress : 0xc2c47000 Void
1: kd> dt LIST_ENTRY 894d1288
ntdll!LIST_ENTRY
[ 0x898f1298 - 0x894d1290 ]
+0x000 Flink : 0x898f1298 _LIST_ENTRY [ 0x8962bcf8 - 0x894d1288 ]
+0x004 Blink : 0x894d1290 _LIST_ENTRY [ 0x894d1288 - 0x894d1298 ]
1: kd> p
nt!CcFindBcb+0x91:
80a12145 837e0400 cmp dword ptr [esi+4],0
1: kd> r
eax=898f1288 ebx=89469530 ecx=00000012 edx=00000000 esi=f78d2768 edi=89469530
1: kd> ?0n7884800
Evaluate expression: 7884800 = 00785000
1: kd> dt _bcb 0x898f1298-10
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n765
+0x002 Dirty : 0x1 ''
+0x003 Reserved : 0 ''
+0x004 ByteLength : 0x1000
+0x008 FileOffset : _LARGE_INTEGER 0x787000
+0x010 BcbLinks : _LIST_ENTRY [ 0x8962bcf8 - 0x894d1288 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x788000
+0x020 OldestLsn : _LARGE_INTEGER 0x0
+0x028 NewestLsn : _LARGE_INTEGER 0x0
+0x030 Vacb : 0x89988498 _VACB
+0x034 PinCount : 1
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x89469530 _SHARED_CACHE_MAP
+0x074 BaseAddress : 0xc2c47000 Void
1: kd> dt _bcb 0x8962bcf8-10
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n765
+0x002 Dirty : 0x1 ''
+0x003 Reserved : 0 ''
+0x004 ByteLength : 0x1000
+0x008 FileOffset : _LARGE_INTEGER 0x786000
+0x010 BcbLinks : _LIST_ENTRY [ 0x894c6668 - 0x898f1298 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x787000
+0x020 OldestLsn : _LARGE_INTEGER 0x0
+0x028 NewestLsn : _LARGE_INTEGER 0x0
+0x030 Vacb : (null)
+0x034 PinCount : 0
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x89469530 _SHARED_CACHE_MAP
+0x074 BaseAddress : (null)
1: kd> dt _bcb 0x894c6668-10
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n765
+0x002 Dirty : 0x1 ''
+0x003 Reserved : 0 ''
+0x004 ByteLength : 0x1000
+0x008 FileOffset : _LARGE_INTEGER 0x785000
+0x010 BcbLinks : _LIST_ENTRY [ 0x894d1280 - 0x8962bcf8 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x786000
+0x020 OldestLsn : _LARGE_INTEGER 0x0
+0x028 NewestLsn : _LARGE_INTEGER 0x0
+0x030 Vacb : (null)
+0x034 PinCount : 0
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x89469530 _SHARED_CACHE_MAP
+0x074 BaseAddress : (null)
1: kd> dt _bcb 0x894d1280-10
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n4712 //错误
+0x002 Dirty : 0x4d 'M'
+0x003 Reserved : 0x89 ''
+0x004 ByteLength : 0x894d1278
+0x008 FileOffset : _LARGE_INTEGER 0x894d1280`894d1270
+0x010 BcbLinks : _LIST_ENTRY [ 0x894d1278 - 0x894c6668 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x894d1290`898f1298
+0x020 OldestLsn : _LARGE_INTEGER 0x894d1298`894d1288
+0x028 NewestLsn : _LARGE_INTEGER 0x894d12a0`894d1290
+0x030 Vacb : 0x894d1298 _VACB
+0x034 PinCount : 0x894d12a8
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x894d12d8 _SHARED_CACHE_MAP
+0x074 BaseAddress : 0x894d12e8 Void
1: kd> p
nt!CcFindBcb+0xb1:
80a12165 3bd1 cmp edx,ecx
1: kd> r
eax=8962bce8 ebx=89469530 ecx=00786000 edx=00785000
1: kd> p
nt!CcFindBcb+0xbe:
80a12172 83e810 sub eax,10h
1: kd> p
nt!CcFindBcb+0xc1:
80a12175 668138fd02 cmp word ptr [eax],2FDh
1: kd> r
eax=894c6658
if (FileOffset->QuadPart >= Bcbt->FileOffset.QuadPart) {
Found = TRUE;
break;
}
第七部分:
1: kd> dt _bcb 894c6658
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n765
+0x002 Dirty : 0x1 ''
+0x003 Reserved : 0 ''
+0x004 ByteLength : 0x1000
+0x008 FileOffset : _LARGE_INTEGER 0x785000
+0x010 BcbLinks : _LIST_ENTRY [ 0x894d1280 - 0x8962bcf8 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x786000
+0x020 OldestLsn : _LARGE_INTEGER 0x0
+0x028 NewestLsn : _LARGE_INTEGER 0x0
+0x030 Vacb : (null)
+0x034 PinCount : 0
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x89469530 _SHARED_CACHE_MAP
+0x074 BaseAddress : (null)
1: kd> dv
SharedCacheMap = 0x89469530
FileOffset = 0xf78d2768 {7884800}
BeyondLastByte = 0xf78d26c8 {7888896}
Bcb = 0xf78d26fc
Found = 0x01 ''
1: kd> dx -r1 ((ntkrnlmp!_BCB * *)0xf78d26fc)
((ntkrnlmp!_BCB * *)0xf78d26fc) : 0xf78d26fc [Type: _BCB * *]
0x894c6658 [Type: _BCB *]
return Found;
}
第八部分:
//
// Position ourselves. If we did not find a Bcb for the page, then
// a lower FileOffset was returned, so we want to move forward one.
//
if (!CcFindBcb( SharedCacheMap,
StartingOffset,
&StartingOffsetBias,
&Bcb )) { //返回到这里:
Bcb = CONTAINING_RECORD( Bcb->BcbLinks.Blink, BCB, BcbLinks );
}
dv
Bcb = 0x894c6658
Bcb = CONTAINING_RECORD( Bcb->BcbLinks.Blink, BCB, BcbLinks ); =0x8962bcf8-10
1: kd> dx -r1 ((ntkrnlmp!_BCB *)0x894c6658)
((ntkrnlmp!_BCB *)0x894c6658) : 0x894c6658 [Type: _BCB *]
[+0x000] Dummy [Type: _MBCB]
[+0x000] NodeTypeCode : 765 [Type: short]
[+0x002] Dirty : 0x1 [Type: unsigned char]
[+0x003] Reserved : 0x0 [Type: unsigned char]
[+0x004] ByteLength : 0x1000 [Type: unsigned long]
[+0x008] FileOffset : {7884800} [Type: _LARGE_INTEGER]
[+0x010] BcbLinks [Type: _LIST_ENTRY]
[+0x018] BeyondLastByte : {7888896} [Type: _LARGE_INTEGER]
[+0x020] OldestLsn : {0} [Type: _LARGE_INTEGER]
[+0x028] NewestLsn : {0} [Type: _LARGE_INTEGER]
[+0x030] Vacb : 0x0 [Type: _VACB *]
[+0x034] PinCount : 0x0 [Type: unsigned long]
[+0x038] Resource [Type: _ERESOURCE]
[+0x070] SharedCacheMap : 0x89469530 [Type: _SHARED_CACHE_MAP *]
[+0x074] BaseAddress : 0x0 [Type: void *]
1: kd> dx -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x894c6668))
(*((ntkrnlmp!_LIST_ENTRY *)0x894c6668)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x894d1280 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x8962bcf8 [Type: _LIST_ENTRY *] Blink : 0x8962bcf8
1: kd> dt _bcb 0x8962bcf8-10
nt!_BCB
+0x000 Dummy : _MBCB
+0x000 NodeTypeCode : 0n765
+0x002 Dirty : 0x1 ''
+0x003 Reserved : 0 ''
+0x004 ByteLength : 0x1000
+0x008 FileOffset : _LARGE_INTEGER 0x786000
+0x010 BcbLinks : _LIST_ENTRY [ 0x894c6668 - 0x898f1298 ]
+0x018 BeyondLastByte : _LARGE_INTEGER 0x787000
+0x020 OldestLsn : _LARGE_INTEGER 0x0
+0x028 NewestLsn : _LARGE_INTEGER 0x0
+0x030 Vacb : (null)
+0x034 PinCount : 0
+0x038 Resource : _ERESOURCE
+0x070 SharedCacheMap : 0x89469530 _SHARED_CACHE_MAP
+0x074 BaseAddress : (null)