Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3255 lines
90 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. verifier.c
  5. Abstract:
  6. Application verifier debugger extension for both ntsd and kd.
  7. Author:
  8. Silviu Calinoiu (SilviuC) 4-Mar-2001
  9. Environment:
  10. User Mode.
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // Page heap extension functions (defined in heappagx.c and heappagxXP.c).
  16. // We need one for WinXP client and one for latest .NET server because the internal
  17. // structures changed significantly and there are not separate debugger packages
  18. // for each OS. We have this problem only for stuff implemented inside ntdll.dll
  19. // since the dll is different between OSes. We do nto have this problem for
  20. // verifier.dll because this one is refreshed whenever the application verifier
  21. // package is installed.
  22. //
  23. VOID
  24. PageHeapExtension(
  25. IN PCSTR lpArgumentString
  26. );
  27. VOID
  28. DebugPageHeapExtensionXP(
  29. IN PCSTR lpArgumentString
  30. );
  31. //
  32. // Local functions
  33. //
  34. ULONG
  35. VrfGetArguments (
  36. PCHAR ArgsString,
  37. PCHAR Args[],
  38. ULONG NoOfArgs
  39. );
  40. VOID
  41. VrfHelp (
  42. VOID
  43. );
  44. BOOLEAN
  45. VrfTraceInitialize (
  46. );
  47. ULONG64
  48. VrfTraceAddress (
  49. ULONG TraceIndex
  50. );
  51. VOID
  52. VrfTraceDump (
  53. ULONG TraceIndex
  54. );
  55. LOGICAL
  56. VrfVerifierGlobalFlagSet (
  57. VOID
  58. );
  59. VOID
  60. VrfDumpSettings (
  61. );
  62. VOID
  63. VrfDumpStopInformation (
  64. VOID
  65. );
  66. VOID
  67. VrfFigureOutAddress (
  68. ULONG64 Address
  69. );
  70. VOID
  71. VrfDumpGlobalCounters (
  72. VOID
  73. );
  74. VOID
  75. VrfDumpBreakTriggers (
  76. VOID
  77. );
  78. VOID
  79. VrfToggleBreakTrigger (
  80. ULONG Index
  81. );
  82. VOID
  83. VrfDumpFaultInjectionSettings (
  84. VOID
  85. );
  86. VOID
  87. VrfSetFaultInjectionParameters (
  88. ULONG Index,
  89. ULONG Probability
  90. );
  91. VOID
  92. VrfSetFaultInjectionCallParameters (
  93. ULONG Index,
  94. ULONG Call
  95. );
  96. VOID
  97. VrfDumpFaultInjectionTargetRanges (
  98. VOID
  99. );
  100. VOID
  101. VrfAddFaultInjectionTargetRange (
  102. ULONG64 Start,
  103. ULONG64 End
  104. );
  105. VOID
  106. VrfResetFaultInjectionTargetRanges (
  107. VOID
  108. );
  109. VOID
  110. VrfDumpFaultInjectionExclusionRanges (
  111. VOID
  112. );
  113. VOID
  114. VrfAddFaultInjectionExclusionRange (
  115. ULONG64 Start,
  116. ULONG64 End
  117. );
  118. VOID
  119. VrfResetFaultInjectionExclusionRanges (
  120. VOID
  121. );
  122. VOID
  123. VrfSetFaultInjectionExclusionPeriod (
  124. ULONG64 TimeInMsecs
  125. );
  126. VOID
  127. VrfDumpFaultInjectionTraces (
  128. ULONG Count
  129. );
  130. VOID
  131. VrfToggleFaultInjectionBreak (
  132. ULONG Index
  133. );
  134. VOID
  135. VrfSetFaultInjectionDllTarget (
  136. PCHAR DllName,
  137. LOGICAL Exclude
  138. );
  139. VOID
  140. VrfDumpExceptionLog (
  141. ULONG MaxEntries
  142. );
  143. VOID
  144. VrfDumpThreadsInformation (
  145. ULONG64 UserThreadId
  146. );
  147. LOGICAL
  148. VrfCheckSymbols (
  149. PCHAR * DllName
  150. );
  151. //
  152. // Globals.
  153. //
  154. LOGICAL WinXpClient;
  155. /////////////////////////////////////////////////////////////////////
  156. /////////////////////////////////////////////// Call tracker querying
  157. /////////////////////////////////////////////////////////////////////
  158. extern ULONG64 VrfThreadTrackerAddress;
  159. extern ULONG64 VrfHeapTrackerAddress;
  160. extern ULONG64 VrfVspaceTrackerAddress;
  161. LOGICAL
  162. VrfDetectTrackerAddresses (
  163. VOID
  164. );
  165. LOGICAL
  166. VrfQueryCallTracker (
  167. ULONG64 TrackerAddress,
  168. ULONG64 SearchAddress,
  169. ULONG64 LastEntries
  170. );
  171. /////////////////////////////////////////////////////////////////////
  172. /////////////////////////////////////////////////// !avrf entry point
  173. /////////////////////////////////////////////////////////////////////
  174. DECLARE_API( avrf )
  175. /*++
  176. Routine Description:
  177. Application verifier debugger extension.
  178. Arguments:
  179. args -
  180. Return Value:
  181. None
  182. --*/
  183. {
  184. PCHAR Args[16];
  185. ULONG NoOfArgs, I;
  186. PCHAR DllName;
  187. INIT_API();
  188. if (g_TargetBuild <= 2600) {
  189. WinXpClient = TRUE;
  190. }
  191. //
  192. // Check out the symbols.
  193. //
  194. if (VrfCheckSymbols(&DllName) == FALSE) {
  195. if (DllName) {
  196. dprintf ("Please fix the symbols for `%s'.\n", DllName);
  197. }
  198. return S_OK;
  199. }
  200. //
  201. // Parse arguments.
  202. //
  203. NoOfArgs = VrfGetArguments ((PCHAR)args,
  204. Args,
  205. 16);
  206. //
  207. // Check if help needed
  208. //
  209. if (NoOfArgs > 0 && strstr (Args[0], "?") != NULL) {
  210. VrfHelp ();
  211. goto Exit;
  212. }
  213. if (NoOfArgs > 0 && _stricmp (Args[0], "-cnt") == 0) {
  214. VrfDumpGlobalCounters ();
  215. goto Exit;
  216. }
  217. if (NoOfArgs > 0 && _stricmp (Args[0], "-brk") == 0) {
  218. if (NoOfArgs > 1) {
  219. ULONG64 Index;
  220. BOOL Result;
  221. PCSTR Remainder;
  222. Result = GetExpressionEx (Args[1], &Index, &Remainder);
  223. if (Result == FALSE) {
  224. dprintf ("\nFailed to convert `%s' to an index.\n", Args[1]);
  225. goto Exit;
  226. }
  227. VrfToggleBreakTrigger ((ULONG)Index);
  228. }
  229. else {
  230. VrfDumpBreakTriggers ();
  231. }
  232. goto Exit;
  233. }
  234. if (NoOfArgs > 0 && _stricmp (Args[0], "-flt") == 0) {
  235. if (NoOfArgs == 1) {
  236. VrfDumpFaultInjectionSettings ();
  237. }
  238. else if (NoOfArgs == 3){
  239. if (_stricmp(Args[1], "stacks") == 0) {
  240. ULONG64 Count;
  241. BOOL Result;
  242. PCSTR Remainder;
  243. Result = GetExpressionEx (Args[2], &Count, &Remainder);
  244. if (Result == FALSE) {
  245. dprintf ("\nFailed to convert `%s' to a number.\n", Args[2]);
  246. goto Exit;
  247. }
  248. VrfDumpFaultInjectionTraces ((ULONG)Count);
  249. }
  250. else if (_stricmp(Args[1], "break") == 0) {
  251. ULONG64 Count;
  252. BOOL Result;
  253. PCSTR Remainder;
  254. Result = GetExpressionEx (Args[2], &Count, &Remainder);
  255. if (Result == FALSE) {
  256. dprintf ("\nFailed to convert `%s' to an index.\n", Args[2]);
  257. goto Exit;
  258. }
  259. VrfToggleFaultInjectionBreak ((ULONG)Count);
  260. }
  261. else {
  262. ULONG64 Index;
  263. ULONG64 Probability;
  264. BOOL Result;
  265. PCSTR Remainder;
  266. Result = GetExpressionEx (Args[1], &Index, &Remainder);
  267. if (Result == FALSE) {
  268. dprintf ("\nFailed to convert `%s' to an index.\n", Args[1]);
  269. goto Exit;
  270. }
  271. Result = GetExpressionEx (Args[2], &Probability, &Remainder);
  272. if (Result == FALSE) {
  273. dprintf ("\nFailed to convert `%s' to a probability.\n", Args[2]);
  274. goto Exit;
  275. }
  276. VrfSetFaultInjectionParameters ((ULONG)Index,
  277. (ULONG)Probability);
  278. }
  279. }
  280. goto Exit;
  281. }
  282. if (NoOfArgs > 0 && _stricmp (Args[0], "-trg") == 0) {
  283. if (NoOfArgs > 1) {
  284. if (_stricmp(Args[1], "all") == 0) {
  285. VrfResetFaultInjectionTargetRanges ();
  286. }
  287. else if (NoOfArgs == 3 && _stricmp(Args[1], "dll") == 0) {
  288. VrfSetFaultInjectionDllTarget (Args[2], FALSE);
  289. }
  290. else if (NoOfArgs > 2){
  291. ULONG64 Start;
  292. ULONG64 End;
  293. BOOL Result;
  294. PCSTR Remainder;
  295. Result = GetExpressionEx (Args[1], &Start, &Remainder);
  296. if (Result == FALSE) {
  297. dprintf ("\nFailed to convert `%s' to a start address.\n", Args[1]);
  298. goto Exit;
  299. }
  300. Result = GetExpressionEx (Args[2], &End, &Remainder);
  301. if (Result == FALSE) {
  302. dprintf ("\nFailed to convert `%s' to an end address.\n", Args[2]);
  303. goto Exit;
  304. }
  305. VrfAddFaultInjectionTargetRange (Start, End);
  306. }
  307. }
  308. else {
  309. VrfDumpFaultInjectionTargetRanges ();
  310. }
  311. goto Exit;
  312. }
  313. if (NoOfArgs > 0 && _stricmp (Args[0], "-skp") == 0) {
  314. if (NoOfArgs > 1) {
  315. if (_stricmp(Args[1], "all") == 0) {
  316. VrfResetFaultInjectionExclusionRanges ();
  317. }
  318. else if (NoOfArgs == 3 && _stricmp(Args[1], "dll") == 0) {
  319. VrfSetFaultInjectionDllTarget (Args[2], TRUE);
  320. }
  321. else if (NoOfArgs == 2) {
  322. ULONG64 Period;
  323. BOOL Result;
  324. PCSTR Remainder;
  325. Result = GetExpressionEx (Args[1], &Period, &Remainder);
  326. if (Result == FALSE) {
  327. dprintf ("\nFailed to convert `%s' to a number.\n", Args[1]);
  328. goto Exit;
  329. }
  330. VrfSetFaultInjectionExclusionPeriod (Period);
  331. }
  332. else if (NoOfArgs > 2){
  333. ULONG64 Start;
  334. ULONG64 End;
  335. BOOL Result;
  336. PCSTR Remainder;
  337. Result = GetExpressionEx (Args[1], &Start, &Remainder);
  338. if (Result == FALSE) {
  339. dprintf ("\nFailed to convert `%s' to a start address.\n", Args[1]);
  340. goto Exit;
  341. }
  342. Result = GetExpressionEx (Args[2], &End, &Remainder);
  343. if (Result == FALSE) {
  344. dprintf ("\nFailed to convert `%s' to an end address.\n", Args[2]);
  345. goto Exit;
  346. }
  347. VrfAddFaultInjectionExclusionRange (Start, End);
  348. }
  349. }
  350. else {
  351. VrfDumpFaultInjectionExclusionRanges ();
  352. }
  353. goto Exit;
  354. }
  355. if (NoOfArgs > 0 && _stricmp (Args[0], "-ex") == 0) {
  356. ULONG MaxEntries;
  357. if (NoOfArgs > 1) {
  358. MaxEntries = atoi (Args[1]);
  359. }
  360. else {
  361. MaxEntries = (ULONG)-1;
  362. }
  363. VrfDumpExceptionLog (MaxEntries);
  364. goto Exit;
  365. }
  366. if (NoOfArgs > 0 && _stricmp (Args[0], "-threads") == 0) {
  367. ULONG64 ThreadId;
  368. if (NoOfArgs > 1) {
  369. BOOL Result;
  370. PCSTR Remainder;
  371. Result = GetExpressionEx (Args[1], &ThreadId, &Remainder);
  372. }
  373. else {
  374. ThreadId = 0;
  375. }
  376. VrfDumpThreadsInformation (ThreadId);
  377. goto Exit;
  378. }
  379. //
  380. // The rest of the options need traces support.
  381. //
  382. if (VrfTraceInitialize() == FALSE) {
  383. goto DumpAndExit;
  384. }
  385. if (NoOfArgs > 1 && _stricmp (Args[0], "-trace") == 0) {
  386. ULONG Index;
  387. Index = (ULONG) GetExpression (Args[1]);
  388. if (Index != 0) {
  389. VrfTraceDump (Index);
  390. }
  391. else {
  392. dprintf ("Invalid trace index: `%s' . \n", Args[1]);
  393. }
  394. goto Exit;
  395. }
  396. if (NoOfArgs > 1 && _stricmp (Args[0], "-a") == 0) {
  397. ULONG64 Address;
  398. BOOL Result;
  399. PCSTR Remainder;
  400. Result = GetExpressionEx (Args[1], &Address, &Remainder);
  401. if (Result == FALSE) {
  402. dprintf ("\nFailed to convert `%s' to an address.\n", Args[1]);
  403. goto Exit;
  404. }
  405. dprintf ("Address %I64X ...\n\n", Address);
  406. VrfFigureOutAddress (Address);
  407. goto Exit;
  408. }
  409. if (NoOfArgs > 1 && _stricmp (Args[0], "-vs") == 0) {
  410. if (NoOfArgs > 2 && _stricmp (Args[1], "-a") == 0) {
  411. ULONG64 Address;
  412. BOOL Result;
  413. PCSTR Remainder;
  414. Result = GetExpressionEx (Args[2], &Address, &Remainder);
  415. if (Result == FALSE) {
  416. dprintf ("\nFailed to convert `%s' to an address.\n", Args[2]);
  417. goto Exit;
  418. }
  419. VrfQueryCallTracker (VrfVspaceTrackerAddress, Address, 0);
  420. goto Exit;
  421. }
  422. else {
  423. VrfQueryCallTracker (VrfVspaceTrackerAddress, 0, atoi(Args[1]));
  424. goto Exit;
  425. }
  426. }
  427. if (NoOfArgs > 1 && _stricmp (Args[0], "-hp") == 0) {
  428. if (NoOfArgs > 2 && _stricmp (Args[1], "-a") == 0) {
  429. ULONG64 Address;
  430. BOOL Result;
  431. PCSTR Remainder;
  432. Result = GetExpressionEx (Args[2], &Address, &Remainder);
  433. if (Result == FALSE) {
  434. dprintf ("\nFailed to convert `%s' to an address.\n", Args[2]);
  435. goto Exit;
  436. }
  437. VrfQueryCallTracker (VrfHeapTrackerAddress, Address, 0);
  438. goto Exit;
  439. }
  440. else {
  441. VrfQueryCallTracker (VrfHeapTrackerAddress, 0, atoi(Args[1]));
  442. goto Exit;
  443. }
  444. }
  445. if (NoOfArgs > 0 && _stricmp (Args[0], "-trm") == 0) {
  446. VrfQueryCallTracker (VrfThreadTrackerAddress, 0, 32);
  447. goto Exit;
  448. }
  449. //
  450. // If no option specified then we just print current settings.
  451. //
  452. DumpAndExit:
  453. VrfDumpSettings ();
  454. Exit:
  455. EXIT_API();
  456. return S_OK;
  457. }
  458. VOID
  459. VrfHelp (
  460. VOID
  461. )
  462. {
  463. dprintf ("Application verifier debugger extension \n"
  464. " \n"
  465. "!avrf displays current settings and stop \n"
  466. " data if a verifier stop happened. \n"
  467. // "!avrf -a ADDR figure out the nature of address ADDR. \n"
  468. "!avrf -vs N dump last N entries from vspace log. \n"
  469. "!avrf -vs -a ADDR searches ADDR in the vspace log. \n"
  470. "!avrf -hp N dump last N entries from heap log. \n"
  471. "!avrf -hp -a ADDR searches ADDR in the heap log. \n"
  472. "!avrf -trm dump thread terminate/suspend log. \n"
  473. "!avrf -ex [N] dump exception log entries. \n"
  474. "!avrf -threads [TID] dump threads information. \n"
  475. "!avrf -trace INDEX dump stack trace with index INDEX. \n"
  476. "!avrf -cnt dump global counters. \n"
  477. "!avrf -brk [INDEX] dump or set/reset break triggers. \n"
  478. "!avrf -flt dump fault injection settings. \n"
  479. "!avrf -flt INDX PROB set fault probability for an event. \n"
  480. "!avrf -flt break INDX toggle break for a fault injection event.\n"
  481. "!avrf -flt stacks N dump the last N fault injection stacks. \n"
  482. "!avrf -trg dump fault injection target addresses. \n"
  483. "!avrf -trg START END add a new fault target range. \n"
  484. "!avrf -trg dll XXX add code in dll XXX as target range. \n"
  485. "!avrf -trg all deletes all fault target ranges. \n"
  486. "!avrf -skp dump fault injection exclusion addresses.\n"
  487. "!avrf -skp START END add a new fault exclusion range. \n"
  488. "!avrf -skp dll XXX add code in dll XXX as exclusion range. \n"
  489. "!avrf -skp all deletes all fault exclusion ranges. \n"
  490. "!avrf -skp TIME disable faults for TIME msecs. \n"
  491. " \n");
  492. }
  493. /////////////////////////////////////////////////////////////////////
  494. /////////////////////////////////////////// Argument parsing routines
  495. /////////////////////////////////////////////////////////////////////
  496. PCHAR
  497. VrfGetArgument (
  498. PCHAR Args,
  499. PCHAR * Next
  500. )
  501. {
  502. PCHAR Start;
  503. if (Args == NULL) {
  504. return NULL;
  505. }
  506. while (*Args == ' ' || *Args == '\t') {
  507. Args += 1;
  508. }
  509. if (*Args == '\0') {
  510. return NULL;
  511. }
  512. Start = Args;
  513. while (*Args != ' ' && *Args != '\t' && *Args != '\0') {
  514. Args += 1;
  515. }
  516. if (*Args == '\0') {
  517. *Next = NULL;
  518. }
  519. else {
  520. *Args = '\0';
  521. *Next = Args + 1;
  522. }
  523. return Start;
  524. }
  525. ULONG
  526. VrfGetArguments (
  527. PCHAR ArgsString,
  528. PCHAR Args[],
  529. ULONG NoOfArgs
  530. )
  531. {
  532. PCHAR Arg = ArgsString;
  533. PCHAR Next;
  534. ULONG Index;
  535. for (Index = 0; Index < NoOfArgs; Index += 1) {
  536. Arg = VrfGetArgument (Arg, &Next);
  537. if (Arg) {
  538. Args[Index] = Arg;
  539. }
  540. else {
  541. break;
  542. }
  543. Arg = Next;
  544. }
  545. return Index;
  546. }
  547. /////////////////////////////////////////////////////////////////////
  548. /////////////////////////////////////////////////// Dump stack traces
  549. /////////////////////////////////////////////////////////////////////
  550. ULONG64 TraceDbArrayEnd;
  551. ULONG PvoidSize;
  552. BOOLEAN
  553. VrfTraceInitialize (
  554. )
  555. {
  556. ULONG64 TraceDatabaseAddress;
  557. ULONG64 TraceDatabase;
  558. //
  559. // Stack trace database address
  560. //
  561. TraceDatabaseAddress = GetExpression("ntdll!RtlpStackTraceDataBase");
  562. if ( TraceDatabaseAddress == 0 ) {
  563. dprintf( "Unable to resolve ntdll!RtlpStackTraceDataBase symbolic name.\n");
  564. return FALSE;
  565. }
  566. if (!ReadPointer (TraceDatabaseAddress, &TraceDatabase ) != S_OK) {
  567. dprintf( "Cannot read pointer at ntdll!RtlpStackTraceDataBase\n" );
  568. return FALSE;
  569. }
  570. if (TraceDatabase == 0) {
  571. dprintf( "Stack traces not enabled (ntdll!RtlpStackTraceDataBase is null).\n" );
  572. return FALSE;
  573. }
  574. //
  575. // Find the array of stack traces
  576. //
  577. if (InitTypeRead(TraceDatabase, ntdll!_STACK_TRACE_DATABASE)) {
  578. dprintf("Unable to read type ntdll!_STACK_TRACE_DATABASE @ %p\n", TraceDatabase);
  579. return FALSE;
  580. }
  581. TraceDbArrayEnd = ReadField (EntryIndexArray);
  582. PvoidSize = IsPtr64() ? 8 : 4;
  583. return TRUE;
  584. }
  585. ULONG64
  586. VrfTraceAddress (
  587. ULONG TraceIndex
  588. )
  589. {
  590. ULONG64 TracePointerAddress;
  591. ULONG64 TracePointer;
  592. TracePointerAddress = TraceDbArrayEnd - TraceIndex * PvoidSize;
  593. if (!ReadPointer (TracePointerAddress, &TracePointer) != S_OK) {
  594. dprintf ("Cannot read stack trace address @ %p\n", TracePointerAddress);
  595. return 0;
  596. }
  597. return TracePointer;
  598. }
  599. VOID
  600. VrfTraceDump (
  601. ULONG TraceIndex
  602. )
  603. {
  604. ULONG64 TraceAddress;
  605. ULONG64 TraceArray;
  606. ULONG TraceDepth;
  607. ULONG Offset;
  608. ULONG Index;
  609. ULONG64 ReturnAddress;
  610. CHAR Symbol[ 1024 ];
  611. ULONG64 Displacement;
  612. //
  613. // Get real address of the trace.
  614. //
  615. TraceAddress = VrfTraceAddress (TraceIndex);
  616. if (TraceAddress == 0) {
  617. return;
  618. }
  619. //
  620. // Read the stack trace depth
  621. //
  622. if (InitTypeRead(TraceAddress, ntdll!_RTL_STACK_TRACE_ENTRY)) {
  623. dprintf("Unable to read type ntdll!_RTL_STACK_TRACE_ENTRY @ %p\n", TraceAddress);
  624. return;
  625. }
  626. TraceDepth = (ULONG)ReadField (Depth);
  627. //
  628. // Limit the depth to 20 to protect ourselves from corrupted data
  629. //
  630. TraceDepth = __min (TraceDepth, 16);
  631. //
  632. // Get a pointer to the BackTrace array
  633. //
  634. GetFieldOffset ("ntdll!_RTL_STACK_TRACE_ENTRY", "BackTrace", &Offset);
  635. TraceArray = TraceAddress + Offset;
  636. //
  637. // Dump this stack trace. Skip first two entries.
  638. //
  639. TraceArray += 2 * PvoidSize;
  640. for (Index = 2; Index < TraceDepth; Index += 1) {
  641. if (!ReadPointer (TraceArray, &ReturnAddress) != S_OK) {
  642. dprintf ("Cannot read address @ %p\n", TraceArray);
  643. return;
  644. }
  645. GetSymbol (ReturnAddress, Symbol, &Displacement);
  646. dprintf ("\t%p: %s+0x%I64X\n",
  647. ReturnAddress,
  648. Symbol,
  649. Displacement );
  650. TraceArray += PvoidSize;
  651. }
  652. }
  653. /////////////////////////////////////////////////////////////////////
  654. /////////////////////////////////////////////////////// Dump settings
  655. /////////////////////////////////////////////////////////////////////
  656. ULONG64
  657. VrfPebAddress (
  658. VOID
  659. )
  660. {
  661. ULONG64 PebAddress;
  662. GetPebAddress (0, &PebAddress);
  663. // dprintf ("PEB @ %I64X \n", PebAddress);
  664. return PebAddress;
  665. }
  666. LOGICAL
  667. VrfVerifierGlobalFlagSet (
  668. VOID
  669. )
  670. {
  671. ULONG64 FlagsAddress;
  672. ULONG Flags;
  673. ULONG BytesRead;
  674. ULONG I;
  675. ULONG64 GlobalFlags;
  676. InitTypeRead (VrfPebAddress(), ntdll!_PEB);
  677. GlobalFlags = ReadField (NtGlobalFlag);
  678. if ((GlobalFlags & FLG_APPLICATION_VERIFIER)) {
  679. return TRUE;
  680. }
  681. else {
  682. return FALSE;
  683. }
  684. }
  685. VOID
  686. VrfDumpSettings (
  687. )
  688. {
  689. ULONG64 FlagsAddress;
  690. ULONG Flags;
  691. ULONG BytesRead;
  692. ULONG I;
  693. ULONG64 GlobalFlags;
  694. InitTypeRead (VrfPebAddress(), ntdll!_PEB);
  695. GlobalFlags = ReadField (NtGlobalFlag);
  696. dprintf ("\nGlobal flags: %08I64X \n", GlobalFlags);
  697. if ((GlobalFlags & FLG_APPLICATION_VERIFIER)) {
  698. dprintf ("Application verifier global flag is set. \n");
  699. }
  700. if ((GlobalFlags & FLG_HEAP_PAGE_ALLOCS)) {
  701. dprintf ("Page heap global flag is set. \n");
  702. }
  703. dprintf ("\n");
  704. if ((GlobalFlags & FLG_APPLICATION_VERIFIER) == 0) {
  705. dprintf ("Application verifier is not enabled for this process. \n");
  706. if ((GlobalFlags & FLG_HEAP_PAGE_ALLOCS)) {
  707. dprintf ("Page heap has been enabled separately. \n");
  708. }
  709. return;
  710. }
  711. FlagsAddress = GetExpression("ntdll!AVrfpVerifierFlags");
  712. if (FlagsAddress == 0) {
  713. dprintf( "Unable to resolve ntdll!AVrfpVerifierFlags symbolic name.\n");
  714. return;
  715. }
  716. if (ReadMemory (FlagsAddress, &Flags, sizeof Flags, &BytesRead) == FALSE) {
  717. dprintf ("Cannot read value @ %p (ntdll!AVrfpVerifierFlags) \n", FlagsAddress);
  718. return;
  719. }
  720. dprintf ("Application verifier settings (%08X): \n\n", Flags);
  721. if (WinXpClient) {
  722. //
  723. // On XP client no heap checks actually means light page heap.
  724. //
  725. if (Flags & RTL_VRF_FLG_FULL_PAGE_HEAP) {
  726. dprintf (" - full page heap\n");
  727. }
  728. else {
  729. dprintf (" - light page heap\n");
  730. }
  731. }
  732. else {
  733. //
  734. // On .NET server no heap checks really means no heap checks.
  735. //
  736. if (Flags & RTL_VRF_FLG_FULL_PAGE_HEAP) {
  737. dprintf (" - full page heap\n");
  738. }
  739. else if (Flags & RTL_VRF_FLG_FAST_FILL_HEAP) {
  740. dprintf (" - fast fill heap (a.k.a light page heap)\n");
  741. }
  742. else {
  743. dprintf (" - no heap checking enabled!\n");
  744. }
  745. }
  746. if (Flags & RTL_VRF_FLG_LOCK_CHECKS) {
  747. dprintf (" - lock checks (critical section verifier)\n");
  748. }
  749. if (Flags & RTL_VRF_FLG_HANDLE_CHECKS) {
  750. dprintf (" - handle checks\n");
  751. }
  752. if (Flags & RTL_VRF_FLG_STACK_CHECKS) {
  753. dprintf (" - stack checks (disable automatic stack extensions)\n");
  754. }
  755. if (Flags & RTL_VRF_FLG_TLS_CHECKS) {
  756. dprintf (" - TLS checks (thread local storage APIs)\n");
  757. }
  758. if (Flags & RTL_VRF_FLG_RPC_CHECKS) {
  759. dprintf (" - RPC checks (RPC verifier)\n");
  760. }
  761. if (Flags & RTL_VRF_FLG_COM_CHECKS) {
  762. dprintf (" - COM checks (COM verifier)\n");
  763. }
  764. if (Flags & RTL_VRF_FLG_DANGEROUS_APIS) {
  765. dprintf (" - bad APIs (e.g. TerminateThread)\n");
  766. }
  767. if (Flags & RTL_VRF_FLG_RACE_CHECKS) {
  768. dprintf (" - random delays for wait operations\n");
  769. }
  770. if (Flags & RTL_VRF_FLG_VIRTUAL_MEM_CHECKS) {
  771. dprintf (" - virtual memory operations checks\n");
  772. }
  773. if (Flags & RTL_VRF_FLG_DEADLOCK_CHECKS) {
  774. dprintf (" - deadlock verifier\n");
  775. }
  776. dprintf ("\n");
  777. //
  778. // Call the appropriate page heap extension.
  779. //
  780. if (WinXpClient) {
  781. DebugPageHeapExtensionXP ("-p");
  782. }
  783. else {
  784. PageHeapExtension ("-p");
  785. }
  786. dprintf ("\n");
  787. //
  788. // Dump verifier stop information if there is any.
  789. //
  790. VrfDumpStopInformation ();
  791. }
  792. /////////////////////////////////////////////////////////////////////
  793. /////////////////////////////////////////////////////////// Stop data
  794. /////////////////////////////////////////////////////////////////////
  795. VOID
  796. VrfDumpBriefStopDescription (
  797. ULONG64 Code
  798. );
  799. VOID
  800. VrfDumpStopInformation (
  801. VOID
  802. )
  803. {
  804. ULONG64 CurrentStopAddress;
  805. ULONG64 CurrentStopData[5];
  806. ULONG64 PreviousStopAddress;
  807. ULONG64 PreviousStopData[5];
  808. ULONG I;
  809. ULONG UlongPtrSize;
  810. UlongPtrSize = GetTypeSize ("ntdll!ULONG_PTR");
  811. //
  812. // Check if a verifier stop has been encountered.
  813. //
  814. CurrentStopAddress = GetExpression("verifier!AVrfpStopData");
  815. if (CurrentStopAddress == 0) {
  816. dprintf( "Unable to resolve verifier!AVrfpStopData symbolic name.\n");
  817. return;
  818. }
  819. for (I = 0; I < 5; I += 1) {
  820. if (!ReadPointer (CurrentStopAddress + I * UlongPtrSize, &(CurrentStopData[I])) != S_OK) {
  821. dprintf ("Cannot read value @ %p \n", CurrentStopAddress + I * UlongPtrSize);
  822. }
  823. }
  824. //
  825. // Read also previous stop data.
  826. //
  827. PreviousStopAddress = GetExpression("verifier!AVrfpPreviousStopData");
  828. if (PreviousStopAddress == 0) {
  829. dprintf( "Unable to resolve verifier!AVrfpPreviousStopData symbolic name.\n");
  830. return;
  831. }
  832. for (I = 0; I < 5; I += 1) {
  833. if (!ReadPointer (PreviousStopAddress + I * UlongPtrSize, &(PreviousStopData[I])) != S_OK) {
  834. dprintf ("Cannot read value @ %p \n", PreviousStopAddress + I * UlongPtrSize);
  835. }
  836. }
  837. //
  838. // Parse the values just read.
  839. //
  840. if (PreviousStopData[0] != 0) {
  841. dprintf ("Previous stop %p : %p %p %p %p was continued! \n",
  842. PreviousStopData[0],
  843. PreviousStopData[1],
  844. PreviousStopData[2],
  845. PreviousStopData[3],
  846. PreviousStopData[4]);
  847. dprintf ("\n ");
  848. VrfDumpBriefStopDescription (PreviousStopData[0]);
  849. dprintf ("\n");
  850. }
  851. if (CurrentStopData[0] == 0) {
  852. dprintf ("No verifier stop active. \n\n");
  853. dprintf ("Note. Sometimes bugs found by verifier manifest themselves \n"
  854. "as raised exceptions (access violations, stack overflows, invalid handles \n"
  855. "and it is not always necessary to have a verifier stop. \n");
  856. }
  857. else {
  858. dprintf ("Current stop %p : %p %p %p %p . \n",
  859. CurrentStopData[0],
  860. CurrentStopData[1],
  861. CurrentStopData[2],
  862. CurrentStopData[3],
  863. CurrentStopData[4]);
  864. dprintf ("\n ");
  865. VrfDumpBriefStopDescription (CurrentStopData[0]);
  866. dprintf ("\n");
  867. }
  868. }
  869. VOID
  870. VrfDumpBriefStopDescription (
  871. ULONG64 Code
  872. )
  873. {
  874. switch (Code) {
  875. case APPLICATION_VERIFIER_UNKNOWN_ERROR:
  876. dprintf ("Unknown error. \n");
  877. break;
  878. case APPLICATION_VERIFIER_ACCESS_VIOLATION:
  879. dprintf ("Access violation. \n");
  880. break;
  881. case APPLICATION_VERIFIER_UNSYNCHRONIZED_ACCESS:
  882. dprintf ("Unsynchronized access. \n");
  883. break;
  884. case APPLICATION_VERIFIER_EXTREME_SIZE_REQUEST:
  885. dprintf ("Extreme size request. \n");
  886. break;
  887. case APPLICATION_VERIFIER_BAD_HEAP_HANDLE:
  888. dprintf ("Bad heap handle (not even handle of another heap). \n");
  889. break;
  890. case APPLICATION_VERIFIER_SWITCHED_HEAP_HANDLE:
  891. dprintf ("Switched heap handle. \n");
  892. break;
  893. case APPLICATION_VERIFIER_DOUBLE_FREE:
  894. dprintf ("Double free. \n");
  895. break;
  896. case APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK:
  897. dprintf ("Corrupted heap block. \n");
  898. break;
  899. case APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP:
  900. dprintf ("Attempt to destroy process heap. \n");
  901. break;
  902. case APPLICATION_VERIFIER_UNEXPECTED_EXCEPTION:
  903. dprintf ("Unexpected exception inside page heap code. \n");
  904. break;
  905. case APPLICATION_VERIFIER_STACK_OVERFLOW:
  906. dprintf ("Stack overflow. \n");
  907. break;
  908. case APPLICATION_VERIFIER_INVALID_FREEMEM:
  909. dprintf ("Invalid free memory. \n");
  910. break;
  911. case APPLICATION_VERIFIER_INVALID_ALLOCMEM:
  912. dprintf ("Invalid memory allocation. \n");
  913. break;
  914. case APPLICATION_VERIFIER_INVALID_MAPVIEW:
  915. dprintf ("Invalid memory mapping. \n");
  916. break;
  917. case APPLICATION_VERIFIER_TERMINATE_THREAD_CALL:
  918. dprintf ("TerminateThread() call. \n");
  919. break;
  920. case APPLICATION_VERIFIER_INVALID_EXIT_PROCESS_CALL:
  921. dprintf ("ExitProcess() call while multiple threads still running. \n");
  922. break;
  923. case APPLICATION_VERIFIER_EXIT_THREAD_OWNS_LOCK:
  924. dprintf ("Threads owns lock in a context it should not. \n");
  925. break;
  926. case APPLICATION_VERIFIER_LOCK_IN_UNLOADED_DLL:
  927. dprintf ("DLL unloaded contains a critical section that was not deleted. \n");
  928. break;
  929. case APPLICATION_VERIFIER_LOCK_IN_FREED_HEAP:
  930. dprintf ("Block freed contains a critical section that was not deleted. \n");
  931. break;
  932. case APPLICATION_VERIFIER_LOCK_IN_FREED_MEMORY:
  933. dprintf ("Virtual region freed contains a critical section that was not deleted. \n");
  934. break;
  935. case APPLICATION_VERIFIER_LOCK_DOUBLE_INITIALIZE:
  936. dprintf ("Critical section initialized twice. \n");
  937. break;
  938. case APPLICATION_VERIFIER_LOCK_CORRUPTED:
  939. dprintf ("Corrupted critical section. \n");
  940. break;
  941. case APPLICATION_VERIFIER_LOCK_INVALID_OWNER:
  942. dprintf ("Critical section has invalid owner. \n");
  943. break;
  944. case APPLICATION_VERIFIER_LOCK_INVALID_RECURSION_COUNT:
  945. dprintf ("Critical section has invalid recursion count. \n");
  946. break;
  947. case APPLICATION_VERIFIER_LOCK_INVALID_LOCK_COUNT:
  948. dprintf ("Critical section has invalid lock count. \n");
  949. break;
  950. case APPLICATION_VERIFIER_LOCK_OVER_RELEASED:
  951. dprintf ("Releasing a critical section that is not acquired. \n");
  952. break;
  953. case APPLICATION_VERIFIER_LOCK_NOT_INITIALIZED:
  954. dprintf ("Using an uninitialized critical section. \n");
  955. break;
  956. case APPLICATION_VERIFIER_LOCK_ALREADY_INITIALIZED:
  957. dprintf ("Initializing a critical section already initialized. \n");
  958. break;
  959. case APPLICATION_VERIFIER_INVALID_HANDLE:
  960. dprintf ("Using an invalid handle (either closed or simply bad). \n");
  961. break;
  962. case APPLICATION_VERIFIER_INVALID_TLS_VALUE:
  963. dprintf ("Using an invalid TLS value (not obtained from TlsAlloc()). \n");
  964. break;
  965. case APPLICATION_VERIFIER_INCORRECT_WAIT_CALL:
  966. dprintf ("Wait call with invalid parameters. \n");
  967. break;
  968. case APPLICATION_VERIFIER_NULL_HANDLE:
  969. dprintf ("Using a null handle. \n");
  970. break;
  971. case APPLICATION_VERIFIER_WAIT_IN_DLLMAIN:
  972. dprintf ("Wait operation in DllMain function. \n");
  973. break;
  974. case APPLICATION_VERIFIER_COM_ERROR:
  975. dprintf ("COM related error. \n");
  976. break;
  977. case APPLICATION_VERIFIER_COM_API_IN_DLLMAIN:
  978. dprintf ("COM error: APPLICATION_VERIFIER_COM_API_IN_DLLMAIN \n");
  979. break;
  980. case APPLICATION_VERIFIER_COM_UNHANDLED_EXCEPTION:
  981. dprintf ("COM error: APPLICATION_VERIFIER_COM_UNHANDLED_EXCEPTION \n");
  982. break;
  983. case APPLICATION_VERIFIER_COM_UNBALANCED_COINIT:
  984. dprintf ("COM error: APPLICATION_VERIFIER_COM_UNBALANCED_COINIT \n");
  985. break;
  986. case APPLICATION_VERIFIER_COM_UNBALANCED_OLEINIT:
  987. dprintf ("COM error: APPLICATION_VERIFIER_COM_UNBALANCED_OLEINIT \n");
  988. break;
  989. case APPLICATION_VERIFIER_COM_UNBALANCED_SWC:
  990. dprintf ("COM error: APPLICATION_VERIFIER_COM_UNBALANCED_SWC \n");
  991. break;
  992. case APPLICATION_VERIFIER_COM_NULL_DACL:
  993. dprintf ("COM error: APPLICATION_VERIFIER_COM_NULL_DACL \n");
  994. break;
  995. case APPLICATION_VERIFIER_COM_UNSAFE_IMPERSONATION:
  996. dprintf ("COM error: APPLICATION_VERIFIER_COM_UNSAFE_IMPERSONATION\n");
  997. break;
  998. case APPLICATION_VERIFIER_COM_SMUGGLED_WRAPPER:
  999. dprintf ("COM error: APPLICATION_VERIFIER_COM_SMUGGLED_WRAPPER \n");
  1000. break;
  1001. case APPLICATION_VERIFIER_COM_SMUGGLED_PROXY:
  1002. dprintf ("COM error: APPLICATION_VERIFIER_COM_SMUGGLED_PROXY \n");
  1003. break;
  1004. case APPLICATION_VERIFIER_COM_CF_SUCCESS_WITH_NULL:
  1005. dprintf ("COM error: APPLICATION_VERIFIER_COM_CF_SUCCESS_WITH_NULL \n");
  1006. break;
  1007. case APPLICATION_VERIFIER_COM_GCO_SUCCESS_WITH_NULL:
  1008. dprintf ("COM error: APPLICATION_VERIFIER_COM_GCO_SUCCESS_WITH_NULL \n");
  1009. break;
  1010. case APPLICATION_VERIFIER_COM_OBJECT_IN_FREED_MEMORY:
  1011. dprintf ("COM error: APPLICATION_VERIFIER_COM_OBJECT_IN_FREED_MEMORY \n");
  1012. break;
  1013. case APPLICATION_VERIFIER_COM_OBJECT_IN_UNLOADED_DLL:
  1014. dprintf ("COM error: APPLICATION_VERIFIER_COM_OBJECT_IN_UNLOADED_DLL \n");
  1015. break;
  1016. case APPLICATION_VERIFIER_COM_VTBL_IN_FREED_MEMORY:
  1017. dprintf ("COM error: APPLICATION_VERIFIER_COM_VTBL_IN_FREED_MEMORY \n");
  1018. break;
  1019. case APPLICATION_VERIFIER_COM_VTBL_IN_UNLOADED_DLL:
  1020. dprintf ("COM error: APPLICATION_VERIFIER_COM_VTBL_IN_UNLOADED_DLL \n");
  1021. break;
  1022. case APPLICATION_VERIFIER_COM_HOLDING_LOCKS_ON_CALL:
  1023. dprintf ("COM error: APPLICATION_VERIFIER_COM_HOLDING_LOCKS_ON_CALL \n");
  1024. break;
  1025. case APPLICATION_VERIFIER_RPC_ERROR:
  1026. dprintf ("RPC related error. \n");
  1027. break;
  1028. default:
  1029. dprintf ("UNRECOGNIZED STOP CODE! \n");
  1030. break;
  1031. }
  1032. }
  1033. /////////////////////////////////////////////////////////////////////
  1034. /////////////////////////////////////////////////// Nature of address
  1035. /////////////////////////////////////////////////////////////////////
  1036. //
  1037. // Definitions from \nt\base\ntos\rtl\heappagi.h
  1038. //
  1039. #define DPH_NORMAL_BLOCK_START_STAMP_ALLOCATED 0xABCDAAAA
  1040. #define DPH_NORMAL_BLOCK_END_STAMP_ALLOCATED 0xDCBAAAAA
  1041. #define DPH_PAGE_BLOCK_START_STAMP_ALLOCATED 0xABCDBBBB
  1042. #define DPH_PAGE_BLOCK_END_STAMP_ALLOCATED 0xDCBABBBB
  1043. #define DPH_NORMAL_BLOCK_SUFFIX 0xA0
  1044. #define DPH_PAGE_BLOCK_PREFIX 0xB0
  1045. #define DPH_PAGE_BLOCK_INFIX 0xC0
  1046. #define DPH_PAGE_BLOCK_SUFFIX 0xD0
  1047. #define DPH_NORMAL_BLOCK_INFIX 0xE0
  1048. #define DPH_FREE_BLOCK_INFIX 0xF0
  1049. VOID
  1050. VrfFigureOutAddress (
  1051. ULONG64 Address
  1052. )
  1053. {
  1054. ULONG64 Prefix;
  1055. ULONG PrefixSize;
  1056. ULONG64 StartStamp, EndStamp;
  1057. ULONG64 Heap;
  1058. CHAR Buffer[128];
  1059. PrefixSize = GetTypeSize ("NTDLL!_DPH_BLOCK_INFORMATION");
  1060. Prefix = Address - PrefixSize;
  1061. if (InitTypeRead (Prefix, NTDLL!_DPH_BLOCK_INFORMATION) == 0) {
  1062. StartStamp = ReadField (StartStamp);
  1063. EndStamp = ReadField (EndStamp);
  1064. Heap = ReadField (Heap);
  1065. if (EndStamp == DPH_NORMAL_BLOCK_END_STAMP_ALLOCATED) {
  1066. dprintf ("Address %I64X is the start of a block allocated in light heap %I64X .\n",
  1067. Address, Heap);
  1068. }
  1069. else if (EndStamp == DPH_NORMAL_BLOCK_END_STAMP_ALLOCATED - 1) {
  1070. dprintf ("Address %I64X is the start of a block freed in light heap %I64X .\n"
  1071. "The block is still in the delayed free cache.\n",
  1072. Address, Heap);
  1073. }
  1074. else if (EndStamp == DPH_NORMAL_BLOCK_END_STAMP_ALLOCATED - 2) {
  1075. dprintf ("Address %I64X is the start of a block freed in light heap %I64X .\n"
  1076. "The block was recycled, it is not in the delayed free cache anymore.\n",
  1077. Address, Heap);
  1078. }
  1079. else {
  1080. sprintf (Buffer, "-p -a %I64X", Address);
  1081. dprintf ("Searching inside page heap structures ... \n");
  1082. //
  1083. // Call the appropriate page heap extension.
  1084. //
  1085. if (WinXpClient) {
  1086. DebugPageHeapExtensionXP (Buffer);
  1087. }
  1088. else {
  1089. PageHeapExtension (Buffer);
  1090. }
  1091. }
  1092. }
  1093. }
  1094. /////////////////////////////////////////////////////////////////////
  1095. /////////////////////////////////////////////////////////////////////
  1096. /////////////////////////////////////////////////////////////////////
  1097. ULONG
  1098. ReadULONG (
  1099. ULONG64 Address
  1100. )
  1101. {
  1102. ULONG Value;
  1103. ULONG BytesRead;
  1104. if (ReadMemory (Address, &Value, sizeof Value, &BytesRead) == FALSE) {
  1105. dprintf ("Cannot read value @ %p. \n", Address);
  1106. return 0;
  1107. }
  1108. else {
  1109. return Value;
  1110. }
  1111. }
  1112. VOID
  1113. WriteULONG (
  1114. ULONG64 Address,
  1115. ULONG Value
  1116. )
  1117. {
  1118. ULONG BytesWritten;
  1119. if (WriteMemory (Address, &Value, sizeof Value, &BytesWritten) == FALSE) {
  1120. dprintf ("Cannot write value @ %p. \n", Address);
  1121. }
  1122. }
  1123. VOID
  1124. WritePVOID (
  1125. ULONG64 Address,
  1126. ULONG64 Value
  1127. )
  1128. {
  1129. ULONG BytesWritten;
  1130. if (IsPtr64()) {
  1131. if (WriteMemory (Address, &Value, 8, &BytesWritten) == FALSE) {
  1132. dprintf ("Cannot write pointer @ %p. \n", Address);
  1133. }
  1134. }
  1135. else {
  1136. if (WriteMemory (Address, &Value, 4, &BytesWritten) == FALSE) {
  1137. dprintf ("Cannot write pointer @ %p. \n", Address);
  1138. }
  1139. }
  1140. }
  1141. ULONG64
  1142. ReadPVOID (
  1143. ULONG64 Address
  1144. )
  1145. {
  1146. ULONG BytesRead;
  1147. if (IsPtr64()) {
  1148. ULONG64 Value;
  1149. if (ReadMemory (Address, &Value, sizeof Value, &BytesRead) == FALSE) {
  1150. dprintf ("Cannot read pointer @ %p. \n", Address);
  1151. return 0;
  1152. }
  1153. else {
  1154. return (ULONG64)Value;
  1155. }
  1156. }
  1157. else {
  1158. ULONG Value;
  1159. if (ReadMemory (Address, &Value, sizeof Value, &BytesRead) == FALSE) {
  1160. dprintf ("Cannot read pointer @ %p. \n", Address);
  1161. return 0;
  1162. }
  1163. else {
  1164. return (ULONG64)Value;
  1165. }
  1166. }
  1167. }
  1168. //
  1169. // Definitions from \nt\base\win32\verifier\support.h
  1170. //
  1171. #define CNT_WAIT_SINGLE_CALLS 0
  1172. #define CNT_WAIT_SINGLEEX_CALLS 1
  1173. #define CNT_WAIT_MULTIPLE_CALLS 2
  1174. #define CNT_WAIT_MULTIPLEEX_CALLS 3
  1175. #define CNT_WAIT_WITH_TIMEOUT_CALLS 4
  1176. #define CNT_WAIT_WITH_TIMEOUT_FAILS 5
  1177. #define CNT_CREATE_EVENT_CALLS 6
  1178. #define CNT_CREATE_EVENT_FAILS 7
  1179. #define CNT_HEAP_ALLOC_CALLS 8
  1180. #define CNT_HEAP_ALLOC_FAILS 9
  1181. #define CNT_CLOSE_NULL_HANDLE_CALLS 10
  1182. #define CNT_CLOSE_PSEUDO_HANDLE_CALLS 11
  1183. #define CNT_HEAPS_CREATED 12
  1184. #define CNT_HEAPS_DESTROYED 13
  1185. #define CNT_VIRTUAL_ALLOC_CALLS 14
  1186. #define CNT_VIRTUAL_ALLOC_FAILS 15
  1187. #define CNT_MAP_VIEW_CALLS 16
  1188. #define CNT_MAP_VIEW_FAILS 17
  1189. #define CNT_OLE_ALLOC_CALLS 18
  1190. #define CNT_OLE_ALLOC_FAILS 19
  1191. VOID
  1192. VrfDumpGlobalCounters (
  1193. VOID
  1194. )
  1195. {
  1196. ULONG64 Address;
  1197. ULONG TypeSize;
  1198. ULONG Value;
  1199. Address = GetExpression("verifier!AVrfpCounter");
  1200. TypeSize = sizeof (ULONG);
  1201. Value = ReadULONG (Address + TypeSize * CNT_WAIT_SINGLE_CALLS);
  1202. dprintf ("WaitForSingleObject calls: %X \n", Value);
  1203. Value = ReadULONG (Address + TypeSize * CNT_WAIT_SINGLEEX_CALLS);
  1204. dprintf ("WaitForSingleObjectEx calls: %X \n", Value);
  1205. Value = ReadULONG (Address + TypeSize * CNT_WAIT_MULTIPLE_CALLS);
  1206. dprintf ("WaitForMultipleObjects calls %X \n", Value);
  1207. Value = ReadULONG (Address + TypeSize * CNT_WAIT_MULTIPLEEX_CALLS);
  1208. dprintf ("WaitForMultipleObjectsEx calls: %X \n", Value);
  1209. Value = ReadULONG (Address + TypeSize * CNT_WAIT_WITH_TIMEOUT_CALLS);
  1210. dprintf ("Waits with timeout calls: %X \n", Value);
  1211. Value = ReadULONG (Address + TypeSize * CNT_WAIT_WITH_TIMEOUT_FAILS);
  1212. dprintf ("Waits with timeout failed: %X \n", Value);
  1213. Value = ReadULONG (Address + TypeSize * CNT_CREATE_EVENT_CALLS);
  1214. dprintf ("CreateEvent calls: %X \n", Value);
  1215. Value = ReadULONG (Address + TypeSize * CNT_CREATE_EVENT_FAILS);
  1216. dprintf ("CreateEvent calls failed: %X \n", Value);
  1217. Value = ReadULONG (Address + TypeSize * CNT_HEAP_ALLOC_CALLS);
  1218. dprintf ("Heap allocation calls: %X \n", Value);
  1219. Value = ReadULONG (Address + TypeSize * CNT_HEAP_ALLOC_FAILS);
  1220. dprintf ("Heap allocations failed: %X \n", Value);
  1221. Value = ReadULONG (Address + TypeSize * CNT_CLOSE_NULL_HANDLE_CALLS);
  1222. dprintf ("CloseHandle called with null handle: %X \n", Value);
  1223. Value = ReadULONG (Address + TypeSize * CNT_CLOSE_PSEUDO_HANDLE_CALLS);
  1224. dprintf ("CloseHandle called with pseudo handle: %X \n", Value);
  1225. Value = ReadULONG (Address + TypeSize * CNT_HEAPS_CREATED);
  1226. dprintf ("Heaps created: %X \n", Value);
  1227. Value = ReadULONG (Address + TypeSize * CNT_HEAPS_DESTROYED);
  1228. dprintf ("Heaps destroyed: %X \n", Value);
  1229. Value = ReadULONG (Address + TypeSize * CNT_VIRTUAL_ALLOC_CALLS);
  1230. dprintf ("Virtual allocation calls: %X \n", Value);
  1231. Value = ReadULONG (Address + TypeSize * CNT_VIRTUAL_ALLOC_FAILS);
  1232. dprintf ("Virtual allocations failed: %X \n", Value);
  1233. Value = ReadULONG (Address + TypeSize * CNT_MAP_VIEW_CALLS);
  1234. dprintf ("Map view calls: %X \n", Value);
  1235. Value = ReadULONG (Address + TypeSize * CNT_MAP_VIEW_FAILS);
  1236. dprintf ("Map views failed: %X \n", Value);
  1237. Value = ReadULONG (Address + TypeSize * CNT_OLE_ALLOC_CALLS);
  1238. dprintf ("OLE string allocation calls: %X \n", Value);
  1239. Value = ReadULONG (Address + TypeSize * CNT_OLE_ALLOC_FAILS);
  1240. dprintf ("OLE string allocations failed: %X \n", Value);
  1241. }
  1242. //
  1243. // Definitions from \nt\base\win32\verifier\support.h
  1244. //
  1245. #define BRK_CLOSE_NULL_HANDLE 0
  1246. #define BRK_CLOSE_PSEUDO_HANDLE 1
  1247. #define BRK_CREATE_EVENT_FAIL 2
  1248. #define BRK_HEAP_ALLOC_FAIL 3
  1249. #define BRK_WAIT_WITH_TIMEOUT_FAIL 4
  1250. #define BRK_VIRTUAL_ALLOC_FAIL 5
  1251. #define BRK_MAP_VIEW_FAIL 6
  1252. #define BRK_CREATE_FILE_FAIL 7
  1253. #define BRK_CREATE_KEY_FAIL 8
  1254. #define BRK_OLE_ALLOC_FAIL 9
  1255. #define BRK_MAXIMUM_INDEX 64
  1256. VOID
  1257. VrfDumpBreakTriggers (
  1258. VOID
  1259. )
  1260. {
  1261. ULONG64 Address;
  1262. ULONG TypeSize;
  1263. ULONG Value;
  1264. Address = GetExpression("verifier!AVrfpBreak");
  1265. TypeSize = sizeof (ULONG);
  1266. Value = ReadULONG (Address + TypeSize * BRK_CLOSE_NULL_HANDLE);
  1267. dprintf ("%03X : Break for closing null handle: %X \n",
  1268. BRK_CLOSE_NULL_HANDLE,
  1269. Value);
  1270. Value = ReadULONG (Address + TypeSize * BRK_CLOSE_PSEUDO_HANDLE);
  1271. dprintf ("%03X : Break for closing pseudo handle: %X \n",
  1272. BRK_CLOSE_PSEUDO_HANDLE,
  1273. Value);
  1274. Value = ReadULONG (Address + TypeSize * BRK_CREATE_EVENT_FAIL);
  1275. dprintf ("%03X : Break for failing CreateEvent: %X \n",
  1276. BRK_CREATE_EVENT_FAIL,
  1277. Value);
  1278. Value = ReadULONG (Address + TypeSize * BRK_HEAP_ALLOC_FAIL);
  1279. dprintf ("%03X : Break for failing heap allocation: %X \n",
  1280. BRK_HEAP_ALLOC_FAIL,
  1281. Value);
  1282. Value = ReadULONG (Address + TypeSize * BRK_WAIT_WITH_TIMEOUT_FAIL);
  1283. dprintf ("%03X : Break for failing a wait with timeout: %X \n",
  1284. BRK_WAIT_WITH_TIMEOUT_FAIL,
  1285. Value);
  1286. Value = ReadULONG (Address + TypeSize * BRK_VIRTUAL_ALLOC_FAIL);
  1287. dprintf ("%03X : Break for failing virtual allocation: %X \n",
  1288. BRK_VIRTUAL_ALLOC_FAIL,
  1289. Value);
  1290. Value = ReadULONG (Address + TypeSize * BRK_MAP_VIEW_FAIL);
  1291. dprintf ("%03X : Break for failing map view operations: %X \n",
  1292. BRK_MAP_VIEW_FAIL,
  1293. Value);
  1294. Value = ReadULONG (Address + TypeSize * BRK_CREATE_FILE_FAIL);
  1295. dprintf ("%03X : Break for failing create/open file operations: %X \n",
  1296. BRK_CREATE_FILE_FAIL,
  1297. Value);
  1298. Value = ReadULONG (Address + TypeSize * BRK_CREATE_KEY_FAIL);
  1299. dprintf ("%03X : Break for failing registry create/open key operations: %X \n",
  1300. BRK_CREATE_KEY_FAIL,
  1301. Value);
  1302. Value = ReadULONG (Address + TypeSize * BRK_OLE_ALLOC_FAIL);
  1303. dprintf ("%03X : Break for failing OLE string allocations: %X \n",
  1304. BRK_OLE_ALLOC_FAIL,
  1305. Value);
  1306. }
  1307. VOID
  1308. VrfToggleBreakTrigger (
  1309. ULONG Index
  1310. )
  1311. {
  1312. ULONG64 Address;
  1313. ULONG TypeSize;
  1314. ULONG Value;
  1315. if (Index > BRK_MAXIMUM_INDEX) {
  1316. dprintf ("Index %X is out of range (0..%X) \n",
  1317. Index,
  1318. BRK_MAXIMUM_INDEX);
  1319. return;
  1320. }
  1321. Address = GetExpression("verifier!AVrfpBreak");
  1322. TypeSize = sizeof (ULONG);
  1323. Value = ReadULONG (Address + TypeSize * Index);
  1324. if (Value == 0) {
  1325. WriteULONG (Address + TypeSize * Index, 1);
  1326. dprintf ("Break trigger %X is now enabled.\n", Index);
  1327. }
  1328. else {
  1329. WriteULONG (Address + TypeSize * Index, 0);
  1330. dprintf ("Break trigger %X is now disabled.\n", Index);
  1331. }
  1332. }
  1333. //
  1334. // Definitions from \nt\base\win32\verifier\faults.h
  1335. //
  1336. #define CLS_WAIT_APIS 0
  1337. #define CLS_HEAP_ALLOC_APIS 1
  1338. #define CLS_VIRTUAL_ALLOC_APIS 2
  1339. #define CLS_REGISTRY_APIS 3
  1340. #define CLS_FILE_APIS 4
  1341. #define CLS_EVENT_APIS 5
  1342. #define CLS_MAP_VIEW_APIS 6
  1343. #define CLS_OLE_ALLOC_APIS 7
  1344. #define CLS_MAXIMUM_INDEX 16
  1345. VOID
  1346. VrfDumpFaultInjectionSettings (
  1347. VOID
  1348. )
  1349. {
  1350. ULONG64 Address;
  1351. ULONG64 BreakAddress;
  1352. ULONG64 TrueAddress;
  1353. ULONG64 FalseAddress;
  1354. ULONG TypeSize;
  1355. ULONG Value;
  1356. ULONG BreakValue;
  1357. ULONG SuccessValue;
  1358. ULONG FailValue;
  1359. dprintf ("Fault injection settings: Probability (break, success/failed) \n"
  1360. "==============================================\n");
  1361. Address = GetExpression("verifier!AVrfpFaultProbability");
  1362. BreakAddress = GetExpression("verifier!AVrfpFaultBreak");
  1363. TrueAddress = GetExpression("verifier!AVrfpFaultTrue");
  1364. FalseAddress = GetExpression("verifier!AVrfpFaultFalse");
  1365. TypeSize = sizeof (ULONG);
  1366. Value = ReadULONG (Address + TypeSize * CLS_WAIT_APIS);
  1367. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_WAIT_APIS);
  1368. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_WAIT_APIS);
  1369. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_WAIT_APIS);
  1370. dprintf ("%03X : Wait APIs: %02X (%X, %X / %X)\n",
  1371. CLS_WAIT_APIS,
  1372. Value,
  1373. BreakValue,
  1374. SuccessValue,
  1375. FailValue);
  1376. Value = ReadULONG (Address + TypeSize * CLS_HEAP_ALLOC_APIS);
  1377. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_HEAP_ALLOC_APIS);
  1378. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_HEAP_ALLOC_APIS);
  1379. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_HEAP_ALLOC_APIS);
  1380. dprintf ("%03X : Heap allocations: %02X (%X, %X / %X)\n",
  1381. CLS_HEAP_ALLOC_APIS,
  1382. Value,
  1383. BreakValue,
  1384. SuccessValue,
  1385. FailValue);
  1386. Value = ReadULONG (Address + TypeSize * CLS_VIRTUAL_ALLOC_APIS);
  1387. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_VIRTUAL_ALLOC_APIS);
  1388. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_VIRTUAL_ALLOC_APIS);
  1389. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_VIRTUAL_ALLOC_APIS);
  1390. dprintf ("%03X : Virtual space allocations: %02X (%X, %X / %X)\n",
  1391. CLS_VIRTUAL_ALLOC_APIS,
  1392. Value,
  1393. BreakValue,
  1394. SuccessValue,
  1395. FailValue);
  1396. Value = ReadULONG (Address + TypeSize * CLS_REGISTRY_APIS);
  1397. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_REGISTRY_APIS);
  1398. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_REGISTRY_APIS);
  1399. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_REGISTRY_APIS);
  1400. dprintf ("%03X : Registry APIs: %02X (%X, %X / %X)\n",
  1401. CLS_REGISTRY_APIS,
  1402. Value,
  1403. BreakValue,
  1404. SuccessValue,
  1405. FailValue);
  1406. Value = ReadULONG (Address + TypeSize * CLS_FILE_APIS);
  1407. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_FILE_APIS);
  1408. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_FILE_APIS);
  1409. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_FILE_APIS);
  1410. dprintf ("%03X : File APIs: %02X (%X, %X / %X)\n",
  1411. CLS_FILE_APIS,
  1412. Value,
  1413. BreakValue,
  1414. SuccessValue,
  1415. FailValue);
  1416. Value = ReadULONG (Address + TypeSize * CLS_EVENT_APIS);
  1417. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_EVENT_APIS);
  1418. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_EVENT_APIS);
  1419. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_EVENT_APIS);
  1420. dprintf ("%03X : Event APIs: %02X (%X, %X / %X)\n",
  1421. CLS_EVENT_APIS,
  1422. Value,
  1423. BreakValue,
  1424. SuccessValue,
  1425. FailValue);
  1426. Value = ReadULONG (Address + TypeSize * CLS_MAP_VIEW_APIS);
  1427. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_MAP_VIEW_APIS);
  1428. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_MAP_VIEW_APIS);
  1429. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_MAP_VIEW_APIS);
  1430. dprintf ("%03X : Map view operations: %02X (%X, %X / %X)\n",
  1431. CLS_MAP_VIEW_APIS,
  1432. Value,
  1433. BreakValue,
  1434. SuccessValue,
  1435. FailValue);
  1436. Value = ReadULONG (Address + TypeSize * CLS_OLE_ALLOC_APIS);
  1437. BreakValue = ReadULONG (BreakAddress + TypeSize * CLS_OLE_ALLOC_APIS);
  1438. SuccessValue = ReadULONG (FalseAddress + TypeSize * CLS_OLE_ALLOC_APIS);
  1439. FailValue = ReadULONG (TrueAddress + TypeSize * CLS_OLE_ALLOC_APIS);
  1440. dprintf ("%03X : OLE string allocations: %02X (%X, %X / %X)\n",
  1441. CLS_OLE_ALLOC_APIS,
  1442. Value,
  1443. BreakValue,
  1444. SuccessValue,
  1445. FailValue);
  1446. }
  1447. VOID
  1448. VrfSetFaultInjectionParameters (
  1449. ULONG Index,
  1450. ULONG Probability
  1451. )
  1452. {
  1453. ULONG64 Address;
  1454. ULONG TypeSize;
  1455. ULONG Value;
  1456. if (Index > CLS_MAXIMUM_INDEX) {
  1457. dprintf ("Index %X is out of range (0..%X) \n",
  1458. Index,
  1459. CLS_MAXIMUM_INDEX);
  1460. return;
  1461. }
  1462. if (Probability > 100) {
  1463. dprintf ("Probability %X is out of range (0..%X) \n",
  1464. Probability,
  1465. 100);
  1466. return;
  1467. }
  1468. Address = GetExpression("verifier!AVrfpFaultProbability");
  1469. TypeSize = sizeof (ULONG);
  1470. WriteULONG (Address + TypeSize * Index, Probability);
  1471. dprintf ("Probability for event %X is now set to %X.\n",
  1472. Index,
  1473. Probability);
  1474. }
  1475. VOID
  1476. VrfToggleFaultInjectionBreak (
  1477. ULONG Index
  1478. )
  1479. {
  1480. ULONG64 Address;
  1481. ULONG TypeSize;
  1482. ULONG Value;
  1483. if (Index > CLS_MAXIMUM_INDEX) {
  1484. dprintf ("Index %X is out of range (0..%X) \n",
  1485. Index,
  1486. CLS_MAXIMUM_INDEX);
  1487. return;
  1488. }
  1489. Address = GetExpression("verifier!AVrfpFaultBreak");
  1490. TypeSize = sizeof (ULONG);
  1491. Value = ReadULONG (Address + TypeSize * Index);
  1492. if (Value == 0) {
  1493. WriteULONG (Address + TypeSize * Index, 1);
  1494. dprintf ("Will break for fault injection event %X.\n", Index);
  1495. }
  1496. else {
  1497. WriteULONG (Address + TypeSize * Index, 0);
  1498. dprintf ("Will not break for fault injection event %X.\n", Index);
  1499. }
  1500. }
  1501. /////////////////////////////////////////////////////////////////////
  1502. /////////////////////////////////////////////////////////////////////
  1503. /////////////////////////////////////////////////////////////////////
  1504. VOID
  1505. VrfDumpFaultInjectionTargetRanges (
  1506. VOID
  1507. )
  1508. {
  1509. ULONG64 StartAddress, EndAddress;
  1510. ULONG64 HitsAddress;
  1511. ULONG64 IndexAddress;
  1512. ULONG TypeSize;
  1513. ULONG64 Start, End;
  1514. ULONG MaximumIndex;
  1515. ULONG Index;
  1516. ULONG RangeCount = 0;
  1517. ULONG Hits;
  1518. dprintf ("Fault injection target ranges (START END HITS): \n"
  1519. "============================================================\n");
  1520. IndexAddress = GetExpression("verifier!AVrfpFaultTargetMaximumIndex");
  1521. StartAddress = GetExpression("verifier!AVrfpFaultTargetStart");
  1522. EndAddress = GetExpression("verifier!AVrfpFaultTargetEnd");
  1523. HitsAddress = GetExpression("verifier!AVrfpFaultTargetHits");
  1524. TypeSize = IsPtr64() ? 8 : 4;
  1525. MaximumIndex = ReadULONG (IndexAddress);
  1526. for (Index = 0; Index < MaximumIndex; Index += 1) {
  1527. ReadPointer (StartAddress + TypeSize * Index, &Start);
  1528. ReadPointer (EndAddress + TypeSize * Index, &End);
  1529. Hits = ReadULONG (HitsAddress + sizeof(ULONG) * Index);
  1530. if (Start == 0 && End == 0) {
  1531. continue;
  1532. }
  1533. dprintf ("%016I64X %016I64X %X\n", Start, End, Hits);
  1534. RangeCount += 1;
  1535. }
  1536. if (RangeCount == 0) {
  1537. dprintf ("No fault injection target ranges are active. \n");
  1538. }
  1539. }
  1540. VOID
  1541. VrfAddFaultInjectionTargetRange (
  1542. ULONG64 TargetStart,
  1543. ULONG64 TargetEnd
  1544. )
  1545. {
  1546. ULONG64 StartAddress, EndAddress;
  1547. ULONG64 HitsAddress;
  1548. ULONG64 IndexAddress;
  1549. ULONG TypeSize;
  1550. ULONG64 Start, End;
  1551. ULONG MaximumIndex;
  1552. ULONG Index;
  1553. ULONG Hits;
  1554. IndexAddress = GetExpression("verifier!AVrfpFaultTargetMaximumIndex");
  1555. StartAddress = GetExpression("verifier!AVrfpFaultTargetStart");
  1556. EndAddress = GetExpression("verifier!AVrfpFaultTargetEnd");
  1557. HitsAddress = GetExpression("verifier!AVrfpFaultTargetHits");
  1558. TypeSize = IsPtr64() ? 8 : 4;
  1559. MaximumIndex = ReadULONG (IndexAddress);
  1560. for (Index = 0; Index < MaximumIndex; Index += 1) {
  1561. ReadPointer (StartAddress + TypeSize * Index, &Start);
  1562. ReadPointer (EndAddress + TypeSize * Index, &End);
  1563. if (Start == 0) {
  1564. break;
  1565. }
  1566. }
  1567. if (Index < MaximumIndex) {
  1568. WritePVOID (StartAddress + TypeSize * Index, TargetStart);
  1569. WritePVOID (EndAddress + TypeSize * Index, TargetEnd);
  1570. WriteULONG (HitsAddress + sizeof(ULONG) * Index, 0);
  1571. dprintf ("Target range %I64X - %I64X activated. \n",
  1572. TargetStart,
  1573. TargetEnd);
  1574. }
  1575. else {
  1576. dprintf ("No more space for additional fault target range. \n");
  1577. }
  1578. }
  1579. VOID
  1580. VrfResetFaultInjectionTargetRanges (
  1581. VOID
  1582. )
  1583. {
  1584. ULONG64 StartAddress, EndAddress;
  1585. ULONG64 HitsAddress;
  1586. ULONG64 IndexAddress;
  1587. ULONG TypeSize;
  1588. ULONG64 Start, End;
  1589. ULONG MaximumIndex;
  1590. ULONG Index;
  1591. ULONG Hits;
  1592. IndexAddress = GetExpression("verifier!AVrfpFaultTargetMaximumIndex");
  1593. StartAddress = GetExpression("verifier!AVrfpFaultTargetStart");
  1594. EndAddress = GetExpression("verifier!AVrfpFaultTargetEnd");
  1595. HitsAddress = GetExpression("verifier!AVrfpFaultTargetHits");
  1596. TypeSize = IsPtr64() ? 8 : 4;
  1597. MaximumIndex = ReadULONG (IndexAddress);
  1598. for (Index = 0; Index < MaximumIndex; Index += 1) {
  1599. WritePVOID (StartAddress + TypeSize * Index, 0);
  1600. WriteULONG (HitsAddress + sizeof(ULONG) * Index, 0);
  1601. if (Index == 0) {
  1602. WritePVOID (EndAddress + TypeSize * Index, ~((ULONG64)0));
  1603. }
  1604. else {
  1605. WritePVOID (EndAddress + TypeSize * Index, 0);
  1606. }
  1607. }
  1608. dprintf ("Target ranges have been reset. \n");
  1609. }
  1610. /////////////////////////////////////////////////////////////////////
  1611. /////////////////////////////////////////////////////////////////////
  1612. /////////////////////////////////////////////////////////////////////
  1613. VOID
  1614. VrfDumpFaultInjectionExclusionRanges (
  1615. VOID
  1616. )
  1617. {
  1618. ULONG64 StartAddress, EndAddress;
  1619. ULONG64 HitsAddress;
  1620. ULONG64 TimeAddress;
  1621. ULONG64 IndexAddress;
  1622. ULONG TypeSize;
  1623. ULONG64 Start, End;
  1624. ULONG MaximumIndex;
  1625. ULONG Index;
  1626. ULONG RangeCount = 0;
  1627. ULONG Hits;
  1628. ULONG TimeInMsecs;
  1629. dprintf ("Fault injection exclusion ranges (START END HITS): \n"
  1630. "============================================================\n");
  1631. IndexAddress = GetExpression("verifier!AVrfpFaultExclusionMaximumIndex");
  1632. StartAddress = GetExpression("verifier!AVrfpFaultExclusionStart");
  1633. EndAddress = GetExpression("verifier!AVrfpFaultExclusionEnd");
  1634. HitsAddress = GetExpression("verifier!AVrfpFaultExclusionHits");
  1635. TimeAddress = GetExpression("verifier!AVrfpFaultPeriodTimeInMsecs");
  1636. TypeSize = IsPtr64() ? 8 : 4;
  1637. MaximumIndex = ReadULONG (IndexAddress);
  1638. TimeInMsecs = ReadULONG (TimeAddress);
  1639. for (Index = 0; Index < MaximumIndex; Index += 1) {
  1640. ReadPointer (StartAddress + TypeSize * Index, &Start);
  1641. ReadPointer (EndAddress + TypeSize * Index, &End);
  1642. Hits = ReadULONG (HitsAddress + sizeof(ULONG) * Index);
  1643. if (Start == 0 && End == 0) {
  1644. continue;
  1645. }
  1646. dprintf ("%016I64X %016I64X %X\n", Start, End, Hits);
  1647. RangeCount += 1;
  1648. }
  1649. if (RangeCount == 0) {
  1650. dprintf ("No fault injection exclusion ranges are active. \n");
  1651. }
  1652. if (TimeInMsecs) {
  1653. dprintf ("\nFault injection disabled for the next 0x%X msecs. \n", TimeInMsecs);
  1654. }
  1655. }
  1656. VOID
  1657. VrfAddFaultInjectionExclusionRange (
  1658. ULONG64 TargetStart,
  1659. ULONG64 TargetEnd
  1660. )
  1661. {
  1662. ULONG64 StartAddress, EndAddress;
  1663. ULONG64 HitsAddress;
  1664. ULONG64 IndexAddress;
  1665. ULONG TypeSize;
  1666. ULONG64 Start, End;
  1667. ULONG MaximumIndex;
  1668. ULONG Index;
  1669. ULONG Hits;
  1670. IndexAddress = GetExpression("verifier!AVrfpFaultExclusionMaximumIndex");
  1671. StartAddress = GetExpression("verifier!AVrfpFaultExclusionStart");
  1672. EndAddress = GetExpression("verifier!AVrfpFaultExclusionEnd");
  1673. HitsAddress = GetExpression("verifier!AVrfpFaultExclusionHits");
  1674. TypeSize = IsPtr64() ? 8 : 4;
  1675. MaximumIndex = ReadULONG (IndexAddress);
  1676. for (Index = 0; Index < MaximumIndex; Index += 1) {
  1677. ReadPointer (StartAddress + TypeSize * Index, &Start);
  1678. ReadPointer (EndAddress + TypeSize * Index, &End);
  1679. if (Start == 0) {
  1680. break;
  1681. }
  1682. }
  1683. if (Index < MaximumIndex) {
  1684. WritePVOID (StartAddress + TypeSize * Index, TargetStart);
  1685. WritePVOID (EndAddress + TypeSize * Index, TargetEnd);
  1686. WriteULONG (HitsAddress + sizeof(ULONG) * Index, 0);
  1687. dprintf ("Exclusion range %I64X - %I64X activated. \n",
  1688. TargetStart,
  1689. TargetEnd);
  1690. }
  1691. else {
  1692. dprintf ("No more space for additional fault exclusion range. \n");
  1693. }
  1694. }
  1695. VOID
  1696. VrfResetFaultInjectionExclusionRanges (
  1697. VOID
  1698. )
  1699. {
  1700. ULONG64 StartAddress, EndAddress;
  1701. ULONG64 TimeAddress;
  1702. ULONG64 HitsAddress;
  1703. ULONG64 IndexAddress;
  1704. ULONG TypeSize;
  1705. ULONG64 Start, End;
  1706. ULONG MaximumIndex;
  1707. ULONG Index;
  1708. ULONG Hits;
  1709. IndexAddress = GetExpression("verifier!AVrfpFaultExclusionMaximumIndex");
  1710. StartAddress = GetExpression("verifier!AVrfpFaultExclusionStart");
  1711. EndAddress = GetExpression("verifier!AVrfpFaultExclusionEnd");
  1712. HitsAddress = GetExpression("verifier!AVrfpFaultExclusionHits");
  1713. TimeAddress = GetExpression("verifier!AVrfpFaultPeriodTimeInMsecs");
  1714. TypeSize = IsPtr64() ? 8 : 4;
  1715. MaximumIndex = ReadULONG (IndexAddress);
  1716. for (Index = 0; Index < MaximumIndex; Index += 1) {
  1717. WritePVOID (StartAddress + TypeSize * Index, 0);
  1718. WritePVOID (EndAddress + TypeSize * Index, 0);
  1719. WriteULONG (HitsAddress + sizeof(ULONG) * Index, 0);
  1720. }
  1721. WriteULONG (TimeAddress, 0);
  1722. dprintf ("Exclusion ranges have been reset. \n");
  1723. }
  1724. VOID
  1725. VrfSetFaultInjectionExclusionPeriod (
  1726. ULONG64 TimeInMsecs
  1727. )
  1728. {
  1729. ULONG64 TimeAddress;
  1730. ULONG64 HitsAddress;
  1731. ULONG64 IndexAddress;
  1732. ULONG TypeSize;
  1733. ULONG64 Start, End;
  1734. ULONG MaximumIndex;
  1735. ULONG Index;
  1736. ULONG Hits;
  1737. TimeAddress = GetExpression("verifier!AVrfpFaultPeriodTimeInMsecs");
  1738. TypeSize = IsPtr64() ? 8 : 4;
  1739. WriteULONG (TimeAddress, (ULONG)TimeInMsecs);
  1740. dprintf ("Fault injection disabled for the next 0x%I64X msecs. \n", TimeInMsecs);
  1741. }
  1742. VOID
  1743. VrfDumpFaultInjectionTraces (
  1744. ULONG Count
  1745. )
  1746. {
  1747. ULONG64 TraceAddress;
  1748. ULONG64 IndexAddress;
  1749. ULONG64 Address;
  1750. ULONG Index;
  1751. ULONG MaxIndex;
  1752. ULONG TraceSize;
  1753. ULONG TypeSize;
  1754. ULONG I;
  1755. TraceAddress = GetExpression ("verifier!AVrfpFaultTrace");
  1756. Address = GetExpression ("verifier!AVrfpFaultTraceIndex");
  1757. Index = ReadULONG(Address);
  1758. Address = GetExpression ("verifier!AVrfpFaultNumberOfTraces");
  1759. MaxIndex = ReadULONG(Address);
  1760. Address = GetExpression ("verifier!AVrfpFaultTraceSize");
  1761. TraceSize = ReadULONG(Address);
  1762. TypeSize = IsPtr64() ? 8 : 4;
  1763. if (Count > MaxIndex) {
  1764. Count = MaxIndex;
  1765. }
  1766. //
  1767. // Bring Index within stack trace database limits.
  1768. //
  1769. Index = Index % MaxIndex;
  1770. while (Count > 0) {
  1771. dprintf ("- - - - - - - - - - - - - - - - - - - - - - - - - \n");
  1772. for (I = 0; I < TraceSize; I += 1) {
  1773. CHAR SymbolName[ 1024 ];
  1774. ULONG64 Displacement;
  1775. ULONG64 ReturnAddress;
  1776. ReadPointer (TraceAddress + TypeSize * TraceSize * Index + TypeSize * I,
  1777. &ReturnAddress);
  1778. if (ReturnAddress == 0) {
  1779. break;
  1780. }
  1781. GetSymbol (ReturnAddress, SymbolName, &Displacement);
  1782. dprintf (" %p %s+0x%p\n",
  1783. ReturnAddress,
  1784. SymbolName,
  1785. Displacement);
  1786. }
  1787. Index = (Index - 1) % MaxIndex;
  1788. Count -= 1;
  1789. }
  1790. }
  1791. PWSTR
  1792. ReadUnicodeString (
  1793. ULONG64 Address,
  1794. PWSTR Buffer,
  1795. ULONG BufferSizeInBytes
  1796. )
  1797. {
  1798. ULONG BytesRead;
  1799. ULONG Offset;
  1800. LOGICAL Result;
  1801. InitTypeRead (Address, ntdll!_UNICODE_STRING);
  1802. Result = ReadMemory (ReadField(Buffer),
  1803. Buffer,
  1804. BufferSizeInBytes,
  1805. &BytesRead);
  1806. if (Result == FALSE) {
  1807. dprintf ("Cannot read UNICODE string @ %p. \n", Address);
  1808. return NULL;
  1809. }
  1810. else {
  1811. Buffer[BufferSizeInBytes - 1] = 0;
  1812. return Buffer;
  1813. }
  1814. }
  1815. CHAR DllNameInChars [256];
  1816. WCHAR DllNameInWChars [256];
  1817. VOID
  1818. VrfSetFaultInjectionDllTarget (
  1819. PCHAR DllName,
  1820. LOGICAL Exclude
  1821. )
  1822. {
  1823. ULONG64 PebAddress;
  1824. ULONG64 LdrAddress;
  1825. ULONG Offset;
  1826. ULONG64 ListStart;
  1827. ULONG64 ListEntry;
  1828. ULONG NameOffset;
  1829. PebAddress = VrfPebAddress ();
  1830. InitTypeRead (PebAddress, ntdll!_PEB);
  1831. LdrAddress = ReadField (Ldr);
  1832. InitTypeRead (LdrAddress, ntdll!_PEB_LDR_DATA);
  1833. GetFieldOffset ("ntdll!_PEB_LDR_DATA",
  1834. "InLoadOrderModuleList",
  1835. &Offset);
  1836. ListStart = LdrAddress + Offset;
  1837. ReadPointer(ListStart, &ListEntry);
  1838. while (ListEntry != ListStart) {
  1839. GetFieldOffset ("ntdll!_LDR_DATA_TABLE_ENTRY",
  1840. "InLoadOrderLinks",
  1841. &Offset);
  1842. LdrAddress = ListEntry - Offset;
  1843. GetFieldOffset ("ntdll!_LDR_DATA_TABLE_ENTRY",
  1844. "BaseDllName",
  1845. &NameOffset);
  1846. ReadUnicodeString (LdrAddress + NameOffset,
  1847. DllNameInWChars,
  1848. sizeof DllNameInWChars);
  1849. //
  1850. // Convert from WCHAR* to CHAR* the dll name.
  1851. //
  1852. {
  1853. PCHAR Src;
  1854. ULONG Ti;
  1855. Src = (PCHAR)DllNameInWChars;
  1856. Ti = 0;
  1857. while (*Src) {
  1858. if (Ti > 254) {
  1859. break;
  1860. }
  1861. DllNameInChars[Ti] = *Src;
  1862. Src += sizeof(WCHAR);
  1863. Ti += 1;
  1864. }
  1865. DllNameInChars[Ti] = 0;
  1866. }
  1867. if (_stricmp (DllName, DllNameInChars) == 0) {
  1868. InitTypeRead (LdrAddress, ntdll!_LDR_DATA_TABLE_ENTRY);
  1869. if (Exclude) {
  1870. VrfAddFaultInjectionExclusionRange (ReadField (DllBase),
  1871. ReadField (DllBase) + ReadField (SizeOfImage));
  1872. }
  1873. else {
  1874. VrfAddFaultInjectionTargetRange (ReadField (DllBase),
  1875. ReadField (DllBase) + ReadField (SizeOfImage));
  1876. }
  1877. break;
  1878. }
  1879. ReadPointer(ListEntry, &ListEntry);
  1880. }
  1881. }
  1882. /////////////////////////////////////////////////////////////////////
  1883. /////////////////////////////////////////////////////////////////////
  1884. /////////////////////////////////////////////////////////////////////
  1885. VOID
  1886. VrfDumpExceptionLog (
  1887. ULONG MaxEntries
  1888. )
  1889. {
  1890. ULONG64 TempAddress;
  1891. ULONG64 ExceptionLogAddress;
  1892. ULONG64 CurrentLogEntryAddress;
  1893. ULONG64 Value;
  1894. ULONG ExceptionLogEntriesNo;
  1895. ULONG CurrentLogIndex;
  1896. ULONG BytesRead;
  1897. ULONG LogEntrySize;
  1898. ULONG LogEntry;
  1899. ULONG EntriedDumped = 0;
  1900. //
  1901. // Read the start of the exception log database.
  1902. //
  1903. ExceptionLogAddress = GetExpression ("&verifier!AVrfpExceptionLog");
  1904. if (ExceptionLogAddress == 0 ) {
  1905. dprintf ("No exception information available (unable to resolve verifier!AVrfpExceptionLog)\n");
  1906. return;
  1907. }
  1908. if (!ReadPointer (ExceptionLogAddress, &ExceptionLogAddress) != S_OK) {
  1909. dprintf ("No exception information available (cannot read pointer from address %p)\n",
  1910. ExceptionLogAddress);
  1911. return;
  1912. }
  1913. //
  1914. // Read the number of entries in the exception log database.
  1915. //
  1916. TempAddress = GetExpression ("&verifier!AVrfpExceptionLogEntriesNo");
  1917. if (TempAddress == 0 ) {
  1918. dprintf ("No exception information available (unable to resolve verifier!AVrfpExceptionLogEntriesNo)\n");
  1919. return;
  1920. }
  1921. ExceptionLogEntriesNo = ReadULONG(TempAddress);
  1922. if (ExceptionLogEntriesNo <= 1) {
  1923. return;
  1924. }
  1925. //
  1926. // Read the current index in the exception log database.
  1927. //
  1928. TempAddress = GetExpression ("&verifier!AVrfpExceptionLogCurrentIndex");
  1929. if (TempAddress == 0 ) {
  1930. dprintf ("No exception information available (unable to resolve verifier!AVrfpExceptionLogCurrentIndex)\n");
  1931. return;
  1932. }
  1933. if (ReadMemory (TempAddress, &CurrentLogIndex, sizeof (CurrentLogIndex), &BytesRead) == FALSE) {
  1934. dprintf ("Error: cannot read value at %p\n",
  1935. TempAddress);
  1936. return;
  1937. }
  1938. CurrentLogIndex = CurrentLogIndex % ExceptionLogEntriesNo;
  1939. //
  1940. // Read the AVRF_EXCEPTION_LOG_ENTRY type size.
  1941. //
  1942. LogEntrySize = GetTypeSize ("verifier!_AVRF_EXCEPTION_LOG_ENTRY");
  1943. if (LogEntrySize == 0) {
  1944. dprintf ("Error: cannot get verifier!_AVRF_EXCEPTION_LOG_ENTRY type size.\n");
  1945. return;
  1946. }
  1947. //
  1948. // Parse all the log entries.
  1949. //
  1950. for (LogEntry = 0; LogEntry < ExceptionLogEntriesNo && LogEntry < MaxEntries; LogEntry += 1) {
  1951. if (CheckControlC()) {
  1952. break;
  1953. }
  1954. CurrentLogEntryAddress = ExceptionLogAddress + CurrentLogIndex * LogEntrySize;
  1955. if (InitTypeRead(CurrentLogEntryAddress, verifier!_AVRF_EXCEPTION_LOG_ENTRY)) {
  1956. dprintf ("Error: cannot read log entry at %p\n",
  1957. CurrentLogEntryAddress);
  1958. }
  1959. else {
  1960. Value = ReadField (ThreadId);
  1961. if (Value == 0) {
  1962. //
  1963. // This is the last entry in our log.
  1964. //
  1965. break;
  1966. }
  1967. EntriedDumped += 1;
  1968. dprintf ("=================================\n");
  1969. dprintf ("Thread ID: %p\n",
  1970. Value);
  1971. Value = ReadField (ExceptionCode);
  1972. dprintf ("Exception code: %I64x\n",
  1973. Value);
  1974. Value = ReadField (ExceptionAddress);
  1975. dprintf ("Exception address: %p\n",
  1976. Value);
  1977. Value = ReadField (ExceptionRecord);
  1978. dprintf ("Exception record: %p\n",
  1979. Value);
  1980. Value = ReadField (ContextRecord);
  1981. dprintf ("Context record: %p\n",
  1982. Value);
  1983. }
  1984. if (CurrentLogIndex > 0) {
  1985. CurrentLogIndex -= 1;
  1986. }
  1987. else {
  1988. CurrentLogIndex = ExceptionLogEntriesNo - 1;
  1989. }
  1990. }
  1991. if (EntriedDumped == 0) {
  1992. dprintf ("No exception log entries available.\n");
  1993. }
  1994. else {
  1995. dprintf ("\nDisplayed %u exception log entries.\n",
  1996. EntriedDumped);
  1997. }
  1998. }
  1999. #define THREAD_TABLE_SIZE 61
  2000. VOID
  2001. VrfDumpThreadsInformation (
  2002. ULONG64 UserThreadId
  2003. )
  2004. {
  2005. ULONG64 CrtListHeadAddress;
  2006. ULONG64 Flink;
  2007. ULONG64 Displacement;
  2008. ULONG64 ThreadId;
  2009. ULONG64 ThreadParentId;
  2010. ULONG64 ThreadParameter;
  2011. ULONG64 ThreadStackSize;
  2012. ULONG64 ThreadStartAddress;
  2013. ULONG64 ThreadCreationFlags;
  2014. ULONG64 TempAddress;
  2015. ULONG CrtListIndex;
  2016. ULONG PtrSize;
  2017. ULONG DumpedThreads;
  2018. ULONG ThreadTableLength;
  2019. BOOL Continue;
  2020. CHAR SeparatorString[] = "===================================================\n";
  2021. CHAR Symbol[ 1024 ];
  2022. PtrSize = IsPtr64() ? 8 : 4;
  2023. DumpedThreads = 0;
  2024. //
  2025. // Get the length of the thread list array.
  2026. //
  2027. TempAddress = GetExpression ("&verifier!AVrfpThreadTableEntriesNo");
  2028. if (TempAddress == 0 ) {
  2029. ThreadTableLength = THREAD_TABLE_SIZE;
  2030. }
  2031. else {
  2032. ThreadTableLength = ReadULONG(TempAddress);
  2033. if (ThreadTableLength <= 1) {
  2034. return;
  2035. }
  2036. }
  2037. //
  2038. // Get the address of the thread list array.
  2039. //
  2040. CrtListHeadAddress = GetExpression ("&verifier!AVrfpThreadTable");
  2041. if (CrtListHeadAddress == 0 ) {
  2042. dprintf ("Unable read thread table (verifier!AVrfpThreadTable))\n");
  2043. return;
  2044. }
  2045. for (CrtListIndex = 0; CrtListIndex < ThreadTableLength; CrtListIndex += 1, CrtListHeadAddress += 2 * PtrSize) {
  2046. if (CheckControlC()) {
  2047. break;
  2048. }
  2049. //
  2050. // Read the first Flink from the list.
  2051. //
  2052. if (ReadPtr (CrtListHeadAddress, &Flink) != S_OK) {
  2053. dprintf ("Cannot read list head from %p\n",
  2054. CrtListHeadAddress);
  2055. continue;
  2056. }
  2057. //
  2058. // Parse all the elements of this list.
  2059. //
  2060. Continue = TRUE;
  2061. while (Flink != CrtListHeadAddress) {
  2062. if (CheckControlC()) {
  2063. Continue = FALSE;
  2064. break;
  2065. }
  2066. if (InitTypeRead(Flink, verifier!_AVRF_THREAD_ENTRY)) {
  2067. dprintf ("Error: cannot read verifier thread structure from %p\n",
  2068. Flink);
  2069. break;
  2070. }
  2071. ThreadId = ReadField (Id);
  2072. if (UserThreadId == 0 || UserThreadId == ThreadId) {
  2073. ThreadStartAddress = ReadField (Function);
  2074. if (ThreadStartAddress != 0) {
  2075. GetSymbol (ThreadStartAddress, Symbol, &Displacement);
  2076. ThreadParameter = ReadField (Parameter);
  2077. ThreadParentId = ReadField (ParentThreadId);
  2078. ThreadStackSize = ReadField (StackSize);
  2079. ThreadCreationFlags = ReadField (CreationFlags);
  2080. }
  2081. DumpedThreads += 1;
  2082. dprintf (SeparatorString);
  2083. dprintf ("Thread ID = 0x%X\n", (ULONG)ThreadId);
  2084. if (ThreadStartAddress == 0) {
  2085. dprintf ("Initial thread\n");
  2086. }
  2087. else {
  2088. dprintf ("Parent thread ID = 0x%X\n", (ULONG)ThreadParentId);
  2089. if (Displacement != 0) {
  2090. dprintf ("Start address = 0x%p: %s+0x%I64X\n",
  2091. ThreadStartAddress,
  2092. Symbol,
  2093. Displacement);
  2094. }
  2095. else {
  2096. dprintf ("Start address = 0x%p: %s\n",
  2097. ThreadStartAddress,
  2098. Symbol);
  2099. }
  2100. if (ThreadParameter != 0) {
  2101. dprintf ("Parameter = 0x%p\n", ThreadParameter);
  2102. }
  2103. if (ThreadStackSize != 0) {
  2104. dprintf ("Stack size specified by parent = 0x%p\n", ThreadStackSize);
  2105. }
  2106. if (ThreadCreationFlags != 0) {
  2107. dprintf ("CreateThread flags specified by parent = 0x%X\n", (ULONG)ThreadCreationFlags);
  2108. }
  2109. }
  2110. }
  2111. //
  2112. // Go to the next thread.
  2113. //
  2114. if (ReadPtr (Flink, &Flink) != S_OK) {
  2115. dprintf ("Cannot read next list element address from %p\n",
  2116. Flink);
  2117. break;
  2118. }
  2119. }
  2120. if (Continue == FALSE) {
  2121. break;
  2122. }
  2123. }
  2124. dprintf (SeparatorString);
  2125. dprintf ("Number of threads displayed: 0x%X\n", DumpedThreads);
  2126. }
  2127. /////////////////////////////////////////////////////////////////////
  2128. /////////////////////////////////////////////// Call tracker querying
  2129. /////////////////////////////////////////////////////////////////////
  2130. //
  2131. // This codes are defined in \nt\base\win32\verifier\tracker.h
  2132. //
  2133. #define TRACK_HEAP_ALLOCATE 1
  2134. #define TRACK_HEAP_REALLOCATE 2
  2135. #define TRACK_HEAP_FREE 3
  2136. #define TRACK_VIRTUAL_ALLOCATE 4
  2137. #define TRACK_VIRTUAL_FREE 5
  2138. #define TRACK_VIRTUAL_PROTECT 6
  2139. #define TRACK_MAP_VIEW_OF_SECTION 7
  2140. #define TRACK_UNMAP_VIEW_OF_SECTION 8
  2141. #define TRACK_EXIT_PROCESS 9
  2142. #define TRACK_TERMINATE_THREAD 10
  2143. #define TRACK_SUSPEND_THREAD 11
  2144. ULONG64 VrfThreadTrackerAddress;
  2145. ULONG64 VrfHeapTrackerAddress;
  2146. ULONG64 VrfVspaceTrackerAddress;
  2147. LOGICAL
  2148. VrfDetectTrackerAddresses (
  2149. VOID
  2150. )
  2151. {
  2152. ULONG64 SymbolAddress;
  2153. SymbolAddress = GetExpression ("verifier!AVrfThreadTracker");
  2154. if (!ReadPointer (SymbolAddress, &VrfThreadTrackerAddress) != S_OK) {
  2155. dprintf( "Error: cannot read pointer at verifier!AVrfThreadTracker \n" );
  2156. return FALSE;
  2157. }
  2158. SymbolAddress = GetExpression ("verifier!AVrfHeapTracker");
  2159. if (!ReadPointer (SymbolAddress, &VrfHeapTrackerAddress) != S_OK) {
  2160. dprintf( "Error: cannot read pointer at verifier!AVrfHeapTracker \n" );
  2161. return FALSE;
  2162. }
  2163. SymbolAddress = GetExpression ("verifier!AVrfVspaceTracker");
  2164. if (!ReadPointer (SymbolAddress, &VrfVspaceTrackerAddress) != S_OK) {
  2165. dprintf( "Error: cannot read pointer at verifier!AVrfVspaceTracker \n" );
  2166. return FALSE;
  2167. }
  2168. return TRUE;
  2169. }
  2170. LOGICAL
  2171. VrfCallTrackerHeapSearchFilter (
  2172. ULONG64 SearchAddress,
  2173. PULONG64 Info
  2174. )
  2175. {
  2176. if (Info[4] == TRACK_HEAP_ALLOCATE) {
  2177. if (Info[0] <= SearchAddress && SearchAddress < Info[0] + Info[1]) {
  2178. return TRUE;
  2179. }
  2180. }
  2181. else if (Info[4] == TRACK_HEAP_FREE) {
  2182. if (Info[0] == SearchAddress) {
  2183. return TRUE;
  2184. }
  2185. }
  2186. else if (Info[4] == TRACK_HEAP_REALLOCATE) {
  2187. if (Info[1] <= SearchAddress && SearchAddress < Info[1] + Info[2]) {
  2188. return TRUE;
  2189. }
  2190. if (Info[0] == SearchAddress) {
  2191. return TRUE;
  2192. }
  2193. }
  2194. return FALSE;
  2195. }
  2196. LOGICAL
  2197. VrfCallTrackerVspaceSearchFilter (
  2198. ULONG64 SearchAddress,
  2199. PULONG64 Info
  2200. )
  2201. {
  2202. if (Info[4] == TRACK_VIRTUAL_ALLOCATE || Info[4] == TRACK_MAP_VIEW_OF_SECTION ) {
  2203. if (Info[0] <= SearchAddress && SearchAddress < Info[0] + Info[1]) {
  2204. return TRUE;
  2205. }
  2206. }
  2207. else {
  2208. if (Info[0] == SearchAddress) {
  2209. return TRUE;
  2210. }
  2211. }
  2212. return FALSE;
  2213. }
  2214. LOGICAL
  2215. VrfCallTrackerSearchFilter (
  2216. ULONG64 TrackerAddress,
  2217. ULONG64 SearchAddress,
  2218. PULONG64 Info
  2219. )
  2220. {
  2221. if (TrackerAddress == VrfThreadTrackerAddress) {
  2222. return FALSE;
  2223. }
  2224. else if (TrackerAddress == VrfHeapTrackerAddress) {
  2225. return VrfCallTrackerHeapSearchFilter (SearchAddress, Info);
  2226. }
  2227. else if (TrackerAddress == VrfVspaceTrackerAddress) {
  2228. return VrfCallTrackerVspaceSearchFilter (SearchAddress, Info);
  2229. }
  2230. else {
  2231. dprintf ("Error: unrecognized call tracker address %p \n", TrackerAddress);
  2232. return FALSE;
  2233. }
  2234. return FALSE;
  2235. }
  2236. PCHAR
  2237. VrfCallTrackerEntryName (
  2238. ULONG64 Type
  2239. )
  2240. {
  2241. switch (Type) {
  2242. case TRACK_HEAP_ALLOCATE: return "HeapAlloc";
  2243. case TRACK_HEAP_REALLOCATE: return "HeapReAlloc";
  2244. case TRACK_HEAP_FREE: return "HeapFree";
  2245. case TRACK_VIRTUAL_ALLOCATE: return "VirtualAlloc";
  2246. case TRACK_VIRTUAL_FREE: return "VirtualFree";
  2247. case TRACK_VIRTUAL_PROTECT: return "VirtualProtect";
  2248. case TRACK_MAP_VIEW_OF_SECTION: return "MapView";
  2249. case TRACK_UNMAP_VIEW_OF_SECTION: return "UnmapView";
  2250. case TRACK_EXIT_PROCESS: return "ExitProcess";
  2251. case TRACK_TERMINATE_THREAD: return "TerminateThread";
  2252. case TRACK_SUSPEND_THREAD: return "SuspendThread";
  2253. default: return "unknown!";
  2254. }
  2255. }
  2256. LOGICAL
  2257. VrfQueryCallTracker (
  2258. ULONG64 TrackerAddress,
  2259. ULONG64 SearchAddress,
  2260. ULONG64 LastEntries
  2261. )
  2262. {
  2263. ULONG64 TrackerSize;
  2264. ULONG64 TrackerIndex;
  2265. ULONG EntriesOffset;
  2266. ULONG Result;
  2267. ULONG EntrySize;
  2268. ULONG64 EntryAddress;
  2269. ULONG64 Index;
  2270. ULONG64 EntryInfo[5];
  2271. ULONG64 EntryTraceDepth;
  2272. ULONG TraceOffset;
  2273. LOGICAL FullTracker = FALSE;
  2274. LOGICAL FoundEntry = FALSE;
  2275. LOGICAL AtLeastOneEntry = FALSE;
  2276. ULONG PvoidSize;
  2277. ULONG64 ReturnAddress;
  2278. ULONG I;
  2279. CHAR Symbol [1024];
  2280. ULONG64 Displacement;
  2281. //
  2282. // Read all type sizes and field offsets required to traverse the call tracker.
  2283. //
  2284. if (InitTypeRead (TrackerAddress, verifier!_AVRF_TRACKER)) {
  2285. dprintf("Error: failed to read type verifier!_AVRF_TRACKER @ %p\n", TrackerAddress);
  2286. return FALSE;
  2287. }
  2288. TrackerSize = ReadField (Size);
  2289. TrackerIndex = ReadField (Index);
  2290. if (GetFieldOffset ("verifier!_AVRF_TRACKER", "Entry", &EntriesOffset) != S_OK) {
  2291. dprintf("Error: failed to get offset of `Entry' in type verifier!_AVRF_TRACKER\n");
  2292. return FALSE;
  2293. }
  2294. if (GetFieldOffset ("verifier!_AVRF_TRACKER_ENTRY", "Trace", &TraceOffset) != S_OK) {
  2295. dprintf("Error: failed to get offset of `Trace' in type verifier!_AVRF_TRACKER_ENTRY\n");
  2296. return FALSE;
  2297. }
  2298. EntrySize = GetTypeSize ("verifier!_AVRF_TRACKER_ENTRY");
  2299. if (EntrySize == 0) {
  2300. dprintf("Error: failed to get size of type verifier!_AVRF_TRACKER_ENTRY\n");
  2301. return FALSE;
  2302. }
  2303. PvoidSize = IsPtr64() ? 8 : 4;
  2304. //
  2305. // Figure out how many valid entries are in the tracker.
  2306. //
  2307. if (TrackerIndex == 0) {
  2308. dprintf ("The tracker has zero entries. \n");
  2309. return TRUE;
  2310. }
  2311. if (SearchAddress != 0) {
  2312. if (TrackerIndex < TrackerSize) {
  2313. dprintf ("Searching call tracker @ %p with %I64u valid entries ... \n",
  2314. TrackerAddress, TrackerIndex);
  2315. }
  2316. else {
  2317. dprintf ("Searching call tracker @ %p with %I64u valid entries ... \n",
  2318. TrackerAddress, TrackerSize);
  2319. FullTracker = TRUE;
  2320. }
  2321. }
  2322. else {
  2323. if (TrackerIndex < TrackerSize) {
  2324. dprintf ("Dumping last %I64u entries from tracker @ %p with %I64u valid entries ... \n",
  2325. LastEntries, TrackerAddress, TrackerIndex);
  2326. }
  2327. else {
  2328. dprintf ("Dumping last %I64u entries from tracker @ %p with %I64u valid entries ... \n",
  2329. LastEntries, TrackerAddress, TrackerSize);
  2330. FullTracker = TRUE;
  2331. }
  2332. }
  2333. //
  2334. // Compute last entry in the call tracker.
  2335. //
  2336. EntryAddress = TrackerAddress + EntriesOffset + EntrySize * TrackerIndex;
  2337. //
  2338. // Start a loop iterating in reverse all tracker entries from the
  2339. // most recent to the oldest one logged
  2340. //
  2341. for (Index = 0; Index < TrackerSize; Index += 1) {
  2342. //
  2343. // Check for user interruption.
  2344. //
  2345. if (CheckControlC ()) {
  2346. dprintf ("Search interrupted. \n");
  2347. break;
  2348. }
  2349. //
  2350. // If we have already printed the last N entries stop.
  2351. //
  2352. if (SearchAddress == 0) {
  2353. if (Index >= LastEntries) {
  2354. break;
  2355. }
  2356. }
  2357. //
  2358. // Read the current tracker entry.
  2359. //
  2360. if (InitTypeRead (EntryAddress, verifier!_AVRF_TRACKER_ENTRY)) {
  2361. dprintf("Error: failed to read type verifier!_AVRF_TRACKER_ENTRY @ %p\n", EntryAddress);
  2362. return FALSE;
  2363. }
  2364. EntryInfo[0] = ReadField (Info[0]);
  2365. EntryInfo[1] = ReadField (Info[1]);
  2366. EntryInfo[2] = ReadField (Info[2]);
  2367. EntryInfo[3] = ReadField (Info[3]);
  2368. EntryInfo[4] = ReadField (Type);
  2369. EntryTraceDepth = ReadField (TraceDepth);
  2370. FoundEntry = TRUE;
  2371. //
  2372. // If we are searching for an address and the current entry
  2373. // does not satisfy the search condition then move on.
  2374. //
  2375. if (SearchAddress != 0) {
  2376. if (VrfCallTrackerSearchFilter(TrackerAddress, SearchAddress, EntryInfo) == FALSE) {
  2377. FoundEntry = FALSE;
  2378. }
  2379. }
  2380. //
  2381. // Dump the tracker entry.
  2382. //
  2383. if (FoundEntry) {
  2384. dprintf ("-------------------------------------------------------------- \n"
  2385. "%s: %I64X %I64X %I64X %I64X \n\n",
  2386. VrfCallTrackerEntryName (EntryInfo[4]),
  2387. EntryInfo[0],
  2388. EntryInfo[1],
  2389. EntryInfo[2],
  2390. EntryInfo[3]);
  2391. for (I = 0; I < EntryTraceDepth; I += 1) {
  2392. ReturnAddress = 0;
  2393. ReadPointer (EntryAddress + TraceOffset + I * PvoidSize, &ReturnAddress);
  2394. GetSymbol (ReturnAddress, Symbol, &Displacement);
  2395. dprintf ("\t%p: %s+0x%I64X\n", ReturnAddress, Symbol, Displacement );
  2396. }
  2397. AtLeastOneEntry = TRUE;
  2398. }
  2399. //
  2400. // Move to the previous tracker entry.
  2401. //
  2402. if (FullTracker) {
  2403. if (TrackerIndex > 0) {
  2404. TrackerIndex -= 1;
  2405. }
  2406. else {
  2407. TrackerIndex = TrackerSize - 1;
  2408. }
  2409. }
  2410. else {
  2411. if (TrackerIndex == 1) {
  2412. break;
  2413. }
  2414. else {
  2415. TrackerIndex -= 1;
  2416. }
  2417. }
  2418. EntryAddress = TrackerAddress + EntriesOffset + EntrySize * TrackerIndex;
  2419. }
  2420. //
  2421. // If we searched for an address and did not find any print a sorry message.
  2422. //
  2423. if (SearchAddress != 0 && AtLeastOneEntry == FALSE) {
  2424. dprintf ("No entries found. \n");
  2425. }
  2426. return TRUE;
  2427. }
  2428. /////////////////////////////////////////////////////////////////////
  2429. ///////////////////////////////////////////////////// Symbol checking
  2430. /////////////////////////////////////////////////////////////////////
  2431. #define CHECK_NAME(Name, Dll) { \
  2432. if (GetExpression(Name) == 0) { \
  2433. dprintf ("Failed to resolve `%s' to an address. \n", Name); \
  2434. Result = FALSE; \
  2435. *DllName = Dll; \
  2436. goto Exit; \
  2437. } \
  2438. }
  2439. #define CHECK_TYPE(Name, Dll) { \
  2440. if (GetTypeSize(Name) == 0) { \
  2441. dprintf ("No type information found for `%s'. \n", Name); \
  2442. Result = FALSE; \
  2443. *DllName = Dll; \
  2444. goto Exit; \
  2445. } \
  2446. }
  2447. LOGICAL
  2448. VrfCheckSymbols (
  2449. PCHAR * DllName
  2450. )
  2451. {
  2452. LOGICAL Result = TRUE;
  2453. CHECK_TYPE ("ntdll!_PEB", "ntdll.dll");
  2454. if (VrfPebAddress() == 0) {
  2455. dprintf ("Failed to get the address of the PEB structure.\n");
  2456. *DllName = "ntdll.dll";
  2457. return FALSE;
  2458. }
  2459. if (VrfVerifierGlobalFlagSet() == FALSE) {
  2460. dprintf ("Application verifier is not enabled for this process.\n"
  2461. "Use appverif.exe tool to enable it. \n");
  2462. *DllName = NULL;
  2463. return FALSE;
  2464. }
  2465. //
  2466. // ntdll.dll variables
  2467. //
  2468. CHECK_NAME ("ntdll!RtlpStackTraceDataBase", "ntdll.dll");
  2469. CHECK_NAME ("ntdll!AVrfpVerifierFlags", "ntdll.dll");
  2470. //
  2471. // ntdll.dll types
  2472. //
  2473. CHECK_TYPE ("ntdll!_RTL_CRITICAL_SECTION", "ntdll.dll");
  2474. CHECK_TYPE ("ntdll!_RTL_CRITICAL_SECTION_DEBUG", "ntdll.dll");
  2475. CHECK_TYPE ("ntdll!_RTL_STACK_TRACE_ENTRY", "ntdll.dll");
  2476. CHECK_TYPE ("ntdll!_STACK_TRACE_DATABASE", "ntdll.dll");
  2477. CHECK_TYPE ("ntdll!_DPH_HEAP_ROOT", "ntdll.dll");
  2478. CHECK_TYPE ("ntdll!_DPH_HEAP_BLOCK", "ntdll.dll");
  2479. CHECK_TYPE ("ntdll!_DPH_BLOCK_INFORMATION", "ntdll.dll");
  2480. CHECK_TYPE ("ntdll!ULONG_PTR", "ntdll.dll");
  2481. CHECK_TYPE ("ntdll!_UNICODE_STRING", "ntdll.dll");
  2482. CHECK_TYPE ("ntdll!_PEB", "ntdll.dll");
  2483. CHECK_TYPE ("ntdll!_PEB_LDR_DATA", "ntdll.dll");
  2484. CHECK_TYPE ("ntdll!_LDR_DATA_TABLE_ENTRY", "ntdll.dll");
  2485. //
  2486. // verifier.dll types
  2487. //
  2488. CHECK_TYPE ("verifier!_AVRF_EXCEPTION_LOG_ENTRY", "verifier.dll");
  2489. CHECK_TYPE ("verifier!_AVRF_DEADLOCK_GLOBALS", "verifier.dll");
  2490. CHECK_TYPE ("verifier!_AVRF_DEADLOCK_RESOURCE", "verifier.dll");
  2491. CHECK_TYPE ("verifier!_AVRF_DEADLOCK_NODE", "verifier.dll");
  2492. CHECK_TYPE ("verifier!_AVRF_DEADLOCK_THREAD", "verifier.dll");
  2493. CHECK_TYPE ("verifier!_AVRF_THREAD_ENTRY", "verifier.dll");
  2494. CHECK_TYPE ("verifier!_AVRF_TRACKER", "verifier.dll");
  2495. CHECK_TYPE ("verifier!_AVRF_TRACKER_ENTRY", "verifier.dll");
  2496. //
  2497. // Cache some addresses we may need.
  2498. //
  2499. VrfDetectTrackerAddresses ();
  2500. Exit:
  2501. //
  2502. // On WinXP !avrf does not work with retail symbols because they do
  2503. // not have the type information required. This has been fixed in .NET using
  2504. // the ntdllsym/verifiersym solution.
  2505. //
  2506. if (Result == FALSE && WinXpClient == TRUE) {
  2507. dprintf ("\nThis extension requires symbols with type information \n"
  2508. "for ntdll.dll and verifier.dll. \n\n");
  2509. }
  2510. return Result;
  2511. }