00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "cmp.h"
00028
#include <windef.h>
00029
#include <ntkdexts.h>
00030
#include <stdlib.h>
00031
#include <stdio.h>
00032
00033 HIVE_LIST_ENTRY HiveList[8];
00034
00035 ULONG
TotalPages;
00036 ULONG
TotalPresentPages;
00037
00038 ULONG
TotalKcbs;
00039 ULONG
TotalKcbName;
00040
00041 BOOLEAN
SavePages;
00042 BOOLEAN
RestorePages;
00043 FILE *
TempFile;
00044
00045 PNTKD_OUTPUT_ROUTINE
lpPrint;
00046 PNTKD_GET_EXPRESSION
lpGetExpressionRoutine;
00047 PNTKD_GET_SYMBOL
lpGetSymbolRoutine;
00048 PNTKD_CHECK_CONTROL_C
lpCheckControlCRoutine;
00049 PNTKD_READ_VIRTUAL_MEMORY
lpReadMem;
00050
00051
void
00052
poolDumpHive(
00053 IN
PCMHIVE Hive
00054 );
00055
00056
VOID
00057
poolDumpMap(
00058 IN ULONG Length,
00059 IN
PHMAP_DIRECTORY Map
00060 );
00061
00062
void
00063
dumpHiveFromFile(
00064 IN FILE *File
00065 );
00066
00067
VOID
00068
kcbWorker(
00069 IN
PCM_KEY_CONTROL_BLOCK pKcb
00070 );
00071
00072
VOID
00073 pool(
00074 DWORD dwCurrentPc,
00075 PNTKD_EXTENSION_APIS lpExtensionApis,
00076 LPSTR lpArgumentString
00077 )
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 {
00111 PLIST_ENTRY pCmpHiveListHead;
00112 PLIST_ENTRY pNextHiveList;
00113
HIVE_LIST_ENTRY *pHiveListEntry;
00114 ULONG BytesRead;
00115
PCMHIVE CmHive;
00116
00117
lpPrint = lpExtensionApis->lpOutputRoutine;
00118
lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
00119
lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine;
00120
lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
00121
lpReadMem = lpExtensionApis->lpReadVirtualMemRoutine;
00122
00123
if (toupper(lpArgumentString[0])==
'S') {
00124
SavePages =
TRUE;
00125 }
else {
00126
SavePages =
FALSE;
00127 }
00128
if (toupper(lpArgumentString[0])==
'R') {
00129
RestorePages =
TRUE;
00130 }
else {
00131
RestorePages =
FALSE;
00132 }
00133
00134
00135
00136
00137 memset(
HiveList,0,
sizeof(
HiveList));
00138 pHiveListEntry = (
PHIVE_LIST_ENTRY)(
lpGetExpressionRoutine)(
"CmpMachineHiveList");
00139
if (pHiveListEntry !=
NULL) {
00140 (
lpReadMem)(pHiveListEntry,
00141
HiveList,
00142
sizeof(
HiveList),
00143 &BytesRead);
00144 }
00145
00146
00147
00148
00149 pCmpHiveListHead = (PLIST_ENTRY)(
lpGetExpressionRoutine)(
"CmpHiveListHead");
00150
if (pCmpHiveListHead==
NULL) {
00151 (
lpPrint)(
"CmpHiveListHead couldn't be read\n");
00152
return;
00153 }
00154
00155 (
lpReadMem)(&pCmpHiveListHead->Flink,
00156 &pNextHiveList,
00157
sizeof(pNextHiveList),
00158 &BytesRead);
00159
if (BytesRead !=
sizeof(pNextHiveList)) {
00160 (
lpPrint)(
"Couldn't read first Flink (%lx) of CmpHiveList\n",
00161 &pCmpHiveListHead->Flink);
00162
return;
00163 }
00164
00165
TotalPages =
TotalPresentPages = 0;
00166
00167
if (
SavePages) {
00168
TempFile = fopen(
"regext.dat",
"w+");
00169
if (
TempFile==
NULL) {
00170 (
lpPrint)(
"Couldn't create regext.dat for write\n");
00171
return;
00172 }
00173 }
else if (
RestorePages) {
00174
TempFile = fopen(
"regext.dat",
"r");
00175
if (
TempFile==
NULL) {
00176 (
lpPrint)(
"Couldn't open regext.dat for read\n");
00177
return;
00178 }
00179 }
00180
00181
if (
RestorePages) {
00182
dumpHiveFromFile(
TempFile);
00183 }
else {
00184
while (pNextHiveList != pCmpHiveListHead) {
00185 CmHive = CONTAINING_RECORD(pNextHiveList,
CMHIVE,
HiveList);
00186
poolDumpHive(CmHive);
00187
00188 (
lpReadMem)(&pNextHiveList->Flink,
00189 &pNextHiveList,
00190
sizeof(pNextHiveList),
00191 &BytesRead);
00192
if (BytesRead !=
sizeof(pNextHiveList)) {
00193 (
lpPrint)(
"Couldn't read Flink (%lx) of %lx\n",
00194 &pCmpHiveListHead->Flink,pNextHiveList);
00195
break;
00196 }
00197
00198 }
00199 }
00200
00201 (
lpPrint)(
"Total pages present = %d / %d\n",
00202
TotalPresentPages,
00203
TotalPages);
00204
00205
if (
SavePages ||
RestorePages) {
00206 fclose(
TempFile);
00207 }
00208 }
00209
00210
void
00211 poolDumpHive(
00212 IN
PCMHIVE pHive
00213 )
00214 {
00215
CMHIVE CmHive;
00216 ULONG BytesRead;
00217 WCHAR
FileName[
HBASE_NAME_ALLOC/2 + 1];
00218 ULONG i;
00219
00220 (
lpPrint)(
"\ndumping hive at %lx ",pHive);
00221 (
lpReadMem)(pHive,
00222 &CmHive,
00223
sizeof(CmHive),
00224 &BytesRead);
00225
00226
if (BytesRead <
sizeof(CmHive)) {
00227 (
lpPrint)(
"\tRead %lx bytes from %lx\n",BytesRead,pHive);
00228
return;
00229 }
00230
00231 (
lpReadMem)(&CmHive.Hive.BaseBlock->FileName,
00232
FileName,
00233
sizeof(
FileName),
00234 &BytesRead);
00235
00236
if (BytesRead <
sizeof(
FileName)) {
00237 wcscpy(
FileName,
L"UNKNOWN");
00238 }
else {
00239
if (
FileName[0]==
L'\0') {
00240 wcscpy(
FileName,
L"NONAME");
00241 }
else {
00242
FileName[
HBASE_NAME_ALLOC/2]=
L'\0';
00243 }
00244 }
00245
00246 (
lpPrint)(
"(%ws)\n",
FileName);
00247
00248 (
lpPrint)(
" %d KCBs open\n",CmHive.KcbCount);
00249 (
lpPrint)(
" Stable Length = %lx\n",CmHive.Hive.Storage[
Stable].Length);
00250
if (
SavePages) {
00251 fprintf(
TempFile,
00252
"%ws %d %d\n",
00253
FileName,
00254 CmHive.Hive.Storage[
Stable].Length,
00255 CmHive.Hive.Storage[
Volatile].Length);
00256 }
00257
poolDumpMap(CmHive.Hive.Storage[
Stable].Length,
00258 CmHive.Hive.Storage[
Stable].Map);
00259
00260 (
lpPrint)(
" Volatile Length = %lx\n",CmHive.Hive.Storage[
Volatile].Length);
00261
poolDumpMap(CmHive.Hive.Storage[
Volatile].Length,
00262 CmHive.Hive.Storage[
Volatile].Map);
00263
00264 }
00265
00266
VOID
00267 poolDumpMap(
00268 IN ULONG Length,
00269 IN
PHMAP_DIRECTORY Map
00270 )
00271 {
00272 ULONG Tables;
00273 ULONG MapSlots;
00274 ULONG i;
00275 ULONG BytesRead;
00276
HMAP_DIRECTORY MapDirectory;
00277
PHMAP_TABLE MapTable;
00278
HMAP_ENTRY MapEntry;
00279 ULONG Garbage;
00280 ULONG Present=0;
00281
00282
if (Length==0) {
00283
return;
00284 }
00285
00286 MapSlots = Length /
HBLOCK_SIZE;
00287 Tables = 1+ ((MapSlots-1) /
HTABLE_SLOTS);
00288
00289
00290
00291
00292 (
lpReadMem)(Map,
00293 &MapDirectory,
00294 Tables *
sizeof(
PHMAP_TABLE),
00295 &BytesRead);
00296
if (BytesRead < (Tables *
sizeof(
PHMAP_TABLE))) {
00297 (
lpPrint)(
"Only read %lx/%lx bytes from %lx\n",
00298 BytesRead,
00299 Tables *
sizeof(
PHMAP_TABLE),
00300 Map);
00301
return;
00302
00303 }
00304
00305
00306
00307
00308
for (i=0; i<MapSlots; i++) {
00309
00310 MapTable = MapDirectory.Directory[i/
HTABLE_SLOTS];
00311
00312 (
lpReadMem)(&(MapTable->
Table[i%
HTABLE_SLOTS]),
00313 &MapEntry,
00314
sizeof(
HMAP_ENTRY),
00315 &BytesRead);
00316
if (BytesRead <
sizeof(
HMAP_ENTRY)) {
00317 (
lpPrint)(
" can't read HMAP_ENTRY at %lx\n",
00318 &(MapTable->
Table[i%
HTABLE_SLOTS]));
00319 }
00320
00321
if (
SavePages) {
00322 fprintf(
TempFile,
"%lx\n",MapEntry.
BlockAddress);
00323
00324 }
00325
00326
00327
00328
00329 (
lpReadMem)(MapEntry.
BlockAddress,
00330 &Garbage,
00331
sizeof(ULONG),
00332 &BytesRead);
00333
if (BytesRead > 0) {
00334 ++Present;
00335 }
00336 }
00337 (
lpPrint)(
" %d/%d pages present\n",
00338 Present,
00339 MapSlots);
00340
00341
TotalPages += MapSlots;
00342
TotalPresentPages += Present;
00343
00344 }
00345
00346
void
00347 dumpHiveFromFile(
00348 IN FILE *File
00349 )
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 {
00387
CHAR Hivename[33];
00388 ULONG StableLength;
00389 ULONG VolatileLength;
00390 ULONG Page;
00391 ULONG i;
00392 ULONG NumFields;
00393 ULONG Garbage;
00394 ULONG Present;
00395 ULONG Total;
00396 ULONG BytesRead;
00397
00398
while (!feof(
File)) {
00399 NumFields = fscanf(
File,
"%s %d %d\n",
00400 Hivename,
00401 &StableLength,
00402 &VolatileLength);
00403
if (NumFields != 3) {
00404 (
lpPrint)(
"fscanf returned %d\n",NumFields);
00405
return;
00406 }
00407
00408 (
lpPrint)(
"\ndumping hive %s\n",Hivename);
00409 (
lpPrint)(
" Stable Length = %lx\n",StableLength);
00410 Present = 0;
00411 Total = 0;
00412
while (StableLength > 0) {
00413 fscanf(
File,
"%lx\n",&Page);
00414 (
lpReadMem)(Page,
00415 &Garbage,
00416
sizeof(ULONG),
00417 &BytesRead);
00418
if (BytesRead > 0) {
00419 ++Present;
00420 }
00421 ++Total;
00422 StableLength -=
HBLOCK_SIZE;
00423 }
00424
if (Total > 0) {
00425 (
lpPrint)(
" %d/%d stable pages present\n",
00426 Present,Total);
00427 }
00428
TotalPages += Total;
00429
TotalPresentPages += Present;
00430
00431 (
lpPrint)(
" Volatile Length = %lx\n",VolatileLength);
00432 Present = 0;
00433 Total = 0;
00434
while (VolatileLength > 0) {
00435 fscanf(
File,
"%lx\n",&Page);
00436 (
lpReadMem)(Page,
00437 &Garbage,
00438
sizeof(ULONG),
00439 &BytesRead);
00440
if (BytesRead > 0) {
00441 ++Present;
00442 }
00443 ++Total;
00444 VolatileLength -=
HBLOCK_SIZE;
00445 }
00446
if (Total > 0) {
00447 (
lpPrint)(
" %d/%d volatile pages present\n",
00448 Present,Total);
00449 }
00450
00451
TotalPages += Total;
00452
TotalPresentPages += Present;
00453 }
00454
00455 }
00456
00457
void
00458 kcb(
00459 DWORD dwCurrentPc,
00460 PNTKD_EXTENSION_APIS lpExtensionApis,
00461 LPSTR lpArgumentString
00462 )
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 {
00493
PCM_KEY_CONTROL_BLOCK pKCB;
00494
PCM_KEY_CONTROL_BLOCK Root;
00495 ULONG BytesRead;
00496
00497
lpPrint = lpExtensionApis->lpOutputRoutine;
00498
lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
00499
lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine;
00500
lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
00501
lpReadMem = lpExtensionApis->lpReadVirtualMemRoutine;
00502
00503 Root = (
PCM_KEY_CONTROL_BLOCK)(
lpGetExpressionRoutine)(
"CmpKeyControlBlockRoot");
00504
if (Root ==
NULL) {
00505 (
lpPrint)(
"Couldn't find address of CmpKeyControlBlockRoot\n");
00506
return;
00507 }
00508 (
lpReadMem)(Root,
00509 &pKCB,
00510
sizeof(pKCB),
00511 &BytesRead);
00512
00513
if (BytesRead <
sizeof(pKCB)) {
00514 (
lpPrint)(
"Couldn't get pKCB from CmpKeyControlBlockRoot\n");
00515 }
00516
00517
TotalKcbs = 0;
00518
TotalKcbName = 0;
00519
kcbWorker(pKCB);
00520
00521 (
lpPrint)(
"%d KCBs\n",
TotalKcbs);
00522 (
lpPrint)(
"%d total bytes of FullNames\n",
TotalKcbName);
00523
00524 }
00525
00526
VOID
00527 kcbWorker(
00528 IN
PCM_KEY_CONTROL_BLOCK pKcb
00529 )
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 {
00548
CM_KEY_CONTROL_BLOCK kcb;
00549 ULONG BytesRead;
00550 WCHAR *
Buffer;
00551
00552 ++
TotalKcbs;
00553 (
lpReadMem)(pKcb,
00554 &
kcb,
00555
sizeof(
kcb),
00556 &BytesRead);
00557
if (BytesRead <
sizeof(
kcb)) {
00558 (
lpPrint)(
"Can't read kcb at %lx\n",pKcb);
00559
return;
00560 }
00561
TotalKcbName +=
kcb.FullName.Length;
00562
00563
if (
kcb.Left !=
NULL) {
00564
kcbWorker(
kcb.Left);
00565 }
00566
00567 (
lpPrint)(
"%d - ",
kcb.RefCount);
00568
00569
Buffer = malloc(
kcb.FullName.Length);
00570
if (
Buffer !=
NULL) {
00571 (
lpReadMem)(
kcb.FullName.Buffer,
00572
Buffer,
00573
kcb.FullName.Length,
00574 &BytesRead);
00575
00576
kcb.FullName.Length = BytesRead;
00577
kcb.FullName.Buffer =
Buffer;
00578
00579 (
lpPrint)(
" %wZ\n",&
kcb.FullName);
00580 free(
Buffer);
00581
00582 }
else {
00583 (
lpPrint)(
" ??? \n");
00584 }
00585
00586
if (
kcb.Right !=
NULL) {
00587
kcbWorker(
kcb.Right);
00588 }
00589
00590
00591 }
00592