[原创]遍历VISTA/WIN 7 缓存VACB
发表于:
2010-8-25 17:29
9575
PS:好久没在看雪发东西,这里有我大学的记忆。。。。
有时候系统缓慢,被占很多缓存,所以想知道哪些文件占据了缓存。缓存的结构在XP和VISTA下有些区别,为了了解VISTA的结构,XP比较简单就不说了。
IDA+WINDBG开始摸索,下面就是过程和结果。
很多文件没缓存,所以为了方便找出缓存的FILLE_OBJECT,我选择对nt!CcMapData下断
kd> bp nt!CcMapData "!fileobj poi(@esp + 4)"
kd> g
\$Directory
Device Object: 0x86579c08 \Driver\volmgr
Vpb: 0x8616d0d0
Access: Read Write SharedRead SharedWrite SharedDelete
Flags: 0x40100
Stream File
Handle Created
FsContext: 0x890740f8 FsContext2: 0x00000000
Private Cache Map: 0x873ff0e0
CurrentByteOffset: 0
Cache Data:
Section Object Pointers: 86a1c2c4
Shared Cache Map: 873ff008 File Offset: 0 in VACB number 0
Vacb: 84b6df10
Your data is at: 8ae40000 kd> dt _SECTION_OBJECT_POINTERS 86a1c2c4
ntdll!_SECTION_OBJECT_POINTERS
+0x000 DataSectionObject : 0x86b8ddb8 Void
+0x004 SharedCacheMap : 0x873ff008 Void
+0x008 ImageSectionObject : (null) kd> dt _SHARED_CACHE_MAP 0x873ff008 InitialVacbs
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] 0x84b6df10 _VACB 查看VACB在什么内核池中:
kd> !pool 0x84b6df10
Pool page 84b6df10 region is Nonpaged pool
*84b6d000 : large page allocation, Tag is CcVa, size is 0x20000 bytes
Pooltag CcVa : Cache Manager Initial array of Vacbs, Binary : nt!cc 可见这个VACB是落在TAG为 CcVa 的POOL中,那是谁分配了这个POOL kd> ed nt!poolhittag 'aVcC'
kd> g
Break instruction exception - code 80000003 (first chance)
nt!DbgBreakPoint:
8186e954 cc int 3
kd> kv
ChildEBP RetAddr Args to Child
80599b74 818592c9 61566343 00020000 00000000 nt!DbgBreakPoint
80599bd0 8190a4cd 00000000 00000000 00020000 nt!ExpAllocateBigPool+0x216
80599c30 8181e282 00000000 00020000 61566343 nt!ExAllocatePoolWithTag+0x116
80599c4c 81b6c0a0 80599c5c 00000001 00000000 nt!CcAllocateInitializeVacbArray+0x19
80599c60 81b6bf8d 8085b010 00010000 00000000 nt!CcInitializeVacbs+0x82
80599c98 81b7ca0a 84b34540 84b34218 00000000 nt!CcInitializeCacheManager+0x3b5
80599d74 81975af1 80599dc0 819f2a1c 8085b010 nt!Phase1InitializationDiscard+0x8dd
80599d7c 819f2a1c 8085b010 3d3a5762 00000000 nt!Phase1Initialization+0xd
80599dc0 8184ba3e 81975ae4 8085b010 00000000 nt!PspSystemThreadStartup+0x9d
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 上面的栈比较清晰地看到nt!CcAllocateInitializeVacbArray创建了 CcVa 的POOL,第三个参数61566343其实就是CcVa
看下nt!CcAllocateInitializeVacbArray
.text:004013A0 014 call esi ; KeReleaseQueuedSpinLock(x,x) ; KeReleaseQueuedSpinLock(x,x)
.text:004013A2 00C push 61566343h ; Tag
.text:004013A7 010 mov edi, 20000h
.text:004013AC 010 push edi ; NumberOfBytes
.text:004013AD 014 push 0 ; PoolType
.text:004013AF 018 call _ExAllocatePoolWithTag@12 ; ExAllocatePoolWithTag(x,x,x)
.text:004013B4 00C mov ebx, eax .text:004013C6 00C lea eax, [ebx+28h]
.text:004013C9 00C mov ecx, 0FFFh
.text:004013CE
.text:004013CE loc_4013CE: ; CODE XREF: CcAllocateInitializeVacbArray()+66 j
.text:004013CE 00C mov [eax], ebx
.text:004013D0 00C add eax, 20h @@@@@@@@@@@@@@@重要,VACB大小是0X18,但我们需要0X20才能访问
.text:004013D3 00C dec ecx
.text:004013D4 00C jnz short loc_4013CE
.text:004013D6 00C jmp short loc_4013EE 分配的这片内存进行初始化, 每隔0X20,都会填一个指向该内存的指针
kd> !list "-t _LIST_ENTRY.Flink -e -x \"dt _VACB_ARRAY_HEADER @$extret\" poi(CcVacbArrays)"
dt _VACB_ARRAY_HEADER @$extret
nt!_VACB_ARRAY_HEADER
+0x000 Links : _LIST_ENTRY [ 0x819530c8 - 0x819530c8 ]
+0x008 MappingCount : 0x2e0
+0x00c Reserved : 0
kd> dd 0x819530c8 l2
819530c8 84b6d000 84b6d000
84b6d000 就是 ExAllocatePoolWithTag( NonPagedPool,0x20000, 'aVcC') 分配的内存 kd> dd 84b6d000 l16
/*84b6d000*/ 819530c8 819530c8 000002e0 00000000
84b6d010 83440000 00000000 00000000 00000000
84b6d020 84b6d040 819530b0 /*84b6d000*/ 00000000
84b6d030 83480000 00000000 00000000 00000000
84b6d040 84b6d060 84b6d020 /*84b6d000*/ 00000000
84b6d050 834c0000 00000000
就是上面代码初始化的原因 也就是nt!_VACB_ARRAY_HEADER的Links其实就是指向的内存第一个指针就是BigPool的指针
目前的话
测试下VACB在内存的位置
kd> bp nt!CcMapData " dt _SHARED_CACHE_MAP poi((poi((poi(@esp + 4) + 0x14)) + 0x4 )) InitialVacbs Vacbs ; g"
kd> g
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] (null)
+0x040 Vacbs : 0x86830df8 -> 0x86824910 _VACB
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] 0x84b6f8b0 _VACB
+0x040 Vacbs : 0x8690bd78 -> 0x84b6f8b0 _VACB
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] 0x84b6f8b0 _VACB
+0x040 Vacbs : 0x8690bd78 -> 0x84b6f8b0 _VACB
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] (null)
+0x040 Vacbs : 0x86830df8 -> 0x86824910 _VACB
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] 0x84b6f910 _VACB
+0x040 Vacbs : 0x86a50430 -> 0x84b6f910 _VACB
nt!_SHARED_CACHE_MAP
+0x030 InitialVacbs : [4] 0x84b6f910 _VACB
+0x040 Vacbs : 0x86a50430 -> 0x84b6f910 _VACB
kd> dt _VACB 0x84b6f8b0
nt!_VACB
+0x000 BaseAddress : 0x8ebc0000 Void
+0x004 SharedCacheMap : 0x8690bd48 _SHARED_CACHE_MAP
+0x008 Overlay : <unnamed-tag>
+0x010 LruList : _LIST_ENTRY [ 0x84b715c0 - 0x84b72e60 ]
+0x018 ArrayHead : 0x84b6d000 _VACB_ARRAY_HEADER kd> .printf"%x\n",poi(0x86a50430) ;dt _VACB poi(0x86a50430)
84b6f910
nt!_VACB
+0x000 BaseAddress : 0x8f840000 Void
+0x004 SharedCacheMap : 0x86a50400 _SHARED_CACHE_MAP
+0x008 Overlay : <unnamed-tag>
+0x010 LruList : _LIST_ENTRY [ 0x84b6e060 - 0x84b715c0 ]
+0x018 ArrayHead : 0x84b6d000 _VACB_ARRAY_HEADER
kd> ? 0x84b6f910 - 0x84b6f8b0
Evaluate expression: 96 = 00000060 kd> ? 0n96 / 0x20
Evaluate expression: 3 = 00000003
能被整除,俩个VACB中间隔了3个VACB 目前的话我们知道CcVa POOL的地址范围是 84b6d000 - 84b8d000 ( 84b6d000 + 0x20000 )
这个范围内就有我们的VACB。。。下面是WINDBG的脚本
$t0 的值可以通过bp /1 nt!CcMapData "r $t0 = poi(@esp + 4); r $t10 = poi((poi(poi( @$t0 + 0x14 ) + 0x4) + 0x30))
; r $t11 = poi((poi(poi( @$t0 + 0x14 ) + 0x4) + 0x40)) ; r $t11 = poi(poi(@$t11)); r @$t10 ; r @$t11 "来获取 .expr /s masm;
r $t0 = 0x84b6f910; $$第一个VACB
r $t1 = poi(nt!CcVacbArrays);
r $t2 = @$t1 + 0x20000;
.printf"Hdr = 0x%x, end = 0x%x\n",@$t1,@$t2 ;
.printf"down --->\n";
.for( r $t3 = $t0 ; @$t3 < @$t2 ; r $t3 = @$t3 + 0x20)
{
.if( poi(@$t3 + 0x04) == 0 )
{
.printf"VACB = 0x%x NULL SharedCacheMap \n",@$t3;
.continue
}
r $t4 = @$t3;
r $t4 = poi(@$t4 + 0x18);
r $t5 = poi((poi(@$t3 + 0x04) + 0x44 )) + 0x30;
.if( @$t4 == $t1)
{
.printf"vacb = 0x%x fileobj 0x%x, %msu \n",@$t3, @$t5-0x30, @$t5;
}
}
.printf"up --->\n";
.for( r $t3 = $t0 ; @$t3 > @$t1 ; r $t3 = @$t3 - 0x20)
{
.if( poi(@$t3 + 0x04) == 0 )
{
.printf"VACB = 0x%x NULL SharedCacheMap \n",@$t3;
.continue
}
r $t4 = @$t3;
r $t4 = poi(@$t4 + 0x18);
r $t5 = poi((poi(@$t3 + 0x04) + 0x44 )) + 0x30; .if( @$t4 == $t1 & @$t3 + 0x04 != 0 )
{
.printf"vacb = 0x%x fileobj 0x%x ,%msu\n",@$t3, @$t5-0x30, @$t5;
}
} 输出
kd> $$>a<c:\vacb.txt
Current expression evaluator: MASM - Microsoft Assembler expressions
Hdr = 0x84b6d000, end = 0x84b8d000
down --->
vacb = 0x84b6f910 fileobj 0x86a38300 ,\$Directory
vacb = 0x84b6f930 fileobj 0x86838f1f ,<Win32 error 0n30>
vacb = 0x84b6f950 fileobj 0x86980450 ,\$Directory
vacb = 0x84b6f970 fileobj 0x85287e70 ,\$Directory
vacb = 0x84b6f990 fileobj 0x85132250 ,\Windows\System32\catroot2\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}\catdb
vacb = 0x84b6f9b0 fileobj 0x86b1ad00 ,\$Directory
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课