Pre-Initialization

The pre-initialization phase of crash dump stack initialization occurs during phase 1 initialization of the kernel.  This phase is depicted in the green box in the illustration below.

crashdump_flowchart_vista2

 

The kernel first loads the crashdmp.sys driver.  This driver plays the role of “broker” between the dump port driver (services write requests), crash filter drivers (modify write requests) and the kernel (issues write requests).  The kernel calls crashdmp!DriverEntry with two arguments:  the path to the boot device and a pointer to a global callback table.  The DriverEntry routine fills the callback table, which the kernel uses to complete pre-initialization and post-initialization tasks.  The call stack for this portion of the pre-initialization phase is illustrated below.

  • nt!KiInitializeKernel()
    • nt!IoInitSystem()  OR  nt!NtCreatePagingFile()
      • nt!IoInitializeCrashDump()
        • IopLoadCrashDumpDriver() – loads crashdmp.sys
          • Crashdmp!DriverEntry() – fills crash dump call table

A sample calltable is shown below.

Table Offset* Value
0x0 1
0x4 1
0x8 CrashdmpInitialize
0xc CrashdmpLoadDumpStack
0x10 CrashdmpInitDumpStack
0x14 CrashdmpFreeDumpStack
0x18 CrashdmpDisable
0x1c CrashdmpNotify
0x20 CrashdmpWrite
0x24 CrashdmpUpdatePhysicalRange

*Pointer width is 8 bytes on 64-bit systems

When DriverEntry returns, the kernel immediately calls the entry in the table that corresponds to crashdmp.sys’ initialization function, CrashdmpInitialize.  This routine handles all remaining aspects of pre-initialization, mostly:

  • Configuring parameters of the dump based on registry settings (such as dump type, maximum dump file size, and so on)
  • Initializing and partially populating a global data structure (called a crash dump control block) used in post-initialization phase
  • Registering all bugcheck callback routines

CrashdmpInitialize routine also calls the CrashdmpLoadDumpStack routine, which locates and loads all drivers in the dump stack with the help of the normal I/O path.  This is accomplished by:

  • Querying the port driver in the normal I/O path using I/O control codes:  IOCTL_SCSI_GET_DUMP_POINTERS, IOCTL_SCSI_GET_ADDRESS, IOCTL_SCSI_GET_PARTITION_INFO, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IOCTL_SCSI_GET_DRIVE_GEOMETRY_EX
  • Loads a special copy of the normal I/O path’s port and miniport drivers from disk, as well as any crash dump filter drivers listed in the registry and:
    • Copies the image into memory, naming it with a “dump_” prefix (note: no DRIVER_OBJECT created)
    • Creates context data structures for each driver in the stack, with special filter context structures for crash dump filter drivers

The “special copy” of the normal I/O path’s port driver (known as the “dump port driver”) is a heavily modified version of the port driver provided by Microsoft, trimmed down to bare necessities with special modifications to operate autonomously in crash mode.  The “special copy” of the normal I/O path’s miniport driver (known as the “dump miniport driver”) is simply a direct copy of the normal miniport driver, but the miniport is already programmed to handle crash mode when its DriverEntry is called with NULL parameters.  This is one of the few secrets of crash mode actually documented by Microsoft1.

The dump port driver will always be copied into memory as dump_scsiport, dump_ataport, dump_storport, or dump_diskdump.  The dump miniport driver can be named anything.

The call stack for this final portion of the pre-initialization phase is shown below.

  • nt!KiInitializeKernel()
    • nt!IoInitSystem()  OR  nt!NtCreatePagingFile()
      • nt!IoInitializeCrashDump()
        • Crashdmp!CrashDmpInitialize()
          • Crashdmp!CrashdmpLoadDumpStack()
            • Crashdump!QueryPortDriver()
            • Crashdmp!LoadPortDriver()
            • Crashdmp!LoadFilterDrivers()
            • Crashdmp!InitializeFilterDrivers()

Once this phase is complete, the crash dump stack has been prepped for use during post-initialization.  At this point, all drivers are copied into memory and information about them has been retained in a global data structure.

Note that some aspects of the process described on this page are specific to Vista+ operating systems.  Windows XP behaves a little differently (in fact there is no crashdmp.sys driver).  For more details, please see one of my whitepapers listed on the Publications page.

1. http://msdn.microsoft.com/en-us/library/ff564084(v=VS.85).aspx

%d bloggers like this: