Driver Verifier의 Pool Tracking이 어떤 방식으로 동작하는지 조금 살펴 보았다.
ExFreePoolWithTag() 에 전달된 해제할 메모리 주소를 분석하여 확인한다.
Verifier 검사 함수인 ViReleasePoolAllocation() 까지 이 메모리 주소가 전달된다.
0: kd> kb
ChildEBP RetAddr Args to Child
f7426ad4 806590b2 815d5f00 81cd8fa8 00000068 nt!ViReleasePoolAllocation+0x6
f7426af8 8066dc72 81cd8fa8 00000058 00000001 nt!ViFreeTrackedPool+0x8c
f7426b40 8054c32a 81cd8fa8 81105ad0 810ffce8 nt!MmFreeSpecialPool+0x1d2
f7426b80 8065a169 81cd8fa8 00000000 f7426b9c nt!ExFreePoolWithTag+0x4a
f7426b90 f706a8a6 81cd8fa8 f7426bb4 f706aac8 nt!VerifierFreePool+0x1f
...
ViReleasePoolAllocation() 의 두번째 파라미터(ebp+0x0c)가 메모리 주소이다.
0: kd> dd ebp
f7426ad4 f7426af8 806590b2 815d5f00 81cd8fa8
f7426ae4 00000068 00000058 81cd8000 00000058
f7426af4 c040e6c0 f7426b40 8066dc72 81cd8fa8
f7426b04 00000058 00000001 00000068 81105ad0
메모리 내용은 아래와 같이 우리가 사용하던 메모리이다.
0: kd> db 81cd8fa8
81cd8fa8 48 00 4b 00 4c 00 4d 00-5c 00 53 00 79 00 73 00 H.K.L.M.\.S.y.s.
81cd8fb8 74 00 65 00 6d 00 5c 00-43 00 6f 00 6e 00 74 00 t.e.m.\.C.o.n.t.
81cd8fc8 72 00 6f 00 6c 00 53 00-65 00 74 00 30 00 30 00 r.o.l.S.e.t.0.0.
81cd8fd8 32 00 5c 00 53 00 65 00-72 00 76 00 69 00 63 00 2.\.S.e.r.v.i.c.
이 메모리 속성을 보면 Special pool 임을 알 수 있다.
0: kd> !pool 81cd8fa8
Pool page 81cd8fa8 region is Special pool
*81cd8fb0 size: 50 pagable special pool, Tag is RMBN
Owning component : Unknown (update pooltag.txt)
Speical Pool 이기 때문에 페이지 맨 앞쪽에서 헤더를 확인한다.
0: kd> db 81cd8000
81cd8000 58 c0 e1 00 52 4d 42 4e-68 00 00 00 00 5f 5d 81 X...RMBNh...._].
81cd8010 e1 e1 e1 e1 e1 e1 e1 e1-e1 e1 e1 e1 e1 e1 e1 e1 ................
81cd8020 e1 e1 e1 e1 e1 e1 e1 e1-e1 e1 e1 e1 e1 e1 e1 e1 ................
81cd8030 e1 e1 e1 e1 e1 e1 e1 e1-e1 e1 e1 e1 e1 e1 e1 e1 ................
앞부분 8 바이트는 할당크기,상태,태그 정보가 있고 뒷부분에 관리 정보가 있다.
뒤부분 8바이트에 포함된 815d5f00 는 Verifier 관리 정보이다.
메모리 속성을 보면
0: kd> !pool 815d5f00
Pool page 815d5f00 region is Nonpaged pool
815d5000 size: 20 previous size: 0 (Allocated) NBqh
…
815d5dc0 size: 20 previous size: 30 (Allocated) VfGo
815d5de0 size: 118 previous size: 20 (Allocated) Dlck
*815d5ef8 size: 88 previous size: 118 (Allocated) *MmLd
Pooltag MmLd : Mm load module database, Binary : nt!mm
…
MemoryManager 의 load module database 라는 것을 알 수 있다.
내용을 보면 드라이버 이름이 보인다.
0: kd> db 815d5f00
815d5f00 48 2a 56 80 48 2a 56 80-03 00 00 00 01 00 00 00 H*V.H*V.........
815d5f10 18 00 1a 00 60 5f 5d 81-00 30 e5 f6 00 c0 e6 f6 ....`_]..0......
815d5f20 01 00 00 00 40 19 76 98-00 00 00 00 01 00 00 00 ....@.v.........
815d5f30 d0 bd 10 81 10 00 00 00-00 00 00 00 00 00 00 00 ................
815d5f40 00 00 00 00 08 00 00 00-02 00 00 00 09 00 00 00 ................
815d5f50 00 00 00 00 7c 01 00 00-00 90 3f 00 00 10 01 00 ....|.....?.....
815d5f60 41 00 79 00 44 00 6d 00-76 00 4e 00 73 00 79 00 M.y.D.r.v...s.y.
815d5f70 73 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 s...............
메모리 할당/해제시에 815d5f30 영역을 참조하여 메모리를 점검하는데 여기에 저장된 메모리 주소 8110bdd0 는 무엇인지 확인해 보자.
0: kd> !pool 8110bdd0
Pool page 8110bdd0 region is Nonpaged pool
8110b000 size: 108 previous size: 0 (Allocated) Driv (Protected)
…
8110bcb0 size: 118 previous size: 40 (Allocated) Devi (Protected)
*8110bdc8 size: 108 previous size: 118 (Allocated) *Vepp
Pooltag Vepp : Verifier Pool Tracking information, Binary : nt!Vf
…
Verifier의 Pool Tracking information 임을 알 수 있다.
내용을 보면
0: kd> db 8110bdd0
8110bdd0 09 00 00 00 6a b9 e5 f6-24 06 00 00 53 49 4f 00 ....j...$...SIO.
8110bde0 d0 ef d2 81 2c b6 e5 f6-30 00 00 00 53 49 4f 00 ....,...0...SIO.
8110bdf0 f0 0f 91 81 97 91 e5 f6-10 00 00 00 49 66 73 20 ............Ifs
8110be00 80 4f 69 82 ec 91 e5 f6-7c 00 00 00 49 66 73 20 .Oi.....|...Ifs
8110be10 d0 2f b3 81 94 92 e5 f6-2c 00 00 00 49 66 73 20 ./......,...Ifs
8110be20 f0 ef 4c 82 85 93 e5 f6-0c 00 00 00 49 66 73 20 ..L.........Ifs
8110be30 f0 0f 94 82 97 5b e5 f6-0c 00 00 00 49 66 73 20 .....[......Ifs
8110be40 b0 af 8b 81 ec 5b e5 f6-50 00 00 00 49 66 73 20 .....[..P...Ifs
일정한 형태가 보이므로 dd 로 다시 보면
0: kd> dd 8110bdd0
8110bdd0 00000009 f6e5b96a 00000624 004f4953
8110bde0 81d2efd0 f6e5b62c 00000030 004f4953
8110bdf0 81910ff0 f6e59197 00000010 20736649
8110be00 82694f80 f6e591ec 0000007c 20736649
8110be10 81b32fd0 f6e59294 0000002c 20736649
8110be20 824ceff0 f6e59385 0000000c 20736649
8110be30 82940ff0 f6e55b97 0000000c 20736649
8110be40 818bafb0 f6e55bec 00000050 20736649
한 부분만 선택해서 분석해 보니
81910ff0 는 할당된 메모리 주소
F6e59197 은 할당한 코드 주소
00000010 은 메모리 크기 임을 알 수 있다.
0: kd> db 81910ff0
81910ff0 00 00 00 00 80 4f 69 82-d0 2f b3 81 f0 ef 4c 82 .....Oi../....L.
81911000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
81911010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
81911020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0: kd> u f6e59197
MyDrv!AllocList+0x17
6e59197 8945f8 mov dword ptr [ebp-8],eax
f6e5919a 837df800 cmp dword ptr [ebp-8],0
f6e5919e 7507 jne MyDrv!AllocList+0x27 (f6e591a7)
f6e591a0 33c0 xor eax,eax
f6e591a2 e963020000 jmp MyDrv!AllocList+0x28a (f6e5940a)
f6e591a7 8b4508 mov eax,dword ptr [ebp+8]
f6e591aa 50 push eax
f6e591ab ff15a02be6f6 call dword ptr [MyDrv!_imp__wcslen (f6e62ba0)]
Verifier의 Pool Tracking information 에 메모리 할당정보가 저장되어 있는 것을 알 수 있다.