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.

2521 lines
72 KiB

  1. /*++
  2. Copyright (c) 1992-2001 Microsoft Corporation
  3. Module Name:
  4. bugcheck.cpp
  5. Abstract:
  6. WinDbg Extension Api
  7. Environment:
  8. User Mode.
  9. Revision History:
  10. Andre Vachon (andreva)
  11. bugcheck analyzer.
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. extern BUGDESC_APIREFS g_BugDescApiRefs[];
  16. extern ULONG g_NumBugDescApiRefs;
  17. PSTR g_PoolRegion[DbgPoolRegionMax] = {
  18. "Unknown", // DbgPoolRegionUnknown,
  19. "Special pool", // DbgPoolRegionSpecial,
  20. "Paged pool", // DbgPoolRegionPaged,
  21. "Nonpaged pool", // DbgPoolRegionNonPaged,
  22. "Pool code", // DbgPoolRegionCode,
  23. "Nonpaged pool expansion", // DbgPoolRegionNonPagedExpansion,
  24. };
  25. /*
  26. Get the description record for a bugcheck code.
  27. */
  28. BOOL
  29. GetBugCheckDescription(
  30. PBUGCHECK_ANALYSIS Bc
  31. )
  32. {
  33. ULONG i;
  34. for (i=0; i<g_NumBugDescApiRefs; i++) {
  35. if (g_BugDescApiRefs[i].Code == Bc->Code) {
  36. (g_BugDescApiRefs[i].pExamineRoutine)(Bc);
  37. return TRUE;
  38. }
  39. }
  40. return FALSE;
  41. }
  42. void
  43. PrintBugDescription(
  44. PBUGCHECK_ANALYSIS pBugCheck
  45. )
  46. {
  47. LPTSTR Name = pBugCheck->szName;
  48. LPTSTR Description = pBugCheck->szDescription;
  49. if (!Name)
  50. {
  51. Name = "Unknown bugcheck code";
  52. }
  53. if (!Description)
  54. {
  55. Description = "Unknown bugcheck description\n";
  56. }
  57. dprintf("%s (%lx)\n%s", Name, pBugCheck->Code, Description);
  58. dprintf("Arguments:\n");
  59. for (ULONG i=0; i<4; i++) {
  60. dprintf("Arg%lx: %p",i+1,pBugCheck->Args[i]);
  61. if (pBugCheck->szParamsDesc[i]) {
  62. dprintf(", %s", pBugCheck->szParamsDesc[i]);
  63. }
  64. dprintf("\n");
  65. }
  66. }
  67. BOOL
  68. SaveImageName(
  69. DebugFailureAnalysis* Analysis,
  70. LPSTR DriverName)
  71. {
  72. PCHAR BaseName = strrchr(DriverName, '\\');
  73. if (BaseName)
  74. {
  75. BaseName++;
  76. }
  77. else
  78. {
  79. BaseName = DriverName;
  80. }
  81. if (*BaseName)
  82. {
  83. Analysis->SetString(DEBUG_FLR_IMAGE_NAME, BaseName);
  84. //
  85. // Just create a best guess module name because I don't think
  86. // the driver name returned by theOs is guaranteed to be in
  87. // the loaded module list (it could be unlaoded)
  88. //
  89. PCHAR EndName;
  90. if (EndName = strrchr(DriverName, '.'))
  91. {
  92. *EndName = 0;
  93. }
  94. Analysis->SetString(DEBUG_FLR_MODULE_NAME, BaseName);
  95. return TRUE;
  96. }
  97. return FALSE;
  98. }
  99. BOOL
  100. ReadUnicodeString(
  101. ULONG64 Address,
  102. PWCHAR Buffer,
  103. ULONG BufferSize,
  104. PULONG StringSize)
  105. {
  106. UNICODE_STRING64 uStr;
  107. UNICODE_STRING32 uStr32;
  108. ULONG res;
  109. if (!Buffer) {
  110. return FALSE;
  111. }
  112. if (!IsPtr64()) {
  113. if (!ReadMemory(Address, &uStr32, sizeof(uStr32), &res)) {
  114. return FALSE;
  115. }
  116. uStr.Length = uStr32.Length;
  117. uStr.MaximumLength = uStr32.MaximumLength;
  118. uStr.Buffer = (ULONG64) (LONG64) (LONG) uStr32.Buffer;
  119. } else {
  120. if (!ReadMemory(Address, &uStr, sizeof(uStr), &res)) {
  121. return FALSE;
  122. }
  123. }
  124. if (StringSize) {
  125. *StringSize = uStr.Length;
  126. }
  127. uStr.Length = (USHORT) min(BufferSize - 2, uStr.Length);
  128. if (!ReadMemory(uStr.Buffer, Buffer, uStr.Length, &res)) {
  129. return FALSE;
  130. }
  131. return TRUE;
  132. }
  133. /*
  134. Add driver name to CrashInfo if a KiBugCheckReferences a valid name
  135. */
  136. BOOL
  137. AddBugcheckDriver(
  138. DebugFailureAnalysis* Analysis,
  139. BOOL bUnicodeString,
  140. BOOL bUnicodeData,
  141. ULONG64 BugCheckDriver
  142. )
  143. {
  144. CHAR DriverName[MAX_PATH];
  145. if (Analysis->Get(DEBUG_FLR_IMAGE_NAME))
  146. {
  147. return FALSE;
  148. }
  149. if (!BugCheckDriver)
  150. {
  151. //
  152. // This contains a pointer to the unicode string.
  153. //
  154. BugCheckDriver = GetExpression("NT!KiBugCheckDriver");
  155. if (BugCheckDriver)
  156. {
  157. ReadPointer(BugCheckDriver, &BugCheckDriver);
  158. }
  159. }
  160. if (BugCheckDriver)
  161. {
  162. ULONG length = 0;
  163. BOOL success;
  164. ULONG size;
  165. ULONG res;
  166. ZeroMemory(DriverName, sizeof(DriverName));
  167. if (bUnicodeString)
  168. {
  169. success = ReadUnicodeString(BugCheckDriver,
  170. (PWCHAR) &DriverName[0],
  171. sizeof(DriverName), &length);
  172. }
  173. else
  174. {
  175. size = bUnicodeData ? 2 : 1;
  176. while (ReadMemory(BugCheckDriver + length,
  177. DriverName + length,
  178. size,
  179. &res) &&
  180. (res == size) &&
  181. *(DriverName + length))
  182. {
  183. length += size;
  184. }
  185. success = (length > 0);
  186. }
  187. if (success)
  188. {
  189. DriverName[length] = 0;
  190. if (bUnicodeData)
  191. {
  192. wchr2ansi((PWCHAR) DriverName, DriverName);
  193. DriverName[length / 2] = 0;
  194. }
  195. return SaveImageName(Analysis, DriverName);
  196. }
  197. }
  198. return FALSE;
  199. }
  200. BOOL
  201. BcGetDriverNameFromIrp(
  202. DebugFailureAnalysis* Analysis,
  203. ULONG64 Irp,
  204. ULONG64 DevObj,
  205. ULONG64 DrvObj
  206. )
  207. {
  208. if (Irp != 0)
  209. {
  210. DEBUG_IRP_INFO IrpInfo;
  211. PGET_IRP_INFO GetIrpInfo;
  212. if (g_ExtControl->GetExtensionFunction(0, "GetIrpInfo", (FARPROC*)&GetIrpInfo) == S_OK)
  213. {
  214. IrpInfo.SizeOfStruct = sizeof(IrpInfo);
  215. if (GetIrpInfo &&
  216. ((*GetIrpInfo)(g_ExtClient,Irp, &IrpInfo) == S_OK))
  217. {
  218. DevObj = IrpInfo.CurrentStack.DeviceObject;
  219. Analysis->SetUlong64(DEBUG_FLR_DEVICE_OBJECT, DevObj);
  220. }
  221. }
  222. }
  223. if (DevObj != 0)
  224. {
  225. DEBUG_DEVICE_OBJECT_INFO DevObjInfo;
  226. PGET_DEVICE_OBJECT_INFO GetDevObjInfo;
  227. if (g_ExtControl->GetExtensionFunction(0, "GetDevObjInfo", (FARPROC*)&GetDevObjInfo) == S_OK)
  228. {
  229. DevObjInfo.SizeOfStruct = sizeof(DEBUG_DEVICE_OBJECT_INFO);
  230. if (GetDevObjInfo &&
  231. ((*GetDevObjInfo)(g_ExtClient,DevObj, &DevObjInfo) == S_OK))
  232. {
  233. DrvObj = DevObjInfo.DriverObject;
  234. Analysis->SetUlong64(DEBUG_FLR_DRIVER_OBJECT, DrvObj);
  235. }
  236. }
  237. }
  238. if (DrvObj)
  239. {
  240. DEBUG_DRIVER_OBJECT_INFO DrvObjInfo;
  241. PGET_DRIVER_OBJECT_INFO GetDrvObjInfo;
  242. if (g_ExtControl->GetExtensionFunction(0, "GetDrvObjInfo",
  243. (FARPROC*)&GetDrvObjInfo) == S_OK)
  244. {
  245. DrvObjInfo.SizeOfStruct = sizeof(DEBUG_DRIVER_OBJECT_INFO);
  246. if (GetDrvObjInfo &&
  247. ((*GetDrvObjInfo)(g_ExtClient,DrvObj, &DrvObjInfo) == S_OK))
  248. {
  249. if (AddBugcheckDriver(Analysis, FALSE, TRUE,
  250. DrvObjInfo.DriverName.Buffer))
  251. {
  252. return TRUE;
  253. }
  254. }
  255. CHAR DriverName[MAX_PATH];
  256. if (g_ExtSymbols->GetModuleNames(DEBUG_ANY_ID,
  257. DrvObjInfo.DriverStart,
  258. DriverName,
  259. sizeof(DriverName),
  260. NULL,
  261. NULL, 0, NULL,
  262. NULL, 0, NULL) == S_OK)
  263. {
  264. return SaveImageName(Analysis, DriverName);
  265. }
  266. }
  267. }
  268. return FALSE;
  269. }
  270. ULONG64
  271. BcTargetKernelAddressStart(
  272. void
  273. )
  274. {
  275. switch (g_TargetMachine)
  276. {
  277. case IMAGE_FILE_MACHINE_I386:
  278. return 0x80000000;
  279. case IMAGE_FILE_MACHINE_AMD64:
  280. // return 0x80000000000UI64;
  281. case IMAGE_FILE_MACHINE_IA64:
  282. return 0x2000000000000000UI64;
  283. }
  284. return 0;
  285. }
  286. BOOL
  287. BcIsCpuOverClocked(
  288. void
  289. )
  290. {
  291. struct _IntelCPUSpeeds
  292. {
  293. union
  294. {
  295. ULONG CpuId;
  296. struct
  297. {
  298. ULONG Stepping:8;
  299. ULONG Model:8;
  300. ULONG Family:16;
  301. } s;
  302. };
  303. ULONG Mhz;
  304. } IntelSpeeds[] = {
  305. {0x06060d, 350},
  306. //{0x060702, 450},
  307. {0x060702, 500},
  308. //{0x060703, 450},
  309. //{0x060703, 500},
  310. //{0x060703, 550},
  311. //{0x060703, 533},
  312. {0x060703, 600},
  313. //{0x060801, 500},
  314. //{0x060801, 533},
  315. //{0x060801, 550},
  316. //{0x060801, 600},
  317. //{0x060801, 650},
  318. //{0x060801, 667},
  319. //{0x060801, 700},
  320. //{0x060801, 733},
  321. //{0x060801, 750},
  322. {0x060801, 800},
  323. //{0x060803, 500},
  324. //{0x060803, 533},
  325. //{0x060803, 550},
  326. //{0x060803, 600},
  327. //{0x060803, 650},
  328. //{0x060803, 667},
  329. //{0x060803, 700},
  330. //{0x060803, 733},
  331. //{0x060803, 750},
  332. //{0x060803, 800},
  333. //{0x060803, 850},
  334. //{0x060803, 866},
  335. //{0x060803, 933},
  336. {0x060803, 1000},
  337. //{0x060806, 600},
  338. //{0x060806, 650},
  339. //{0x060806, 667},
  340. //{0x060806, 700},
  341. //{0x060806, 733},
  342. //{0x060806, 750},
  343. //{0x060806, 800},
  344. //{0x060806, 850},
  345. //{0x060806, 866},
  346. //{0x060806, 900},
  347. //{0x060806, 933},
  348. {0x060806, 1000},
  349. //{0x06080A, 700},
  350. //{0x06080A, 733},
  351. //{0x06080A, 750},
  352. //{0x06080A, 800},
  353. //{0x06080A, 850},
  354. //{0x06080A, 866},
  355. //{0x06080A, 933},
  356. //{0x06080A, 1100},
  357. {0x06080A, 1130},
  358. //{0x060B01, 1000},
  359. //{0x060B01, 1130},
  360. //{0x060B01, 1200},
  361. {0x060B01, 1260},
  362. {0, 0},
  363. };
  364. PROCESSORINFO ProcInfo;
  365. ULONG Processor;
  366. ULONG64 Prcb;
  367. HRESULT Hr;
  368. ULONG Mhz;
  369. ULONG Number;
  370. ULONG CpuType;
  371. ULONG CpuStep;
  372. DEBUG_PROCESSOR_IDENTIFICATION_ALL IdAll;
  373. if (g_TargetMachine != IMAGE_FILE_MACHINE_I386)
  374. {
  375. return FALSE;
  376. }
  377. if (!Ioctl(IG_KD_CONTEXT, &ProcInfo, sizeof(ProcInfo)))
  378. {
  379. return FALSE;
  380. }
  381. Processor = ProcInfo.Processor;
  382. Hr = g_ExtData->ReadProcessorSystemData(Processor,
  383. DEBUG_DATA_KPRCB_OFFSET,
  384. &Prcb,
  385. sizeof(Prcb),
  386. NULL);
  387. if (Hr != S_OK)
  388. {
  389. return FALSE;
  390. }
  391. if (g_ExtData->
  392. ReadProcessorSystemData(Processor,
  393. DEBUG_DATA_PROCESSOR_IDENTIFICATION,
  394. &IdAll, sizeof(IdAll), NULL) != S_OK)
  395. {
  396. return FALSE;
  397. }
  398. if (g_ExtData->
  399. ReadProcessorSystemData(Processor,
  400. DEBUG_DATA_PROCESSOR_SPEED,
  401. &Mhz, sizeof(Mhz), NULL) != S_OK)
  402. {
  403. return FALSE;
  404. }
  405. {
  406. ULONG Speed;
  407. ULONG CpuId;
  408. CpuId = (IdAll.X86.Family << 16) + (IdAll.X86.Model << 8) + IdAll.X86.Stepping;
  409. if (!strcmp(IdAll.X86.VendorString, "GenuineIntel"))
  410. {
  411. for (ULONG i=0; IntelSpeeds[i].CpuId !=0; ++i)
  412. {
  413. if (IntelSpeeds[i].CpuId == CpuId)
  414. {
  415. //
  416. // If the part is within 2% of the MHz, it's OK.
  417. //
  418. if (Mhz > (IntelSpeeds[i].Mhz * 1.02))
  419. {
  420. return TRUE;
  421. }
  422. }
  423. }
  424. }
  425. }
  426. return FALSE;
  427. }
  428. HRESULT
  429. ExtGetPoolData(
  430. ULONG64 Pool,
  431. PDEBUG_POOL_DATA pPoolData
  432. )
  433. {
  434. PGET_POOL_DATA pGetPoolData = NULL;
  435. if (g_ExtControl->
  436. GetExtensionFunction(0, "GetPoolData",
  437. (FARPROC*)&pGetPoolData) == S_OK &&
  438. pGetPoolData)
  439. {
  440. return (*pGetPoolData)(g_ExtClient, Pool, pPoolData);
  441. }
  442. return E_FAIL;
  443. }
  444. #define DECL_GETINFO(bcname) \
  445. void \
  446. GetInfoFor##bcname ( \
  447. PBUGCHECK_ANALYSIS Bc, \
  448. KernelDebugFailureAnalysis* Analysis \
  449. )
  450. //DUPINFOCASE( DRIVER_IRQL_NOT_LESS_OR_EQUAL ); //0xD1
  451. DECL_GETINFO( IRQL_NOT_LESS_OR_EQUAL ) // (0xA)
  452. /*
  453. * Parameters
  454. *
  455. * Parameter 1 Memory referenced
  456. * Parameter 2 IRQL Value
  457. * Parameter 3 0 - Read 1 - Write
  458. * Parameter 4 Address that referenced the memory
  459. *
  460. *
  461. * Special Case
  462. *
  463. * If Parameter 3 is nonzero and equal to Parameter 1, this means that
  464. * a worker routine returned at a raised IRQL.
  465. * In this case:
  466. *
  467. * Parameter 1 Address of work routine
  468. * Parameter 2 IRQL at time of reference
  469. * Parameter 3 Address of work routine
  470. * Parameter 4 Work item
  471. *
  472. */
  473. {
  474. if ((Bc->Args[0] == Bc->Args[2]) && Bc->Args[2])
  475. {
  476. // special case
  477. Analysis->SetUlong64(DEBUG_FLR_WORKER_ROUTINE, Bc->Args[2]);
  478. Analysis->SetUlong64(DEBUG_FLR_WORK_ITEM, Bc->Args[3]);
  479. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  480. return;
  481. }
  482. Analysis->SetUlong64(Bc->Args[2] ?
  483. DEBUG_FLR_WRITE_ADDRESS : DEBUG_FLR_READ_ADDRESS,
  484. Bc->Args[0]);
  485. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  486. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[3]);
  487. if (Bc->Args[0] == Bc->Args[3] &&
  488. Bc->Args[2] == 0)
  489. {
  490. Analysis->SetString(DEBUG_FLR_BUGCHECK_SPECIFIER, "_CODE_AV");
  491. }
  492. }
  493. DECL_GETINFO( MEMORY_MANAGEMENT ) // 0x1A
  494. {
  495. CHAR BugCheckStr[20];
  496. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, Bc->Args[0]);
  497. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  498. }
  499. DECL_GETINFO( KMODE_EXCEPTION_NOT_HANDLED ) // (1e)
  500. {
  501. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_CODE, Bc->Args[0]);
  502. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[1]);
  503. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_PARAMETER1, Bc->Args[2]);
  504. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_PARAMETER2, Bc->Args[3]);
  505. if ((ULONG)Bc->Args[0] == STATUS_ACCESS_VIOLATION)
  506. {
  507. Analysis->SetUlong64(Bc->Args[2] ?
  508. DEBUG_FLR_WRITE_ADDRESS : DEBUG_FLR_READ_ADDRESS,
  509. Bc->Args[3]);
  510. }
  511. }
  512. DECL_GETINFO( FAT_FILE_SYSTEM ) // 0x23
  513. {
  514. ULONG64 ExR = 0, CxR = 0;
  515. ULONG64 KernAddrStart;
  516. KernAddrStart = BcTargetKernelAddressStart();
  517. if (Bc->Args[1] > KernAddrStart) {
  518. ExR = Bc->Args[1];
  519. }
  520. if (Bc->Args[2] > KernAddrStart) {
  521. CxR = Bc->Args[2];
  522. }
  523. if (ExR) {
  524. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_RECORD, ExR);
  525. }
  526. if (CxR) {
  527. Analysis->SetUlong64(DEBUG_FLR_CONTEXT, CxR);
  528. }
  529. }
  530. DECL_GETINFO( PANIC_STACK_SWITCH ) // 0x2b
  531. {
  532. Analysis->SetUlong64(DEBUG_FLR_TRAP_FRAME, Bc->Args[0]);
  533. }
  534. DECL_GETINFO( SYSTEM_SERVICE_EXCEPTION ) // 0x3b
  535. {
  536. Analysis->SetUlong64(DEBUG_FLR_CONTEXT, Bc->Args[2]);
  537. }
  538. DECL_GETINFO( MULTIPLE_IRP_COMPLETE_REQUESTS ) // 0x44
  539. {
  540. Analysis->SetUlong64(DEBUG_FLR_IRP_ADDRESS, Bc->Args[0]);
  541. }
  542. DECL_GETINFO( SESSION3_INITIALIZATION_FAILED ) // 0x6f
  543. {
  544. CHAR BugCheckStr[20];
  545. sprintf(BugCheckStr, "0x%lX_%lX", Bc->Code, Bc->Args[0]);
  546. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  547. }
  548. DECL_GETINFO( PROCESS_HAS_LOCKED_PAGES ) // 0x76
  549. {
  550. Analysis->SetUlong64(DEBUG_FLR_PROCESS_OBJECT, Bc->Args[1]);
  551. Analysis->SetString(DEBUG_FLR_DEFAULT_BUCKET_ID, "DRIVER_FAULT_0x76");
  552. #if 0
  553. Analysis->SetString(DEBUG_FLR_INTERNAL_SOLUTION_TEXT,
  554. "An unknown driver has left locked pages in the kernel"
  555. ".\nUsing the registry editor, set HKLM\\SYSTEM\\"
  556. "CurrentControlSet\\Control\\Session Manager\\"
  557. "Memory Management\\TrackLockedPages to a DWORD value"
  558. " of 1, and then reboot the machine.\n\n"
  559. "If the problem reproduces, the "
  560. "guilty driver will now be identifiable.\n");
  561. #endif
  562. }
  563. DECL_GETINFO( KERNEL_STACK_INPAGE_ERROR ) // 0x77
  564. {
  565. CHAR BugCheckStr[20];
  566. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, Bc->Args[0]);
  567. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  568. Analysis->SetUlong(DEBUG_FLR_STATUS_CODE, (ULONG)Bc->Args[0]);
  569. switch ((ULONG) Bc->Args[0])
  570. {
  571. case 0xc000009c: // (STATUS_DEVICE_DATA_ERROR)
  572. case 0xC000016A: // (STATUS_DISK_OPERATION_FAILED)
  573. Analysis->SetUlong(DEBUG_FLR_DISK_HARDWARE_ERROR, 1);
  574. break;
  575. default:
  576. break;
  577. }
  578. }
  579. DECL_GETINFO( KERNEL_DATA_INPAGE_ERROR ) // 0x7A
  580. {
  581. CHAR BugCheckStr[20];
  582. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, Bc->Args[1]);
  583. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  584. Analysis->SetUlong(DEBUG_FLR_STATUS_CODE, (ULONG) Bc->Args[1]);
  585. switch ( (ULONG) Bc->Args[1])
  586. {
  587. case 0xC000000E: case 0xC000009C:
  588. case 0xC000009D: case 0xC0000185:
  589. Analysis->SetUlong(DEBUG_FLR_DISK_HARDWARE_ERROR, 1);
  590. break;
  591. default:
  592. break;
  593. }
  594. }
  595. DECL_GETINFO( SYSTEM_THREAD_EXCEPTION_NOT_HANDLED ) // (7e)
  596. {
  597. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_CODE, Bc->Args[0]);
  598. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[1]);
  599. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_PARAMETER1, Bc->Args[2]);
  600. Analysis->SetUlong64(DEBUG_FLR_CONTEXT, Bc->Args[3]);
  601. }
  602. DECL_GETINFO( BUGCODE_NDIS_DRIVER ) //0x7c
  603. {
  604. ULONG64 DriverAddr, DriverBase;
  605. DriverAddr = 0;
  606. g_ExtSymbols->Reload("ndis.sys");
  607. switch (Bc->Args[0])
  608. {
  609. case 1: case 2: case 3:
  610. case 5: case 6: case 7: case 8: case 9:
  611. // Args[1] - A pointer to Miniport block. !ndiskd.miniport on this pointer for more info.
  612. GetFieldValue(Bc->Args[1], "ndis!NDIS_MINIPORT_BLOCK", "SavedSendHandler", DriverAddr);
  613. if (!DriverAddr)
  614. {
  615. GetFieldValue(Bc->Args[1], "ndis!NDIS_MINIPORT_BLOCK", "SavedSendPacketsHandler", DriverAddr);
  616. }
  617. break;
  618. case 4:
  619. // Arg[1] - a pointer to ndis!NDIS_M_DRIVER_BLOCK
  620. GetFieldValue(Bc->Args[1], "ndis!NDIS_M_DRIVER_BLOCK", "MiniportCharacteristics.InitializeHandler", DriverAddr);
  621. break;
  622. default:
  623. break;
  624. }
  625. if (DriverAddr &&
  626. (g_ExtSymbols->GetModuleByOffset(DriverAddr, 0, NULL, &DriverBase) == S_OK))
  627. {
  628. if (DriverBase)
  629. {
  630. Analysis->SetUlong64(DEBUG_FLR_FAULTING_MODULE, DriverBase);
  631. }
  632. }
  633. return ;
  634. }
  635. DECL_GETINFO( UNEXPECTED_KERNEL_MODE_TRAP ) // (7f)
  636. // It would be good to have TSS or TRAP address as exception parameter
  637. {
  638. DEBUG_STACK_FRAME stk[MAX_STACK_FRAMES];
  639. ULONG frames, i;
  640. CHAR BugCheckStr[20];
  641. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, Bc->Args[0]);
  642. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  643. if ((g_TargetMachine == IMAGE_FILE_MACHINE_I386) &&
  644. (g_ExtControl->GetStackTrace(0, 0, 0, stk, MAX_STACK_FRAMES,
  645. &frames ) == S_OK))
  646. {
  647. for (i=0; i<frames; ++i)
  648. {
  649. if (stk[i].FuncTableEntry)
  650. {
  651. PFPO_DATA FpoData = (PFPO_DATA)stk[i].FuncTableEntry;
  652. if (FpoData->cbFrame == FRAME_TSS)
  653. {
  654. Analysis->SetUlong64(DEBUG_FLR_TSS,
  655. (ULONG)stk[i].Reserved[1]);
  656. break;
  657. }
  658. // KiSystemService always has a trap frame - thats normal
  659. else if ( (FpoData->cbFrame == FRAME_TRAP) &&
  660. !FaIsFunctionAddr(stk[i].InstructionOffset,
  661. "KiSystemService"))
  662. {
  663. Analysis->SetUlong64(DEBUG_FLR_TRAP_FRAME,
  664. (ULONG)stk[i].Reserved[2]);
  665. break;
  666. }
  667. //if (FaIsFunctionAddr(stk[i].InstructionOffset, "KiTrap"))
  668. //{
  669. // TrapFrame = stk[i].FrameOffset;
  670. // break;
  671. //}
  672. }
  673. }
  674. }
  675. }
  676. DECL_GETINFO( KERNEL_MODE_EXCEPTION_NOT_HANDLED ) // (8e)
  677. {
  678. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_CODE, Bc->Args[0]);
  679. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[1]);
  680. Analysis->SetUlong64(DEBUG_FLR_TRAP_FRAME, Bc->Args[2]);
  681. }
  682. DECL_GETINFO( MACHINE_CHECK_EXCEPTION ) // 0x9C
  683. {
  684. DEBUG_PROCESSOR_IDENTIFICATION_ALL IdAll;
  685. CHAR BugCheckStr[4+5+17+3]; // space for vendor string, etc.
  686. PROCESSORINFO ProcInfo;
  687. ULONG64 Prcb;
  688. PCHAR Architecture;
  689. PCHAR Vendor;
  690. ULONG Processor;
  691. HRESULT Hr;
  692. if (!Ioctl(IG_KD_CONTEXT, &ProcInfo, sizeof(ProcInfo)))
  693. {
  694. return;
  695. }
  696. Processor = ProcInfo.Processor;
  697. //
  698. // Make sure we can find the PRCB before we ask for identification
  699. // information that would've been acquired from the PRCB.
  700. //
  701. Hr = g_ExtData->ReadProcessorSystemData(Processor,
  702. DEBUG_DATA_KPRCB_OFFSET,
  703. &Prcb,
  704. sizeof(Prcb),
  705. NULL);
  706. if (Hr != S_OK)
  707. {
  708. return;
  709. }
  710. Hr = g_ExtData->ReadProcessorSystemData(Processor,
  711. DEBUG_DATA_PROCESSOR_IDENTIFICATION,
  712. &IdAll,
  713. sizeof(IdAll),
  714. NULL);
  715. if (Hr != S_OK)
  716. {
  717. return;
  718. }
  719. switch (g_TargetMachine) {
  720. case IMAGE_FILE_MACHINE_I386:
  721. Architecture = "IA32";
  722. Vendor = IdAll.X86.VendorString;
  723. break;
  724. case IMAGE_FILE_MACHINE_IA64:
  725. Architecture = "IA64";
  726. Vendor = IdAll.Ia64.VendorString;
  727. break;
  728. case IMAGE_FILE_MACHINE_AMD64:
  729. Architecture = "AMD64";
  730. Vendor = IdAll.Amd64.VendorString;
  731. break;
  732. default:
  733. // use the standard bugcheck string
  734. return;
  735. }
  736. sprintf(BugCheckStr, "0x%lX_%s_%s", Bc->Code, Architecture, Vendor);
  737. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  738. }
  739. DECL_GETINFO( USER_MODE_HEALTH_MONITOR ) // 0x9E
  740. {
  741. if (Bc->Args[0])
  742. {
  743. ULONG result;
  744. CHAR ImageName[MAX_PATH];
  745. Analysis->SetUlong64(DEBUG_FLR_PROCESS_OBJECT, Bc->Args[0]);
  746. //
  747. // Second parameter (which is actually a string within the EPROCESS)
  748. // is the name of the image.
  749. //
  750. if (ReadMemory(Bc->Args[2], ImageName, sizeof(ImageName), &result) &&
  751. result)
  752. {
  753. ImageName[MAX_PATH-1]=0;
  754. ImageName[result]=0;
  755. SaveImageName(Analysis, ImageName);
  756. }
  757. }
  758. }
  759. DECL_GETINFO( DRIVER_POWER_STATE_FAILURE ) // 0x9F
  760. {
  761. ULONG64 DevObj = Bc->Args[2];
  762. ULONG64 DrvObj = Bc->Args[3];
  763. ULONG SubCode = (ULONG) Bc->Args[0];
  764. if (SubCode)
  765. {
  766. Analysis->SetUlong64(DEBUG_FLR_DRVPOWERSTATE_SUBCODE, SubCode);
  767. }
  768. if (DrvObj)
  769. {
  770. Analysis->SetUlong64(DEBUG_FLR_DRIVER_OBJECT, DrvObj);
  771. BcGetDriverNameFromIrp(Analysis, 0, 0, DrvObj);
  772. }
  773. if (DevObj)
  774. {
  775. Analysis->SetUlong64(DEBUG_FLR_DEVICE_OBJECT, DevObj);
  776. if (!DrvObj)
  777. {
  778. BcGetDriverNameFromIrp(Analysis, 0, DevObj, 0);
  779. }
  780. }
  781. }
  782. DECL_GETINFO( ACPI_BIOS_ERROR ) // 0xa5
  783. {
  784. switch (Bc->Args[0])
  785. {
  786. case 0x03 :
  787. Analysis->SetUlong64(DEBUG_FLR_ACPI_OBJECT, Bc->Args[1]);
  788. break;
  789. case 0x04 :
  790. case 0x05 :
  791. case 0x06 :
  792. case 0x07 :
  793. case 0x08 :
  794. case 0x09 :
  795. case 0x0A :
  796. case 0x0C :
  797. Analysis->SetUlong64(DEBUG_FLR_ACPI_OBJECT, Bc->Args[2]);
  798. // fallthrough
  799. case 0x01 :
  800. case 0x02 :
  801. case 0x0B :
  802. case 0x0D :
  803. case 0x10 :
  804. Analysis->SetUlong64(DEBUG_FLR_ACPI_EXTENSION, Bc->Args[1]);
  805. break;
  806. case 0x11 :
  807. if (Bc->Args[1] == 6)
  808. {
  809. // The machine fail to transition into ACPI mode
  810. CHAR BugCheckStr[40];
  811. sprintf(BugCheckStr, "0x%lx_FAILED_ACPI_TRANSITION", Bc->Code);
  812. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  813. }
  814. break;
  815. case 0x10001 :
  816. case 0x10002 :
  817. case 0x10003 :
  818. Analysis->SetUlong64(DEBUG_FLR_DEVICE_OBJECT, Bc->Args[1]);
  819. Analysis->SetUlong64(DEBUG_FLR_ACPI_OBJECT, Bc->Args[3]);
  820. break;
  821. case 0x10005 :
  822. case 0x10006 :
  823. Analysis->SetUlong64(DEBUG_FLR_ACPI_OBJECT, Bc->Args[1]);
  824. break;
  825. default:
  826. break;
  827. }
  828. }
  829. DECL_GETINFO( SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION ) // (c1)
  830. {
  831. Analysis->SetUlong(DEBUG_FLR_ANALYZAABLE_POOL_CORRUPTION, 1);
  832. Analysis->SetUlong64(DEBUG_FLR_SPECIAL_POOL_CORRUPTION_TYPE, Bc->Args[3]);
  833. }
  834. DECL_GETINFO( BAD_POOL_CALLER ) // 0xC2
  835. {
  836. DEBUG_POOL_DATA PoolData = {0};
  837. CHAR BugcheckStr[20] = {0};
  838. sprintf(BugcheckStr, "0x%lx_%lx", BAD_POOL_CALLER, (ULONG) Bc->Args[0]);
  839. if (Bc->Args[0] == 7)
  840. {
  841. // Double free
  842. if (!(Bc->Args[3] & 0x7))
  843. {
  844. // likely to be a valid address
  845. Analysis->SetUlong(DEBUG_FLR_ANALYZAABLE_POOL_CORRUPTION, 1);
  846. PoolData.SizeofStruct = sizeof(DEBUG_POOL_DATA);
  847. if (ExtGetPoolData(Bc->Args[3], &PoolData) == S_OK)
  848. {
  849. if (isprint(PoolData.PoolTag & 0xff) &&
  850. isprint((PoolData.PoolTag >> 8) & 0xff))
  851. {
  852. CHAR PoolTag[8] = {0};
  853. sprintf(PoolTag,"%c%c%c%c",
  854. #define PP(x) isprint(((x)&0xff))?((x)&0xff):('.')
  855. PP(PoolData.PoolTag),
  856. PP(PoolData.PoolTag >> 8),
  857. PP(PoolData.PoolTag >> 16),
  858. PP((PoolData.PoolTag&~0x80000000) >> 24)
  859. #undef PP
  860. );
  861. // seems like a valid pooltag
  862. Analysis->SetString(DEBUG_FLR_FREED_POOL_TAG, PoolTag);
  863. CatString(BugcheckStr, "_", sizeof(BugcheckStr));
  864. CatString(BugcheckStr, PoolTag, sizeof(BugcheckStr));
  865. }
  866. }
  867. }
  868. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugcheckStr);
  869. }
  870. else if ((Bc->Args[0] >= 0x40) && (Bc->Args[0] < 0x60))
  871. {
  872. if (Bc->Args[1] == 0)
  873. {
  874. Analysis->SetUlong(DEBUG_FLR_ANALYZAABLE_POOL_CORRUPTION, 1);
  875. }
  876. } else
  877. {
  878. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugcheckStr);
  879. }
  880. }
  881. DECL_GETINFO( DRIVER_VERIFIER_DETECTED_VIOLATION ) // 0xC4
  882. /*
  883. * Parameters
  884. *
  885. * Parameter 1 subclass of violation
  886. * Parameter 2, 3, 4 vary depending on parameter 1
  887. *
  888. */
  889. {
  890. ULONG64 BadDriverAddr;
  891. ULONG64 DriverNameAddr;
  892. ULONG res;
  893. ULONG ParamCount = 0;
  894. CHAR BugCheckStr[20];
  895. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, Bc->Args[0]);
  896. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  897. Analysis->SetUlong(DEBUG_FLR_ANALYZAABLE_POOL_CORRUPTION, 1);
  898. if ((BadDriverAddr = GetExpression("nt!ViBadDriver")) &&
  899. ReadPointer(BadDriverAddr, &DriverNameAddr))
  900. {
  901. AddBugcheckDriver(Analysis, TRUE, TRUE, DriverNameAddr);
  902. }
  903. switch (Bc->Args[0])
  904. {
  905. case 0x00 : // caller is trying to allocate zero bytes
  906. case 0x01 : // caller is trying to allocate paged pool at DISPATCH_LEVEL or above
  907. case 0x02 : // caller is trying to allocate nonpaged pool at an IRQL above DISPATCH_LEVEL
  908. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  909. // 3 - pool type
  910. // 4 - number of bytes
  911. break;
  912. case 0x03 : // caller is trying to allocate more than one page of mustsucceed pool, but one page is the maximum allowed by this API.
  913. break;
  914. case 0x10 : // caller is freeing a bad pool address
  915. Analysis->SetUlong64(DEBUG_FLR_POOL_ADDRESS, Bc->Args[1]); // bad pool address
  916. break;
  917. case 0x11 : // caller is trying to free paged pool at DISPATCH_LEVEL or above
  918. case 0x12 : // caller is trying to free nonpaged pool at an IRQL above DISPATCH_LEVEL
  919. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  920. Analysis->SetUlong64(DEBUG_FLR_POOL_ADDRESS, Bc->Args[3]);
  921. // 3 - pool type
  922. break;
  923. case 0x13 : // the pool the caller is trying to free is already free.
  924. case 0x14 : // the pool the caller is trying to free is already free.
  925. // 2 - line number
  926. // 3 - pool header
  927. // 4 - pool header contents
  928. Analysis->SetUlong64(DEBUG_FLR_POOL_ADDRESS, Bc->Args[3]);
  929. break;
  930. case 0x15 : // the pool the caller is trying to free contains an active timer.
  931. // 2 - timer entry
  932. // 3 - pool type
  933. // 4 - pool address being freed
  934. Analysis->SetUlong64(DEBUG_FLR_POOL_ADDRESS, Bc->Args[3]);
  935. break;
  936. case 0x16 : // the pool the caller is trying to free is a bad address.
  937. Analysis->SetUlong64(DEBUG_FLR_POOL_ADDRESS, Bc->Args[2]);
  938. break;
  939. // 2 - line number
  940. case 0x17 : // the pool the caller is trying to free contains an active ERESOURCE.
  941. // 2 - resource entry
  942. // 3 - pool type
  943. Analysis->SetUlong64(DEBUG_FLR_POOL_ADDRESS, Bc->Args[3]);
  944. break;
  945. case 0x30 : // raising IRQL to an invalid level,
  946. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  947. Analysis->SetUlong64(DEBUG_FLR_REQUESTED_IRQL, Bc->Args[2]);
  948. break;
  949. case 0x31 : // lowering IRQL to an invalid level,
  950. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  951. Analysis->SetUlong64(DEBUG_FLR_REQUESTED_IRQL, Bc->Args[2]);
  952. // 4 - 0 means the new IRQL is bad, 1 means the IRQL is invalid inside a DPC routine
  953. break;
  954. case 0x32 : // releasing a spinlock when not at DISPATCH_LEVEL.
  955. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  956. // 3 - spinlock address
  957. break;
  958. case 0x33 : // acquiring a fast mutex when not at APC_LEVEL or below.
  959. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  960. break;
  961. // 3 - fast mutex address
  962. case 0x34 : // releasing a fast mutex when not at APC_LEVEL.
  963. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  964. break;
  965. // 3 - thread APC disable count, 4 == fast mutex address
  966. case 0x35 : // kernel is releasing a spinlock when not at DISPATCH_LEVEL.
  967. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  968. Analysis->SetUlong64(DEBUG_FLR_PREVIOUS_IRQL, Bc->Args[3]);
  969. break;
  970. // 3 - spinlock address, 4 == old irql.
  971. case 0x36 : // kernel is releasing a queued spinlock when not at DISPATCH_LEVEL.
  972. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  973. Analysis->SetUlong64(DEBUG_FLR_PREVIOUS_IRQL, Bc->Args[3]);
  974. break;
  975. // 3 - spinlock number,
  976. case 0x37 : // a resource is being acquired but APCs are not disabled.
  977. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  978. break;
  979. // 3 - thread APC disable count,
  980. // 4 - resource.
  981. case 0x38 : // a resource is being released but APCs are not disabled.
  982. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  983. break;
  984. // 3 - thread APC disable count,
  985. // 4 - resource.
  986. case 0x39 : // a mutex is being acquired unsafe, but irql is not APC_LEVEL on entry.
  987. case 0x3A : // a mutex is being released unsafe, but irql is not APC_LEVEL on entry.
  988. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  989. break;
  990. // 3 - thread APC disable count,
  991. // 4 - mutex.
  992. case 0x3B : // KeWaitXxx routine is being called at DISPATCH_LEVEL or higher.
  993. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  994. break;
  995. // 3 - object to wait on,
  996. // 4 - time out parameter.
  997. case 0x3E : // KeLeaveCriticalRegion is being called for a thread that never entered a critical region.
  998. // Current stack analysis will give followup
  999. break;
  1000. case 0x40 : // acquiring a spinlock when not at DISPATCH_LEVEL.
  1001. case 0x41 : // releasing a spinlock when not at DISPATCH_LEVEL.
  1002. case 0x42 : // acquiring a spinlock when caller is already above DISPATCH_LEVEL.
  1003. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  1004. break;
  1005. // 3 - spinlock address
  1006. case 0x51 : // freeing memory where the caller has written past the end of the allocation overwriting our stored bytecount.
  1007. case 0x52 : // freeing memory where the caller has written past the end of the allocation overwriting our stored virtual address.
  1008. case 0x53 : // freeing memory where the caller has written past the end of the allocation overwriting our stored virtual address.
  1009. case 0x54 : // freeing memory where the caller has written past the end of the allocation overwriting our stored virtual address.
  1010. case 0x59 : // freeing memory where the caller has written past the end of the allocation overwriting our stored virtual address.
  1011. Analysis->SetUlong64(DEBUG_FLR_WRITE_ADDRESS, Bc->Args[1]);
  1012. break;
  1013. case 0x60 : // A driver has forgotten to free its pool allocations prior to unloading.
  1014. case 0x61 : // A driver is unloading and allocating memory (in another thread) at the same time.
  1015. // In both cases ViBadDriver should be set.
  1016. break;
  1017. case 0x70 : // MmProbeAndLockPages called when not at DISPATCH_LEVEL or below.
  1018. case 0x71 : // MmProbeAndLockProcessPages called when not at DISPATCH_LEVEL or below.
  1019. case 0x72 : // MmProbeAndLockSelectedPages called when not at DISPATCH_LEVEL or below.
  1020. case 0x73 : // MmMapIoSpace called when not at DISPATCH_LEVEL or below.
  1021. case 0x74 : // MmMapLockedPages called when not at DISPATCH_LEVEL or below.
  1022. case 0x75 : // MmMapLockedPages called when not at APC_LEVEL or below.
  1023. case 0x76 : // MmMapLockedPagesSpecifyCache called when not at DISPATCH_LEVEL or below.
  1024. case 0x77 : // MmMapLockedPagesSpecifyCache called when not at APC_LEVEL or below.
  1025. case 0x78 : // MmUnlockPages called when not at DISPATCH_LEVEL or below.
  1026. case 0x79 : // MmUnmapLockedPages called when not at DISPATCH_LEVEL or below.
  1027. case 0x7A : // MmUnmapLockedPages called when not at APC_LEVEL or below.
  1028. case 0x7B : // MmUnmapIoSpace called when not at APC_LEVEL or below.
  1029. case 0x7C : // MmUnlockPages called with an MDL whose pages were never successfully locked.
  1030. case 0x7D : // MmUnlockPages called with an MDL whose pages are from nonpaged pool - these should never be unlocked.
  1031. case 0x80 : // KeSetEvent called when not at DISPATCH_LEVEL or below.
  1032. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  1033. break;
  1034. case 0x81 : // MmMapLockedPages called without MDL_MAPPING_CAN_FAIL
  1035. break;
  1036. }
  1037. }
  1038. DECL_GETINFO( DRIVER_CAUGHT_MODIFYING_FREED_POOL ) // (c6)
  1039. /*
  1040. An attempt was made to access freed pool memory. The faulty component is
  1041. displayed in the current kernel stack.
  1042. Arguments:
  1043. Arg1: memory referenced
  1044. Arg2: value 0 = read operation, 1 = write operation
  1045. Arg3: previous mode.
  1046. Arg4: 4.
  1047. */
  1048. {
  1049. DEBUG_POOL_DATA PoolData;
  1050. Analysis->SetUlong64(Bc->Args[1] ?
  1051. DEBUG_FLR_WRITE_ADDRESS : DEBUG_FLR_READ_ADDRESS,
  1052. Bc->Args[0]);
  1053. Analysis->SetUlong64(DEBUG_FLR_PREVIOUS_MODE, Bc->Args[2]);
  1054. }
  1055. DECL_GETINFO( TIMER_OR_DPC_INVALID ) // (c7)
  1056. /*
  1057. *
  1058. * This is issued if a kernel timer or DPC is found somewhere in
  1059. * memory where it is not permitted.
  1060. *
  1061. * Bugcheck Parameters
  1062. *
  1063. * Parameter 1 0: Timer object 1: DPC object 2: DPC routine
  1064. * Parameter 2 Address of object
  1065. * Parameter 3 Beginning of memory range checked
  1066. * Parameter 4 End of memory range checked
  1067. *
  1068. * This condition is usually caused by a driver failing to cancel a
  1069. * timer or DPC before freeing the memory where it resides.
  1070. */
  1071. {
  1072. ULONG PtrSize = IsPtr64() ? 8 : 4;
  1073. ULONG64 ObjAddress;
  1074. CHAR Buffer[MAX_PATH];
  1075. ULONG64 Disp;
  1076. ObjAddress = Bc->Args[1];
  1077. switch (Bc->Args[0]) {
  1078. case 0: //Timer object
  1079. ULONG DpcOffsetInTimer;
  1080. if (GetFieldOffset("nt!_KTIMER", "Dpc", &DpcOffsetInTimer))
  1081. {
  1082. // we don't have types
  1083. DpcOffsetInTimer = 0x10 + PtrSize*4;
  1084. }
  1085. if (!ReadPointer(ObjAddress + DpcOffsetInTimer, &ObjAddress))
  1086. {
  1087. // fail
  1088. break;
  1089. }
  1090. // Fall thru
  1091. case 1:
  1092. ULONG DeferredRoutinOffsetInKDPC;
  1093. if (GetFieldOffset("nt!_KDPC", "DeferredRoutine", &DeferredRoutinOffsetInKDPC))
  1094. {
  1095. DeferredRoutinOffsetInKDPC = 4 + PtrSize*2;
  1096. }
  1097. if (!ReadPointer(ObjAddress + DeferredRoutinOffsetInKDPC, &ObjAddress))
  1098. {
  1099. // fail
  1100. break;
  1101. }
  1102. // Fall thru
  1103. case 2:
  1104. if (FaGetSymbol(ObjAddress, Buffer, &Disp, sizeof(Buffer)))
  1105. {
  1106. Analysis->SetUlong64(DEBUG_FLR_INVALID_DPC_FOUND, ObjAddress);
  1107. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, ObjAddress);
  1108. }
  1109. break;
  1110. }
  1111. }
  1112. DECL_GETINFO( DRIVER_VERIFIER_IOMANAGER_VIOLATION ) // (c9)
  1113. {
  1114. ULONG64 DeviceObject = 0;
  1115. Analysis->SetUlong64(DEBUG_FLR_DRIVER_VERIFIER_IO_VIOLATION_TYPE,
  1116. Bc->Args[0]);
  1117. switch (Bc->Args[0])
  1118. {
  1119. case 0x1:
  1120. // "Invalid IRP passed to IoFreeIrp";
  1121. case 0x2:
  1122. // "IRP still associated with a thread at IoFreeIrp";
  1123. case 0x3:
  1124. // "Invalid IRP passed to IoCallDriver";
  1125. Analysis->SetUlong64(DEBUG_FLR_IRP_ADDRESS, Bc->Args[1]);
  1126. break;
  1127. case 0x4:
  1128. // "Invalid Device object passed to IoCallDriver";
  1129. DeviceObject = Bc->Args[1];
  1130. break;
  1131. case 0x5:
  1132. // "Irql not equal across call to the driver dispatch routine"
  1133. DeviceObject = Bc->Args[1];
  1134. Analysis->SetUlong64(DEBUG_FLR_PREVIOUS_IRQL, Bc->Args[2]);
  1135. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[3]);
  1136. break;
  1137. case 0x6:
  1138. // "IRP passed to IoCompleteRequest contains invalid status"
  1139. // Param 1 = "the status";
  1140. Analysis->SetUlong64(DEBUG_FLR_IRP_ADDRESS, Bc->Args[2]);
  1141. break;
  1142. case 0x7:
  1143. // "IRP passed to IoCompleteRequest still has cancel routine"
  1144. Analysis->SetUlong64(DEBUG_FLR_IRP_CANCEL_ROUTINE, Bc->Args[1]);
  1145. Analysis->SetUlong64(DEBUG_FLR_IRP_ADDRESS, Bc->Args[2]);
  1146. break;
  1147. case 0x8:
  1148. // "Call to IoBuildAsynchronousFsdRequest threw an exce
  1149. DeviceObject = Bc->Args[1];
  1150. Analysis->SetUlong64(DEBUG_FLR_IRP_MAJOR_FN, Bc->Args[2]);
  1151. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_CODE, Bc->Args[3]);
  1152. break;
  1153. case 0x9:
  1154. // "Call to IoBuildDeviceIoControlRequest threw an exce
  1155. DeviceObject = Bc->Args[1];
  1156. Analysis->SetUlong64(DEBUG_FLR_IOCONTROL_CODE, Bc->Args[2]);
  1157. Analysis->SetUlong64(DEBUG_FLR_EXCEPTION_CODE, Bc->Args[3]);
  1158. break;
  1159. case 0x10:
  1160. // "Reinitialization of Device object timer";
  1161. DeviceObject = Bc->Args[1];
  1162. break;
  1163. case 0x12:
  1164. // "Invalid IOSB in IRP at APC IopCompleteRequest (appe
  1165. Analysis->SetUlong64(DEBUG_FLR_IOSB_ADDRESS, Bc->Args[1]);
  1166. break;
  1167. case 0x13:
  1168. // "Invalid UserEvent in IRP at APC IopCompleteRequest
  1169. Analysis->SetUlong64(DEBUG_FLR_INVALID_USEREVENT, Bc->Args[1]);
  1170. break;
  1171. case 0x14:
  1172. // "Irql > DPC at IoCompleteRequest";
  1173. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  1174. Analysis->SetUlong64(DEBUG_FLR_IRP_ADDRESS, Bc->Args[2]);
  1175. break;
  1176. }
  1177. if (DeviceObject)
  1178. {
  1179. Analysis->SetUlong64(DEBUG_FLR_DEVICE_OBJECT, DeviceObject);
  1180. BcGetDriverNameFromIrp(Analysis, 0, DeviceObject, 0);
  1181. }
  1182. }
  1183. DECL_GETINFO( PNP_DETECTED_FATAL_ERROR ) // 0xca
  1184. {
  1185. CHAR BugCheckStr[20];
  1186. ULONG64 DeviceObject;
  1187. sprintf(BugCheckStr, "0x%lX_%lX", Bc->Code, Bc->Args[0]);
  1188. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  1189. DeviceObject = Bc->Args[1];
  1190. if (DeviceObject)
  1191. {
  1192. Analysis->SetUlong64(DEBUG_FLR_DEVICE_OBJECT, DeviceObject);
  1193. BcGetDriverNameFromIrp(Analysis, 0, DeviceObject, 0);
  1194. }
  1195. }
  1196. DECL_GETINFO( DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS ) // 0xcb
  1197. {
  1198. Analysis->SetUlong64(DEBUG_FLR_FAULTING_MODULE, Bc->Args[0]);
  1199. }
  1200. DECL_GETINFO( DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS ) //0xce
  1201. {
  1202. Analysis->SetUlong64(Bc->Args[1] ?
  1203. DEBUG_FLR_WRITE_ADDRESS : DEBUG_FLR_READ_ADDRESS,
  1204. Bc->Args[0]);
  1205. if (Bc->Args[2]) {
  1206. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[2]);
  1207. }
  1208. }
  1209. DECL_GETINFO( DRIVER_CORRUPTED_MMPOOL ) // 0xd0
  1210. {
  1211. Analysis->SetUlong64(Bc->Args[2] ?
  1212. DEBUG_FLR_WRITE_ADDRESS : DEBUG_FLR_READ_ADDRESS,
  1213. Bc->Args[0]);
  1214. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Bc->Args[1]);
  1215. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[3]);
  1216. }
  1217. //DUPINFOCASE( PAGE_FAULT_IN_FREED_SPECIAL_POOL ); // 0xCC
  1218. //DUPINFOCASE( PAGE_FAULT_BEYOND_END_OF_ALLOCATION ); // 0xCD
  1219. //DUPINFOCASE( TERMINAL_SERVER_DRIVER_MADE_INCORRECT_MEMORY_REFERENCE ); // 0xCF
  1220. //DUPINFOCASE( PAGE_FAULT_IN_NONPAGED_AREA ) // 0x50
  1221. //DUPINFOCASE( DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION ) // 0xD6
  1222. DECL_GETINFO( DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL ) // 0xD5
  1223. /*
  1224. * Parameters
  1225. *
  1226. * Parameter 1 Memory referenced
  1227. * Parameter 2 0: Read 1: Write
  1228. * Parameter 3 Address that referenced memory (if known)
  1229. * Parameter 4 Reserved
  1230. *
  1231. */
  1232. {
  1233. CHAR BugCheckStr[30];
  1234. Analysis->SetUlong64(Bc->Args[1] ?
  1235. DEBUG_FLR_WRITE_ADDRESS : DEBUG_FLR_READ_ADDRESS,
  1236. Bc->Args[0]);
  1237. if (Bc->Args[2]) {
  1238. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[2]);
  1239. }
  1240. Analysis->SetUlong64(DEBUG_FLR_MM_INTERNAL_CODE, Bc->Args[3]);
  1241. if (Bc->Args[0] == Bc->Args[2] &&
  1242. Bc->Args[1] == 0)
  1243. {
  1244. Analysis->SetString(DEBUG_FLR_BUGCHECK_SPECIFIER, "_CODE_AV");
  1245. }
  1246. AddBugcheckDriver(Analysis, TRUE, TRUE, 0);
  1247. }
  1248. DECL_GETINFO( MANUALLY_INITIATED_CRASH ) //0xE2, 0xDEADDEAD
  1249. {
  1250. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, "MANUALLY_INITIATED_CRASH");
  1251. }
  1252. DECL_GETINFO( THREAD_STUCK_IN_DEVICE_DRIVER ) // 0xEA
  1253. /*
  1254. * PARAMETERS:
  1255. *
  1256. * 1 - Pointer to a stuck thread object. Do .thread then kb on it to
  1257. * find hung location.
  1258. *
  1259. * 2 - Pointer to a DEFERRED_WATCHDOG object.
  1260. *
  1261. * 3 - Pointer to offending driver name.
  1262. *
  1263. * 4 - Number of times "intercepted" bugcheck 0xEA was hit (see notes).
  1264. */
  1265. {
  1266. Analysis->SetUlong64(DEBUG_FLR_FOLLOWUP_DRIVER_ONLY, 0);
  1267. Analysis->SetUlong64(DEBUG_FLR_FAULTING_THREAD, Bc->Args[0]);
  1268. Analysis->SetString(DEBUG_FLR_DEFAULT_BUCKET_ID, "GRAPHICS_DRIVER_FAULT");
  1269. }
  1270. DECL_GETINFO( CRITICAL_PROCESS_DIED ) // (0xef)
  1271. {
  1272. Analysis->SetUlong64(DEBUG_FLR_PROCESS_OBJECT, Bc->Args[0]);
  1273. }
  1274. DECL_GETINFO( CRITICAL_OBJECT_TERMINATION ) // (0xf4)
  1275. {
  1276. if (Bc->Args[0] == 3)
  1277. {
  1278. ULONG result;
  1279. CHAR ImageName[MAX_PATH];
  1280. Analysis->SetUlong64(DEBUG_FLR_PROCESS_OBJECT, Bc->Args[1]);
  1281. //
  1282. // Second parameter (which is actually a string within the EPROCESS)
  1283. // is the name of the image.
  1284. //
  1285. if (ReadMemory(Bc->Args[2], ImageName, sizeof(ImageName), &result) &&
  1286. result)
  1287. {
  1288. ImageName[MAX_PATH-1]=0;
  1289. ImageName[result]=0;
  1290. SaveImageName(Analysis, ImageName);
  1291. }
  1292. }
  1293. }
  1294. DECL_GETINFO( WINLOGON_FATAL_ERROR ) //(c000021a)
  1295. {
  1296. CHAR BugCheckStr[20];
  1297. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, Bc->Args[1]);
  1298. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  1299. }
  1300. DECL_GETINFO( STATUS_DRIVER_UNABLE_TO_LOAD ) //0xc0000xxx
  1301. {
  1302. if (Bc->Args[0])
  1303. {
  1304. AddBugcheckDriver(Analysis, FALSE, FALSE, Bc->Args[0]);
  1305. }
  1306. }
  1307. DECL_GETINFO( ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY ) // (0xFC)
  1308. {
  1309. if (Bc->Args[0])
  1310. {
  1311. Analysis->SetUlong64(DEBUG_FLR_FAULTING_IP, Bc->Args[0]);
  1312. }
  1313. // Add bugcheck driver from KiBugCheckDriver
  1314. AddBugcheckDriver(Analysis, TRUE, TRUE, 0);
  1315. }
  1316. DECL_GETINFO( UNMOUNTABLE_BOOT_VOLUME ) // 0xED
  1317. {
  1318. CHAR BugCheckStr[20];
  1319. sprintf(BugCheckStr, "0x%lx_%lx", Bc->Code, (ULONG) Bc->Args[1]);
  1320. Analysis->SetUlong(DEBUG_FLR_STATUS_CODE, (ULONG) Bc->Args[1]);
  1321. switch ((ULONG) Bc->Args[1])
  1322. {
  1323. case 0xC0000006:
  1324. Analysis->SetUlong(DEBUG_FLR_SHOW_ERRORLOG, 1);
  1325. break;
  1326. default:
  1327. break;
  1328. }
  1329. }
  1330. #define GETINFOCASE(bcname) \
  1331. case bcname : \
  1332. GetInfoFor##bcname (Bc, Analysis); \
  1333. break;
  1334. #define DUPINFOCASE(bcname) \
  1335. case bcname:
  1336. void
  1337. BcFillAnalysis(
  1338. PBUGCHECK_ANALYSIS Bc,
  1339. KernelDebugFailureAnalysis* Analysis
  1340. )
  1341. {
  1342. Analysis->SetFailureClass(DEBUG_CLASS_KERNEL);
  1343. HRESULT Status = Analysis->CheckModuleSymbols("nt", "Kernel");
  1344. if (Status != S_OK)
  1345. {
  1346. goto SkipBucheckSpecificProcessing;
  1347. }
  1348. //
  1349. // BBT Breaks the stack trace for builds > 2201
  1350. // Hack the return address for better results
  1351. // A new of routines are at the wrong addresses.
  1352. //
  1353. if ((g_TargetMachine == IMAGE_FILE_MACHINE_I386) &&
  1354. (g_TargetBuild > 2500) && (g_TargetBuild < 2507))
  1355. {
  1356. DEBUG_STACK_FRAME Stk[MAX_STACK_FRAMES];
  1357. ULONG Frames = 0;
  1358. if (S_OK == g_ExtControl->GetStackTrace(0, 0, 0, Stk, MAX_STACK_FRAMES,
  1359. &Frames) &&
  1360. FaIsFunctionAddr(Stk[0].InstructionOffset, "KeBugCheckEx"))
  1361. {
  1362. ULONG CallIP = (ULONG) Stk[1].InstructionOffset - 5, Res;
  1363. UCHAR Instr;
  1364. // Move the caller's IP back to the actual KeBugCheckEx
  1365. // call. Only do this if we haven't already backed up
  1366. // to a call instruction.
  1367. if (!ReadMemory(Stk[1].InstructionOffset, &Instr, sizeof(Instr),
  1368. &Res) ||
  1369. Res != sizeof(Instr) ||
  1370. Instr != 0xe8)
  1371. {
  1372. WriteMemory(Stk[0].FrameOffset + 4, &CallIP, sizeof(CallIP),
  1373. &Res);
  1374. g_ExtControl->GetStackTrace(0, 0, 0, Stk, MAX_STACK_FRAMES,
  1375. &Frames);
  1376. }
  1377. }
  1378. }
  1379. //
  1380. // Special value that is set by the kernel debugger so we can detect when
  1381. // people are messing with physical address via the kernel debugger.
  1382. //
  1383. ULONG64 MmPoisonedTbAddr;
  1384. MmPoisonedTbAddr = GetExpression("nt!MmPoisonedTb");
  1385. if (MmPoisonedTbAddr)
  1386. {
  1387. ULONG cb;
  1388. ULONG MmPoisonedTb = 0;
  1389. if (ReadMemory(MmPoisonedTbAddr, &MmPoisonedTb, sizeof(ULONG), &cb) &&
  1390. (MmPoisonedTb != 0))
  1391. {
  1392. Analysis->SetUlong64(DEBUG_FLR_POISONED_TB, 0);
  1393. }
  1394. }
  1395. SkipBucheckSpecificProcessing:
  1396. Analysis->SetFailureType(DEBUG_FLR_KERNEL);
  1397. switch (Bc->Code)
  1398. {
  1399. case 0:
  1400. ULONG c_ip;
  1401. //
  1402. // This can be a user mode failurein kd. Try to determine that.
  1403. //
  1404. if ( (GetExpression("@$ip") < BcTargetKernelAddressStart()) &&
  1405. (GetExpression("@$sp") < BcTargetKernelAddressStart()) )
  1406. {
  1407. Analysis->SetFailureType(DEBUG_FLR_USER_CRASH);
  1408. g_ExtControl->Execute(DEBUG_OUTCTL_IGNORE, ".reload /user",
  1409. DEBUG_EXECUTE_NOT_LOGGED);
  1410. }
  1411. break;
  1412. GETINFOCASE( DRIVER_CAUGHT_MODIFYING_FREED_POOL );
  1413. DUPINFOCASE( PAGE_FAULT_IN_FREED_SPECIAL_POOL );
  1414. DUPINFOCASE( PAGE_FAULT_BEYOND_END_OF_ALLOCATION );
  1415. DUPINFOCASE( TERMINAL_SERVER_DRIVER_MADE_INCORRECT_MEMORY_REFERENCE );
  1416. DUPINFOCASE( PAGE_FAULT_IN_NONPAGED_AREA );
  1417. DUPINFOCASE( DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION );
  1418. GETINFOCASE( DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL );
  1419. GETINFOCASE( DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS );
  1420. GETINFOCASE( DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS );
  1421. GETINFOCASE( DRIVER_VERIFIER_IOMANAGER_VIOLATION );
  1422. DUPINFOCASE( DRIVER_IRQL_NOT_LESS_OR_EQUAL );
  1423. GETINFOCASE( IRQL_NOT_LESS_OR_EQUAL );
  1424. GETINFOCASE( PANIC_STACK_SWITCH );
  1425. GETINFOCASE( KMODE_EXCEPTION_NOT_HANDLED );
  1426. GETINFOCASE( SYSTEM_SERVICE_EXCEPTION );
  1427. GETINFOCASE( ACPI_BIOS_ERROR );
  1428. GETINFOCASE( USER_MODE_HEALTH_MONITOR );
  1429. GETINFOCASE( MEMORY_MANAGEMENT );
  1430. DUPINFOCASE( KERNEL_MODE_EXCEPTION_NOT_HANDLED_M );
  1431. GETINFOCASE( KERNEL_MODE_EXCEPTION_NOT_HANDLED );
  1432. DUPINFOCASE( SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M );
  1433. GETINFOCASE( SYSTEM_THREAD_EXCEPTION_NOT_HANDLED );
  1434. GETINFOCASE( SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION );
  1435. GETINFOCASE( KERNEL_STACK_INPAGE_ERROR );
  1436. GETINFOCASE( KERNEL_DATA_INPAGE_ERROR );
  1437. GETINFOCASE( TIMER_OR_DPC_INVALID );
  1438. DUPINFOCASE( UNEXPECTED_KERNEL_MODE_TRAP_M );
  1439. GETINFOCASE( UNEXPECTED_KERNEL_MODE_TRAP );
  1440. GETINFOCASE( MULTIPLE_IRP_COMPLETE_REQUESTS );
  1441. GETINFOCASE( WINLOGON_FATAL_ERROR );
  1442. DUPINFOCASE( RDR_FILE_SYSTEM );
  1443. DUPINFOCASE( UDFS_FILE_SYSTEM );
  1444. DUPINFOCASE( CDFS_FILE_SYSTEM );
  1445. DUPINFOCASE( NTFS_FILE_SYSTEM );
  1446. GETINFOCASE( FAT_FILE_SYSTEM );
  1447. DUPINFOCASE( STATUS_DRIVER_ENTRYPOINT_NOT_FOUND );
  1448. DUPINFOCASE( STATUS_PROCEDURE_NOT_FOUND );
  1449. DUPINFOCASE( STATUS_DRIVER_ORDINAL_NOT_FOUND );
  1450. GETINFOCASE( STATUS_DRIVER_UNABLE_TO_LOAD );
  1451. GETINFOCASE( PNP_DETECTED_FATAL_ERROR );
  1452. GETINFOCASE( MACHINE_CHECK_EXCEPTION );
  1453. GETINFOCASE( DRIVER_POWER_STATE_FAILURE );
  1454. DUPINFOCASE( THREAD_STUCK_IN_DEVICE_DRIVER_M );
  1455. GETINFOCASE( THREAD_STUCK_IN_DEVICE_DRIVER );
  1456. GETINFOCASE( SESSION3_INITIALIZATION_FAILED );
  1457. GETINFOCASE( DRIVER_VERIFIER_DETECTED_VIOLATION );
  1458. GETINFOCASE( CRITICAL_OBJECT_TERMINATION );
  1459. GETINFOCASE( CRITICAL_PROCESS_DIED );
  1460. GETINFOCASE( PROCESS_HAS_LOCKED_PAGES );
  1461. DUPINFOCASE( MANUALLY_INITIATED_CRASH1 );
  1462. GETINFOCASE( MANUALLY_INITIATED_CRASH );
  1463. GETINFOCASE( BAD_POOL_CALLER );
  1464. DUPINFOCASE( DRIVER_CORRUPTED_SYSPTES );
  1465. DUPINFOCASE( SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD )
  1466. DUPINFOCASE( DRIVER_PORTION_MUST_BE_NONPAGED );
  1467. GETINFOCASE( DRIVER_CORRUPTED_MMPOOL );
  1468. default:
  1469. break;
  1470. }
  1471. if (!Analysis->GetFailureCode())
  1472. {
  1473. //
  1474. // We ignore the top bit when setting the internal failure code
  1475. // so we can bucket things togeter appropriately.
  1476. // The top bit only represent a dump generation difference, not
  1477. // a root cause difference.
  1478. //
  1479. Analysis->SetFailureCode(Bc->Code & ~0x10000000);
  1480. }
  1481. if (!Analysis->Get(DEBUG_FLR_DEFAULT_BUCKET_ID))
  1482. {
  1483. if (Analysis->GetFailureType() == DEBUG_FLR_USER_CRASH)
  1484. {
  1485. Analysis->SetString(DEBUG_FLR_DEFAULT_BUCKET_ID, "APPLICATION_FAULT");
  1486. }
  1487. else
  1488. {
  1489. Analysis->SetString(DEBUG_FLR_DEFAULT_BUCKET_ID, "DRIVER_FAULT");
  1490. }
  1491. }
  1492. if (!Analysis->Get(DEBUG_FLR_BUGCHECK_STR))
  1493. {
  1494. CHAR BugCheckStr[12];
  1495. sprintf(BugCheckStr, "0x%lX", Analysis->GetFailureCode());
  1496. Analysis->SetString(DEBUG_FLR_BUGCHECK_STR, BugCheckStr);
  1497. if (Analysis->Get(DEBUG_FLR_WRITE_ADDRESS))
  1498. {
  1499. Analysis->SetString(DEBUG_FLR_BUGCHECK_SPECIFIER, "_W");
  1500. }
  1501. }
  1502. //
  1503. // Save the current IRQL.
  1504. //
  1505. if (g_TargetBuild > 2600)
  1506. {
  1507. PROCESSORINFO ProcInfo;
  1508. ULONG64 Prcb;
  1509. ULONG64 Irql = 0;
  1510. HRESULT Hr;
  1511. if (Ioctl(IG_KD_CONTEXT, &ProcInfo, sizeof(ProcInfo)))
  1512. {
  1513. Hr = g_ExtData->ReadProcessorSystemData(ProcInfo.Processor,
  1514. DEBUG_DATA_KPRCB_OFFSET,
  1515. &Prcb,
  1516. sizeof(Prcb),
  1517. NULL);
  1518. if (Hr == S_OK && Prcb)
  1519. {
  1520. if (!GetFieldValue(Prcb, "nt!_KPRCB", "DebuggerSavedIRQL", Irql))
  1521. {
  1522. Analysis->SetUlong64(DEBUG_FLR_CURRENT_IRQL, Irql);
  1523. }
  1524. }
  1525. }
  1526. }
  1527. ULONG64 Irp;
  1528. if (Analysis->GetUlong64(DEBUG_FLR_IRP_ADDRESS, &Irp))
  1529. {
  1530. BcGetDriverNameFromIrp(Analysis, Irp, 0, 0);
  1531. }
  1532. //
  1533. // Generic processing
  1534. //
  1535. Analysis->ProcessInformation();
  1536. }
  1537. void
  1538. ReadWatchDogBugcheck(
  1539. PBUGCHECK_ANALYSIS Bc
  1540. )
  1541. {
  1542. // Check if this could be a watchdog bugcheck
  1543. // Read watchdog!g_WdBugCheckData
  1544. ULONG64 wdBugcheck;
  1545. ULONG res;
  1546. ULONG PtrSize = IsPtr64() ? 8 : 4;
  1547. wdBugcheck = GetExpression("watchdog!g_WdBugCheckData");
  1548. if (wdBugcheck)
  1549. {
  1550. wdBugcheck = GetExpression("VIDEOPRT!g_WdpBugCheckData");
  1551. }
  1552. if (wdBugcheck)
  1553. {
  1554. ReadMemory(wdBugcheck, &Bc->Code, sizeof(ULONG), &res);
  1555. ReadPointer(wdBugcheck + PtrSize,&Bc->Args[0]);
  1556. ReadPointer(wdBugcheck + 2*PtrSize,&Bc->Args[1]);
  1557. ReadPointer(wdBugcheck + 3*PtrSize,&Bc->Args[2]);
  1558. ReadPointer(wdBugcheck + 4*PtrSize,&Bc->Args[3]);
  1559. }
  1560. }
  1561. KernelDebugFailureAnalysis*
  1562. BcAnalyze(
  1563. OUT PBUGCHECK_ANALYSIS Bc,
  1564. ULONG Flags
  1565. )
  1566. {
  1567. if (g_ExtControl->ReadBugCheckData(&Bc->Code, &Bc->Args[0], &Bc->Args[1],
  1568. &Bc->Args[2], &Bc->Args[3]) != S_OK)
  1569. {
  1570. return NULL;
  1571. }
  1572. if (Bc->Code == 0)
  1573. {
  1574. ReadWatchDogBugcheck(Bc);
  1575. }
  1576. KernelDebugFailureAnalysis* Analysis = new KernelDebugFailureAnalysis;
  1577. if (Analysis)
  1578. {
  1579. Analysis->SetProcessingFlags(Flags);
  1580. __try
  1581. {
  1582. BcFillAnalysis(Bc, Analysis);
  1583. }
  1584. __except(FaExceptionFilter(GetExceptionInformation()))
  1585. {
  1586. delete Analysis;
  1587. Analysis = NULL;
  1588. }
  1589. }
  1590. return Analysis;
  1591. }
  1592. HRESULT
  1593. AnalyzeBugCheck(
  1594. PCSTR args
  1595. )
  1596. {
  1597. KernelDebugFailureAnalysis* Analysis;
  1598. BUGCHECK_ANALYSIS Bc = {0};
  1599. BOOL Dump = TRUE;
  1600. ULONG Flags = 0;
  1601. DEBUG_FLR_PARAM_TYPE Params[10];
  1602. ULONG ParamCount = 0;
  1603. if (g_TargetClass != DEBUG_CLASS_KERNEL) {
  1604. dprintf("!analyzebugcheck is for kernel mode only\n");
  1605. return E_FAIL;
  1606. }
  1607. for (;;)
  1608. {
  1609. while (*args == ' ' || *args == '\t')
  1610. {
  1611. args++;
  1612. }
  1613. if (*args == '-')
  1614. {
  1615. ++args;
  1616. switch(*args)
  1617. {
  1618. case 'D':
  1619. {
  1620. CHAR ParamString[100];
  1621. ULONG ParamLength = 0;
  1622. args+=2;
  1623. while(*args && *args != ' ' && *args != '\t')
  1624. {
  1625. ParamString[ParamLength++] = *args++;
  1626. }
  1627. ParamString[ParamLength] = 0;
  1628. //
  1629. // Match the string to the actual failure ID.
  1630. //
  1631. ULONG i=0;
  1632. while(FlrLookupTable[i].Data &&
  1633. strcmp(FlrLookupTable[i].String, ParamString))
  1634. {
  1635. i++;
  1636. }
  1637. Params[ParamCount++] = FlrLookupTable[i].Data;
  1638. break;
  1639. }
  1640. case 'n':
  1641. if (!strncmp(args, "nodb",4))
  1642. {
  1643. args+=4;
  1644. Flags |= FAILURE_ANALYSIS_NO_DB_LOOKUP;
  1645. }
  1646. break;
  1647. case 's':
  1648. if (!strncmp(args, "show",4))
  1649. {
  1650. ULONG64 Code;
  1651. args+=4;
  1652. GetExpressionEx(args, &Code, &args);
  1653. Bc.Code = (ULONG)Code;
  1654. for (ULONG i=0; i<4 && *args; i++)
  1655. {
  1656. if (!GetExpressionEx(args, &Bc.Args[i], &args))
  1657. {
  1658. break;
  1659. }
  1660. }
  1661. GetBugCheckDescription(&Bc);
  1662. PrintBugDescription(&Bc);
  1663. return S_OK;
  1664. }
  1665. case 'v':
  1666. Flags |= FAILURE_ANALYSIS_VERBOSE;
  1667. break;
  1668. case 'f':
  1669. break;
  1670. default:
  1671. {
  1672. CHAR Option[2];
  1673. Option[0] = *args; Option[1] = 0;
  1674. dprintf("\nUnknown option '-%s'\n", Option );
  1675. break;
  1676. }
  1677. }
  1678. if (*args == 0)
  1679. {
  1680. break;
  1681. }
  1682. ++args;
  1683. }
  1684. else
  1685. {
  1686. break;
  1687. }
  1688. }
  1689. g_ExtControl->ReadBugCheckData(&Bc.Code, &Bc.Args[0], &Bc.Args[1],
  1690. &Bc.Args[2], &Bc.Args[3]);
  1691. if (Bc.Code == 0)
  1692. {
  1693. ReadWatchDogBugcheck(&Bc);
  1694. }
  1695. if (!ParamCount)
  1696. {
  1697. dprintf("*******************************************************************************\n");
  1698. dprintf("* *\n");
  1699. dprintf("* Bugcheck Analysis *\n");
  1700. dprintf("* *\n");
  1701. dprintf("*******************************************************************************\n");
  1702. dprintf("\n");
  1703. if (Flags & FAILURE_ANALYSIS_VERBOSE)
  1704. {
  1705. GetBugCheckDescription(&Bc);
  1706. PrintBugDescription(&Bc);
  1707. dprintf("\nDebugging Details:\n------------------\n\n");
  1708. }
  1709. else
  1710. {
  1711. dprintf("Use !analyze -v to get detailed debugging information.\n\n");
  1712. dprintf("BugCheck %lX, {%1p, %1p, %1p, %1p}\n\n",
  1713. Bc.Code,
  1714. Bc.Args[0],Bc.Args[1],Bc.Args[2],Bc.Args[3]);
  1715. }
  1716. }
  1717. Analysis = BcAnalyze(&Bc, Flags);
  1718. if (!Analysis)
  1719. {
  1720. dprintf("\n\nFailure could not be analyzed\n\n");
  1721. return E_FAIL;
  1722. }
  1723. if (ParamCount)
  1724. {
  1725. while(ParamCount--)
  1726. {
  1727. Analysis->OutputEntryParam(Params[ParamCount]);
  1728. }
  1729. }
  1730. //
  1731. // Always call output so we can key information printed out also, such
  1732. // as *** entries.
  1733. //
  1734. Analysis->Output();
  1735. delete Analysis;
  1736. return S_OK;
  1737. }
  1738. //----------------------------------------------------------------------------
  1739. //
  1740. // KernelDebugFailureAnalysis.
  1741. //
  1742. //----------------------------------------------------------------------------
  1743. KernelDebugFailureAnalysis::KernelDebugFailureAnalysis(void)
  1744. : m_KernelModule("nt")
  1745. {
  1746. }
  1747. DEBUG_POOL_REGION
  1748. KernelDebugFailureAnalysis::GetPoolForAddress(ULONG64 Addr)
  1749. {
  1750. PGET_POOL_REGION GetPoolRegion = NULL;
  1751. if (g_ExtControl->
  1752. GetExtensionFunction(0, "GetPoolRegion",
  1753. (FARPROC*)&GetPoolRegion) == S_OK &&
  1754. GetPoolRegion)
  1755. {
  1756. DEBUG_POOL_REGION RegionId;
  1757. (*GetPoolRegion)(g_ExtClient, Addr, &RegionId);
  1758. return RegionId;
  1759. }
  1760. return DbgPoolRegionUnknown;
  1761. }
  1762. PCSTR
  1763. KernelDebugFailureAnalysis::DescribeAddress(ULONG64 Addr)
  1764. {
  1765. DEBUG_POOL_REGION RegionId = GetPoolForAddress(Addr);
  1766. if ((RegionId != DbgPoolRegionUnknown) &&
  1767. (RegionId < DbgPoolRegionMax))
  1768. {
  1769. return g_PoolRegion[RegionId];
  1770. }
  1771. return NULL;
  1772. }
  1773. FOLLOW_ADDRESS
  1774. KernelDebugFailureAnalysis::IsPotentialFollowupAddress(ULONG64 Address)
  1775. {
  1776. CHAR Buffer[MAX_PATH];
  1777. ULONG64 Disp;
  1778. //
  1779. // Check for special symbols which indicate we are transitioning back
  1780. // to user mode code, so the rest of the stack can not be at fault.
  1781. //
  1782. if (GetFailureType() == DEBUG_FLR_USER_CRASH)
  1783. {
  1784. return FollowYes;
  1785. }
  1786. if (FaGetSymbol(Address, Buffer, &Disp, sizeof(Buffer)) &&
  1787. (!_strcmpi(Buffer, "nt!KiCallUserMode") ||
  1788. !_strcmpi(Buffer, "SharedUserData!SystemCallStub")))
  1789. {
  1790. return FollowStop;
  1791. }
  1792. if (Address > BcTargetKernelAddressStart())
  1793. {
  1794. return FollowYes;
  1795. }
  1796. else
  1797. {
  1798. //
  1799. // We don't stop on user mode addresses because they could be
  1800. // garbage on the stack we - just skip them
  1801. //
  1802. return FollowSkip;
  1803. }
  1804. }
  1805. FOLLOW_ADDRESS
  1806. KernelDebugFailureAnalysis::IsFollowupContext(ULONG64 Address1,
  1807. ULONG64 Address2,
  1808. ULONG64 Address3)
  1809. {
  1810. // If it's a user mode address, and a dump file, it's not a valid
  1811. // context.
  1812. // A user mode address is valid for a kernel mode context because
  1813. // a hardcoded breakpoint from user mode with kd active will show up
  1814. // on the stack.
  1815. if ( (Address1 < BcTargetKernelAddressStart()) &&
  1816. (Address2 < BcTargetKernelAddressStart()) &&
  1817. (Address3 < BcTargetKernelAddressStart()) )
  1818. {
  1819. if ((g_TargetQualifier == DEBUG_DUMP_SMALL) ||
  1820. (g_TargetQualifier == DEBUG_DUMP_DEFAULT) ||
  1821. (g_TargetQualifier == DEBUG_DUMP_FULL))
  1822. {
  1823. return FollowStop;
  1824. }
  1825. }
  1826. return FollowYes;
  1827. }
  1828. FlpClasses
  1829. KernelDebugFailureAnalysis::GetFollowupClass(ULONG64 Address,
  1830. PCSTR Module, PCSTR Routine)
  1831. {
  1832. if (m_KernelModule.Contains(Address) ||
  1833. !_strcmpi(Module, "ntfs") ||
  1834. !_strcmpi(Module, "fastfat"))
  1835. {
  1836. return FlpOSRoutine;
  1837. }
  1838. else if (!_strcmpi(Module, "sr") ||
  1839. !_strcmpi(Module, "ndis") ||
  1840. !_strcmpi(Module, "videoprt") ||
  1841. !_strcmpi(Module, "USBPORT") ||
  1842. !_strcmpi(Module, "USBHUB") ||
  1843. !_strcmpi(Module, "dxg") ||
  1844. !_strcmpi(Module, "win32k") ||
  1845. !_strcmpi(Module, "verifier") ||
  1846. !_strcmpi(Module, "scsiport"))
  1847. {
  1848. return FlpOSFilterDrv;
  1849. }
  1850. else if (!_strcmpi(Module, "SharedUserData") &&
  1851. Routine && !_strcmpi(Routine, "SystemCallStub"))
  1852. {
  1853. // Do not followup on usermode calls
  1854. return FlpIgnore;
  1855. }
  1856. else
  1857. {
  1858. return FlpUnknownDrv;
  1859. }
  1860. }
  1861. /*
  1862. * This checks for valid object pointers in HANDLE_TABLE_ENTRY. If the pointers are
  1863. * invalid it tries to figure out who corrupted the values.
  1864. *
  1865. * Reutrns TRUE if it succesfully identifies a memory curruption
  1866. */
  1867. BOOL
  1868. KernelDebugFailureAnalysis::CheckForCorruptionInHTE(
  1869. ULONG64 hTableEntry,
  1870. PCHAR Owner,
  1871. ULONG OwnerSize)
  1872. {
  1873. ULONG64 Object = 0;
  1874. ULONG64 CorruptingPool = 0;
  1875. DEBUG_POOL_REGION Region;
  1876. // hTableEntry must be in PagedPool, but we have
  1877. // a loose check here since GetPoolForAddress is unreliable on
  1878. // minidumps PagedPool
  1879. if (IsPotentialFollowupAddress(hTableEntry) != FollowYes)
  1880. {
  1881. return FALSE;
  1882. }
  1883. if (!ReadPointer(hTableEntry, &Object))
  1884. {
  1885. return FALSE;
  1886. }
  1887. Region = GetPoolForAddress(Object);
  1888. if (IsPotentialFollowupAddress(Object) != FollowYes)
  1889. {
  1890. // Object is invalid, it must be in PagedPool or NonPagedPool
  1891. return AddCorruptingPool(hTableEntry);
  1892. }
  1893. if (InitTypeRead(Object, nt!_OBJECT_HEADER))
  1894. {
  1895. return FALSE;
  1896. }
  1897. ULONG PointerCount, HandleCount;
  1898. ULONG64 ObjType;
  1899. PointerCount = (ULONG) ReadField(PointerCount);
  1900. HandleCount = (ULONG) ReadField(HandleCount);
  1901. ObjType = (ULONG) ReadField(Type);
  1902. // Verify object for inconsistent counts
  1903. // Invalid object type, must be in kernel mode
  1904. if ((PointerCount > 0x10000) ||
  1905. (HandleCount > 0x10000) ||
  1906. (HandleCount > PointerCount) ||
  1907. (IsPotentialFollowupAddress(ObjType) != FollowYes)
  1908. )
  1909. {
  1910. // Object is corrupted, previous pool is a possible corruptor
  1911. AddCorruptingPool(Object);
  1912. }
  1913. else
  1914. {
  1915. return FALSE;
  1916. }
  1917. return TRUE;
  1918. }
  1919. BOOL
  1920. KernelDebugFailureAnalysis::AddCorruptingPool(
  1921. ULONG64 CorruptedPool
  1922. )
  1923. {
  1924. DEBUG_POOL_DATA PoolData = {0};
  1925. PoolData.SizeofStruct = sizeof(DEBUG_POOL_DATA);
  1926. if (ExtGetPoolData(CorruptedPool, &PoolData) != S_OK)
  1927. {
  1928. //
  1929. // Pool block is badly corrupted, loop backwards to find first non-corrupt block
  1930. //
  1931. ULONG PoolHeaderSize = GetTypeSize("nt!_POOL_HEADER");
  1932. ULONG64 PoolAddr;
  1933. for (PoolAddr = CorruptedPool - 2*PoolHeaderSize;
  1934. PoolAddr > (CorruptedPool -0x1000); // Limit to 4KB
  1935. PoolAddr -= 2*PoolHeaderSize)
  1936. {
  1937. if (ExtGetPoolData(PoolAddr, &PoolData) == S_OK)
  1938. {
  1939. goto FoundPool;
  1940. }
  1941. }
  1942. return FALSE;
  1943. } else if (PoolData.Free && !PoolData.Allocated &&
  1944. PoolData.Size != 0)
  1945. {
  1946. // Pool seem to have been correctly freed
  1947. return FALSE;
  1948. } else if (ExtGetPoolData(PoolData.PoolBlock - PoolData.PreviousSize,
  1949. &PoolData) == S_OK)
  1950. // Now get previous pool as it most likely corruptor
  1951. {
  1952. FoundPool:
  1953. CHAR PoolTag[8] = {0};
  1954. SetUlong64(DEBUG_FLR_CORRUPTING_POOL_ADDRESS, PoolData.PoolBlock);
  1955. sprintf(PoolTag,"%c%c%c%c",
  1956. #define PP(x) isprint(((x)&0xff))?((x)&0xff):('.')
  1957. PP(PoolData.PoolTag),
  1958. PP(PoolData.PoolTag >> 8),
  1959. PP(PoolData.PoolTag >> 16),
  1960. PP((PoolData.PoolTag&~0x80000000) >> 24)
  1961. #undef PP
  1962. );
  1963. SetString(DEBUG_FLR_CORRUPTING_POOL_TAG, PoolTag);
  1964. return TRUE;
  1965. }
  1966. return FALSE;
  1967. }
  1968. typedef struct _CHECK_STACK {
  1969. PCHAR* BreakinStk;
  1970. BOOL ValidMatch;
  1971. ULONG MachineType;
  1972. } CHECK_STACK;
  1973. BOOL
  1974. KernelDebugFailureAnalysis::IsManualBreakin(
  1975. PDEBUG_STACK_FRAME Stk,
  1976. ULONG Frames
  1977. )
  1978. //
  1979. // Check stack to see if this is result of manual breakin
  1980. //
  1981. {
  1982. CHAR szBrakFn[100];
  1983. ULONG64 Disp;
  1984. ULONG NumStacks, i, j;
  1985. BOOL NoMatches;
  1986. static PCHAR StkX86CtrlCBreakin1[] = {
  1987. "nt!*Break*",
  1988. "nt!KeUpdateSystemTime",
  1989. "nt!KiIdleLoop",
  1990. NULL,
  1991. };
  1992. static PCHAR StkX86CtrlCBreakin2[] = {
  1993. "nt!*Break*",
  1994. "nt!KeUpdateSystemTime",
  1995. "hal!HalProcessorIdle",
  1996. NULL,
  1997. };
  1998. static PCHAR StkIa64CtrlCBreakin1[] = {
  1999. "nt!KeBreakinBreakpoint",
  2000. "hal!HalpClockInterrupt",
  2001. "nt!KiExternalInterruptHandler",
  2002. "nt!Kil_TopOfIdleLoop",
  2003. NULL,
  2004. };
  2005. static PCHAR StkIa64CtrlCBreakin2[] = {
  2006. "nt!KeBreakinBreakpoint",
  2007. "hal!HalpClockInterrupt",
  2008. "nt!KiExternalInterruptHandler",
  2009. NULL
  2010. };
  2011. CHECK_STACK StksToCheck[] = {
  2012. {StkX86CtrlCBreakin1, TRUE, IMAGE_FILE_MACHINE_I386},
  2013. {StkX86CtrlCBreakin2, TRUE, IMAGE_FILE_MACHINE_I386},
  2014. {StkIa64CtrlCBreakin1, TRUE, IMAGE_FILE_MACHINE_IA64},
  2015. {StkIa64CtrlCBreakin2, TRUE, IMAGE_FILE_MACHINE_IA64},
  2016. };
  2017. //
  2018. // We are looking for:
  2019. // 0 nt!*Break*
  2020. //
  2021. //
  2022. // Assume 3 to 5 frames for a manual breakin stack
  2023. //
  2024. if (Frames < 3 || Frames > 5 || Stk == NULL)
  2025. {
  2026. return FALSE;
  2027. }
  2028. if (FaGetSymbol(Stk[0].InstructionOffset, szBrakFn,
  2029. &Disp, sizeof(szBrakFn)))
  2030. {
  2031. if (!strstr(szBrakFn, "Break"))
  2032. {
  2033. return FALSE;
  2034. }
  2035. } else
  2036. {
  2037. return FALSE;
  2038. }
  2039. NumStacks = sizeof(StksToCheck)/sizeof(CHECK_STACK);
  2040. for (i = 0; i < NumStacks; ++i)
  2041. {
  2042. if (StksToCheck[i].MachineType != g_TargetMachine)
  2043. {
  2044. StksToCheck[i].ValidMatch = FALSE;
  2045. }
  2046. }
  2047. for (j=1;j<Frames;++j)
  2048. {
  2049. NoMatches = TRUE;
  2050. if (FaGetSymbol(Stk[j].InstructionOffset, szBrakFn,
  2051. &Disp, sizeof(szBrakFn)))
  2052. {
  2053. for (i = 0; i < NumStacks; ++i)
  2054. {
  2055. if (StksToCheck[i].ValidMatch)
  2056. {
  2057. if (StksToCheck[i].BreakinStk[j] == NULL)
  2058. {
  2059. StksToCheck[i].ValidMatch = FALSE;
  2060. } else if (strcmp(szBrakFn, StksToCheck[i].BreakinStk[j]))
  2061. {
  2062. StksToCheck[i].ValidMatch = FALSE;
  2063. } else
  2064. {
  2065. // Breakin stack i matck with current stack till frame j
  2066. NoMatches = FALSE;
  2067. }
  2068. }
  2069. }
  2070. }
  2071. if (NoMatches)
  2072. {
  2073. // None of the stacks in StksToCheck match
  2074. return FALSE;
  2075. }
  2076. }
  2077. for (i = 0; i < NumStacks; ++i)
  2078. {
  2079. if (StksToCheck[i].ValidMatch)
  2080. {
  2081. return TRUE;
  2082. }
  2083. }
  2084. return FALSE;
  2085. }
  2086. //
  2087. // Create a new minidump file of this crash
  2088. //
  2089. #if 0
  2090. ULONG FailTime = 0;
  2091. ULONG UpTime = 0;
  2092. CHAR CurrentTime[20];
  2093. CHAR CurrentDate[20];
  2094. CHAR Buffer[MAX_PATH];
  2095. g_ExtControl->GetCurrentTimeDate(&FailTime);
  2096. g_ExtControl->GetCurrentSystemUpTime(&UpTime);
  2097. _strtime(CurrentTime);
  2098. _strdate(CurrentDate);
  2099. if (CurrentTime && UpTime)
  2100. {
  2101. PrintString(Buffer, sizeof(Buffer), "Dump%s-%s-%08lx-%08lx-%s.dmp",
  2102. FailTime, Uptime, Currentdate, CurrentTime);
  2103. Status = g_ExtClient->WriteDumpFile(Buffer ,DEBUG_DUMP_SMALL);
  2104. }
  2105. #endif
  2106. #if 0
  2107. CHAR Buffer[MAX_PATH];
  2108. if (Dump && GetTempFileName(".", "DMP", 0, Buffer))
  2109. {
  2110. Status = g_ExtClient->WriteDumpFile(Buffer ,DEBUG_DUMP_SMALL);
  2111. if (Status == S_OK)
  2112. {
  2113. //
  2114. // We create a file - now lets send it to the database
  2115. //
  2116. //CopyFile(Buffer, "c:\\xxxx", 0);
  2117. DeleteFile(Buffer);
  2118. }
  2119. dprintf("Done.");
  2120. }
  2121. dprintf("\n\n");
  2122. #endif