I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
Upcoming SlideShare
Loading in...5
×
 

I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits

on

  • 7,573 views

 

Statistics

Views

Total Views
7,573
Views on SlideShare
2,450
Embed Views
5,123

Actions

Likes
2
Downloads
54
Comments
0

26 Embeds 5,123

http://blog.crowdstrike.com 3983
http://www.crowdstrike.com 903
https://twitter.com 60
http://feeds.feedburner.com 48
http://calcitrate12.corisu.com 38
http://www.tinkrwith.us 27
http://www.redditmedia.com 9
http://website.cs.sys 6
http://feedly.com 6
http://tinkrwith.us 6
http://10.12.7.5 6
http://translate.googleusercontent.com 4
http://feedreader.com 4
http://www.newsblur.com 3
http://rss.acemod.fr 3
http://webcache.googleusercontent.com 2
https://es.twitter.com 2
http://7985496991125228536_f4bc10215afec018e558f6ab1d4a8831baef7bcb.blogspot.com 2
http://feedproxy.google.com 2
http://twitter.com 2
http://7985496991125228536_f4bc10215afec018e558f6ab1d4a8831baef7bcb.blogspot.com.au 2
http://7985496991125228536_f4bc10215afec018e558f6ab1d4a8831baef7bcb.blogspot.co.uk 1
http://cloud.feedly.com 1
http://127.0.0.1 1
http://www.excite-webtl.jp 1
https://twimg0-a.akamaihd.net 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits Presentation Transcript

    • I/O, YOU OWN:REGAINING CONTROLOF YOUR DISK IN THEPRESENCE OFBOOTKITSAaron LeMasters @lilhoser
    • Introduction2  My background  Your background  Brief history of this presentation  Disclaimer: some of this might be wrong…  Please read white paper for details
    • Agenda3  Technical Background  What is the crash dump stack in Windows?  How the operating system initializes and uses the crash dump stack (post Windows Vista)  Pre Vista is in Appendix A  Bootkit Defeat Technique for SCSI drives  How we can use this stack outside of the operating system’s normal activity  IDE drive technique in Appendix B  Sneak peak at Windows 8 Release Preview changes  Demo – Defeating TDL4
    • 4 Technical Background Terminology and Concepts
    • Basics5  Port driver – abstraction interface provided by OS, hides underlying protocol details from class driver  Miniport driver – manufacturer-supplied driver to interface with hardware (Host Bus Adapter/HBA); linked against port driver for specific transport technology  Class driver – a driver that abstracts the underlying technology of a category of devices that share similar qualities (e.g., cdrom.sys)  Normal I/O path – the route an I/O request takes during regular system operation  Crash dump I/O path – the route the kernel uses to write a crash dump file to disk during a crash
    • Normal I/O Path6
    • Crash Dump I/O Path7
    • Why two paths?8  When a bugcheck occurs, the OS has no idea where the problem occurred – it could have happened inside a driver in the normal I/O path.  What differs between the two paths? Normal I/O Path Crash Dump I/O Path Primary drivers Many, layered Modified port and miniport Filter drivers Many, layered Crash dump filters only Controlled by I/O manager Kernel or crashdmp.sys Documented? Yes *cough*
    • The Crash Dump Mechanism9  Encompasses the entire crash dump process  Fromwhen it is initialized during system boot up to when it is used after KeBugCheck2()  Primary components:  The kernel  Crashdmp.sys (Vista+)  The crash dump driver stack or just “crash dump stack”  Goal: Write a crash dump file to boot device or save state in a hibernation file
    • The Crash Dump Stack10  A “stack” of drivers, consisting of:  A dump port driver  A dump miniport driver  One or more crash dump filter drivers  Initialized in two phases:  System startup/page file creation (pre-initialization)  System crash (post-initialization)  Used when:  A bug check occurs  The system is about to hibernate
    • The Crash Dump Stack – Common Drivers11 Driver Name On Disk Driver Base Name in Purpose Memory diskdump.sys dump_diskdump SCSI/Storport dump port driver with required exports from scsiport.sys and storport.sys. This driver is unloaded. dumpata.sys dump_dumpata IDE/ATA dump port driver with required ataport.sys exports. This driver is unloaded. scsiport.sys dump_scsiport The final SCSI/Storport dump port driver. ataport.sys dump_ataport The final IDE/ATA dump port driver. atapi.sys dump_atapi An older, generic ATAPI miniport driver provided by the OS for IDE/ATA drives vmscsi.sys dump_vmscsi The miniport driver provided by VMWare for SCSI drives. LSI_SAS.sys dump_LSI_SAS The miniport driver provided by LSI Corporation for serial- attached storage drives. dumpfve.sys dump_dumpfve Windows full volume encryption crash dump filter driver
    • Crash Dump Environment12  Normal I/O path is disabled  All processors are disabled except the one the current thread is executing on  Active CPU becomes single-threaded (IRQL is raised to HIGH_LEVEL) and uninterruptible  I/O sent to the crash dump stack is synchronous  If IDE controller, only the channel containing the device with the paging file is enabled
    • 13 Technical Background Crash Dump Stack Initialization and Usage after Windows Vista
    • Crash Dump Stack Configuration14  Crash dump is configured via IoConfigureCrashDump()  Reads in registry settings to control dump behavior  Passes handle to system paging file to IopInitializeCrashDump()  Triggered via NtSetSystemInformation() or PoBroadcastSystemState() or PoShutdownBugCheck()
    • Initialization15
    • Load and Call Entry Point of16 Crashdmp.sys  Nearly all of crash dump code was removed from kernel and put in crashdmp.sys  KiInitializeKernel()  IoInitSystem() OR NtCreatePagingFile()  IoInitializeCrashDump(HANDLE PageFile)  IopLoadCrashDumpDriver() – loads crashdmp.sys  Crashdmp!DriverEntry() – fills crash dump call table  Entry point called with two arguments:  Name of the arc boot device  Pointer to a global crashdmp callback table
    • Crashdmp.sys Call Table17 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
    • Identify and Initialize Crash Dump18 Drivers  KiInitializeKernel()  IoInitSystem() OR NtCreatePagingFile()  IoInitializeCrashDump()  Crashdmp!CrashDmpInitialize():  Crashdmp!CrashdmpLoadDumpStack():  Crashdump!QueryPortDriver()  Crashdmp!LoadPortDriver()  Crashdmp!LoadFilterDrivers()  Crashdmp!InitializeFilterDrivers()
    • CrashdmpInitialize()19  References boot device’s FILE_OBJECT  Read registry for crash dump settings  Stored in local crashdump control block  Initializes crashdump control block  Registers a KbCallbackSecondaryDumpData bugcheck callback  Calls CrashdmpLoadDumpStack()…
    • CrashdmpLoadDumpStack()20  Queries port driver capabilities using 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  Locates all crash dump drivers: port, miniport and crash dump filter drivers  Copies them into memory with “dump_” prefix  No DRIVER_OBJECT or DEVICE_OBJECT!  Port driver will be one of dump_scsiport, dump_ataport or dump_storport; on disk either diskdump.sys (scsi/storport) or dumpata.sys (ataport)  Miniport can be named anything
    • Usage21
    • Call Dump Driver Entry Points22  KeBugCheck2()  IoWriteCrashDump():  Calls the eighth entry in the CrashDmpCallTable table, CrashDmpNotify() - displays the string “collecting data for crash dump”  Fills dump block with bug check codes and other debug information  Appends a triage dump if necessary
    • Call Dump Driver Entry Points and23 Dump Port Driver Callbacks  KeBugCheck2()  IoWriteCrashDump():  Callsthe ninth entry in the CrashDmpCallTable table, CrashDmpWrite():  CrashdmpInitDumpStack():  StartFilterDrivers() – calls the DumpStart callback of each crash dump filter driver  InitializeDumpDriver() – calls the dump driver entry point; calls the DiskDumpOpen callback provided by the dump port driver; fills dump context structure with callback pointers CrashdmpWriteRoutine, CrashdmpWritePendingRoutine, CrashdmpFinishRoutine
    • Data Written to Dump File24  KeBugCheck2()  IoWriteCrashDump():  CrashDmpWrite():  CrashdmpInitDumpStack():  DumpWrite() – creates dump file based on configuration:  FillDumpHeader()  Calls one of:  WriteFullDump()  WriteKernelDump()  WriteMiniDump()  InvokeSecondaryDumpCallbacks() - Invokes all BugCheckSecondaryDumpDataCallback callbacks to allow drivers to append data to the completed crash dump file.  InvokeDumpCallbacks() - Invokes all BugCheckDumpIoCallback callbacks, informing them crash dump is complete.
    • 25 Bootkit Defeat Technique How to bypass the Normal I/O Path and use the Crash Dump I/O Path to read and write to disk
    • Inspiration26 Restrictions on Miniport Drivers that Manage the Boot Drive: “A storage miniport driver that manages an adapter for a boot device is subject to special restrictions during a system crash. While dumping the systems memory image to disk, the miniport driver must operate within a different environment. The usual communication between the miniport driver, the port driver, and disk class driver is interrupted. The kernel does disk I/O by direct calls to the disk dump port driver (diskdump.sys for SCSI adapters or dumpata.sys for ATA controllers), bypassing file systems, and the normal I/O stack. The disk dump driver, in turn, calls the boot devices miniport driver to handle all I/O operations, and the disk dump driver intercepts all of the miniport drivers calls to the port driver.” [1]
    • Leveraging the Crash Dump I/O27 Path  The crash dump mechanism provides a pristine path to disk  But it only provides write capabilities  Leverage knowledge of the crash dump mechanism and internals of the port/miniport relationship to coerce read/write  Here’s how…
    • ..sort of like the O/S does…28
    • …but more like this29
    • Identify Crash Dump Port/Miniport30 Drivers  Walk loaded module list  Single out dump drivers easily via “dump_” prefix  Port driver will be one of dump_scsiport, dump_storport or dump_ataport  Miniport driver name:  open a handle to the class driver’s device object, walk attached devices to the lowest one  Vista+ DUMP_POINTERS_EX.DriverList  Once drivers have been found, call their entry points with the appropriate arguments  Dump port: DriverEntry(NULL, DumpInit*)  Dump miniport: DriverEntry(NULL, NULL)
    • Get Boot Device Information31  IOCTL to get hardware register mapping and port configuration information (IOCTL_SCSI_GET_DUMP_POINTERS); data returned in DUMP_POINTERS or DUMP_POINTERS_EX structure  IOCTL to get boot device location such as Target id, path Id, and Lun (IOCTL_GET_SCSI_ADDRESS); data returned in a SCSI_ADDRESS structure  Resulting information is stored in the DUMP_INITIALIZATION_CONTEXT structure before calling the dump port driver’s DriverEntry
    • Find StartIo or DispatchCrb32  How do we send I/O requests?  There is no device object for dump port driver  Use internal functions  StartIo (SCSI) – accepts a single SCSI_REQUEST_BLOCK (SRB) as argument  DispatchCrb (IDE) – accepts a single argument, a channel extension structure  Find functions by scanning dump port driver’s image’s text section for “magic bytes”
    • Find the Dump Port Driver’s33 Device Extension (1/2)  Can’t simply call the internal functions, more initialization required  Port/miniport share a device extension structure that must be properly initialized  An internal variable of the port driver  Most critical fields are filled in by dump port driver/miniport driver’s DriverEntry routines  Two methods to find Device Extension  Call a dump port function that leaks a pointer to it  Use DumpInit.MemoryBlock + 16  Dump port’s DriverEntry()assigns Device Extension to DumpInit->MemoryBlock+16, which we control and pass as second argument to DriverEntry() when we call it  Both methods work for all transports all the way through Windows 8
    • Find the Dump Port Driver’s34 Device Extension (2/2)  Function pointer leak example: Diskdump.sys leaks in ecx register in DiskDumpOpen() Transport Leaking Function Leaked in Register Architecture SCSI/Storoprt DiskDumpOpen ecx x86 (diskdump.sys) SCSI/Storport DriverEntry rdx x64 (diskdump.sys) IDE (dumpata.sys)* IdeDumpOpen ecx x86 IDE (dumpata.sys)* IdeDumpOpen rcx x64
    • Send SRB (SCSI) (1/2)35  Mimic DiskDumpWrite() an MDL at offset 0xD0 (0x118 x64) into the  Allocate device extension structure – MDL describes the SRB.DataBuffer  Call StartIo()
    • Send SRB (SCSI) (2/2)36  After MDL is created, send an SRB as follows:  SRB.Function - SRB_FUNCTION_EXECUTE_SCSI  SRB.PathId, SRB.TargetId, SRB.Lun – set to corresponding fields in SCSI_ADDRESS  SRB.CdbLength - 10 for 10-byte SCSI-2 command  SRB.SrbFlags - specify flags for a read operation  SRB.DataTransferLength - 512  SRB.DataBuffer - allocate 512 bytes NonPagedPool – result stored here  SRB.Cdb – the SCSI-2 command descriptor block (cdb)  Describes the location on disk to read
    • 37 Demo Overview
    • Recent Bootkits38  Alureon/TDL4 has gained popularity in the last few years  Abuses driver trust chain by hooking the port and miniport drivers, which are at the bottom of the disk driver stack trust chain  Modifies I/O requests in various ways to hide its rootkit file system, as well as return a clean MBR  Similar MBR/VBR rootkits include Popureb, Stoned, Hasta La Vista, Zeroaccess  Completely new strains, as well as variants, emerging constantly
    • TDL4 Bootkit Infection39  Modifies the miniport’s device object and driver object  DRIVER_OBJECT.DriverStartIo  hooked  DEVICE_OBJECT.DriverObject  hooked  Lowest attached device is unlinked from the miniport device by hooking DEVICE_OBJECT.NextDevice  Monitors for read or write attempts to the boot sector and its hidden file system  If boot sector, return original, clean MBR  If hidden file system, return zeroes  For more info, see [2]
    • 40 Demo Defeating TDL4
    • Results – Full Disclosure!41  SCSI – working from Windows XP – 7 (tested)  IDE – polling is hard   Method 1: IRB sent, garbage returned   Either the port driver is messing up the IRB somewhere during polling or we are missing a field in dump extension  Method 2: IRB sent, nothing returned , IRB status 2 (data length mismatch), ATA status 0x20 (?)  IRB.TaskFile might have invalid values  IDE_TASK_FILE: No examples anywhere!  Dump extension field missing – data length?
    • PoC Improvements42  POCs for both transports can cause momentary lag or event deadlock, because normal I/O path is not properly “shutdown”  Solution:  SCSIPort (push model, port driver controls queuing I/O) - Need to send flush and lock request SRB’s  StorPort – (pull model, miniport driver controls queuing I/O) – StorPortPauseDevice()
    • 43 Windows 8 Release Preview A Sneak Peak at Exciting New Changes
    • Core Kernel Changes44  Synchronization changes suggest crash dump stack can be used in multiple places  New function IopInitializeCrashDump()  Contents of IoInitializeCrashDump() moved here  only called if a prior initialize attempt fails and it guards call to IopInitializeCrashDump()with critical region  IopCrashDumpLock previously only used when crash dump stack is (re)configured; now additionally used when (re)initialized
    • Crashdmp Call Table Changes45 Table Offset* Windows 7 Value Windows 8 RP Value0x0 1 10x4 1 40x8 CrashdmpInitialize0xC CrashdmpLoadDumpStack0x10 CrashdmpInitDumpStack0x14 CrashdmpFreeDumpStack0x18 CrashdmpDisable0x1C CrashdmpNotify0x20 CrashdmpWrite0x24 CrashdmpUpdatePhysicalRange0x28 CrashdmpResumeCapable0x2C CrashdmpGetTransferSizes0x30 CrashdmpLogStatusData0x34 CrashdmpReady*Pointer width is 8 bytes on 64-bit systems
    • Crashdmp.sys Changes (1/6)46  GetLegacyPortDriverName() no longer uses static dump port driver names (e.g, “diskdump.sys”, “storport.sys”, “scsiport.sys”)  After loading a crash dump driver in CrashdmpLoadDriver()via MmLoadSystemImage(), it uses RtlImageNtHeader on imageBase instead of direct return value – possible bug fix  New hiber functions, ResumeCapable  ETW tracing, performance counters  Enhanced logging in c:DumpStack.log.tmp  Crashdmp.sys “drive telemetry” callback  New dump type: bitmap dump
    • Crashdmp.sys Changes (2/6)47  New security checks using __fastfail intrinsic [3]  CORRUPT_LIST_ENTRY cases  DumpWrite function used by call table’s CrashdmpWrite is not handled by IDA auto analysis – you must undefine bogus data/code, restart analysis or force code generation on block, and recreate the function  Several other functions have this issue
    • Crashdmp.sys Changes (3/6)48
    • Crashdmp.sys Changes (4/6)49  CrashdmpWrite behavior changed:  Checks that dump device is ready (eg, supported firmware); if so, call DumpWrite; if not, call DumpWriteCapsule which simulates the write by calling special “dump capsule” dump filters but does not write actual dump to disk  “Dump capsule” concept not documented
    • Crashdmp.sys Changes (5/6)50  Dump port driver DriverEntry() prototype has changed  Old:DriverEntry(NULL, DumpInit*)  New: DriverEntry(NULL, CrashdmpContext*)  This will affect our PoC (it won’t work on Win8)  New PoC coming soon…
    • Crashdmp.sys Changes (6/6)51  New CrashdmpReadRoutine populated in dump context structure by InitializeDumpDriver()  Wrapper around a call to new dump port driver function Diskdump!DiskDumpRead()  Calls new function DiskDumpIoIssue() which sets up SCSI read SRB and performs all of the hard tasks that the POC in this paper had to hack 
    • Why a New Read Capability?52  Not to make my research irrelevant   Internally: supports logging and new hibernation resume feature  Externally: crash dump filter drivers now have the ability to filter read requests to dump port driver  Define a DUMP_READ callback [4]  Provide a pointer to the callback in FILTER_INITIALIZATION_CONTEXT [5]  “Filter drivers can modify the contents of the data buffer contained in Mdl to revert any changes made to the data when it was written to disk” [4]  Probably to support hibernation resume; for example, encryption drivers need to decrypt
    • How to Use It (1/3)53  Filter read callback is cool, but not helpful to the goal of this research  We can only see read requests initiated by kernel/dump port driver; not useful for controlling what is read  But the point is the Crash Dump I/O Path now supports reading – we don’t need to hack it  At least not as bad as before  Contention issues with normal I/O path still exist
    • How to Use It (2/3)54  We have two options: 1. CrashdmpReadRoutine(Type, Offset, Mdl): just a wrapper for port read routine; only adds functionality to call filter read callbacks 2. Diskdump!DumpRead(Type, Offset, Mdl): does the actual work with miniport to complete I/O  The first option adds no value for us  Best option: call the port driver’s DumpRead() routine directly  Determine any pre-requisites
    • How to Use It (3/3)55  The dump port driver read routine is a simple wrapper:  DiskDumpIoIssue() kindly handles the entire I/O issuing process for us (i.e, our POC’s hack):  SRB initialization for a read operation  Mapping the MDL if required  Calling StartIo(), which calls the dump miniport  Polling to wait on result  Can we call DiskDumpRead() directly?  Stay tuned…
    • 56 Conclusions
    • Takeaways57  Why is this important?  We have a separate path to disk which is not currently hooked by any malware I am aware of  Tampering with the crash dump mechanism could destabilize the system  We can read AND write to disk this way  The crash dump port driver only provides callbacks to write to disk, but the StartIo function lets us issue any arbitrary SRB  The ability to write to disk with this technique provides us unique remediation (file cleaning) opportunities  New read functionality in Windows 8 makes reading disk via dump port driver officially supported (sort of)!
    • Stay Tuned…58  Keep an eye on blog.crowdstrike.com  New series on Windows 8 coming soon  Alex Ionescu (author of Windows Internals) covers new security features and how to break them  I will be posting about crash dump changes related to this research  Whitepapercoming soon  Windows 8 PoC coming soon
    • References59 [1] http://msdn.microsoft.com/en- us/library/ff564084(v=VS.85).aspx [2] http://go.eset.com/us/resources/white- papers/The_Evolution_of_TDL.pdf [3] http://www.alex-ionescu.com/?m=201110 [4] http://msdn.microsoft.com/en- us/library/windows/hardware/hh439713(v=vs.85).aspx [5] http://msdn.microsoft.com/en- us/library/windows/hardware/ff553865(v=vs.85).aspx Special thanks to Alex Ionescu
    • Thanks for listening! Questions ??? lilhoser@gmail.com @lilhoser60
    • 61 Appendix A Crash Dump Stack Initialization and Usage before Windows Vista
    • Initialization62
    • Initialize IopDumpControlBlock63  KiInitializeKernel()  IoInitSystem() OR NtCreatePagingFile():  IoInitializeCrashDump():  IopInitializeDCB():  Allocate IopDumpControlBlock structure  Fill in basic debug information - # CPUs, architecture, OS version, etc  Read registry settings for crash dump configuration
    • IopDumpControlBlock64 IopDumpControlBlock – global kernel variable typedef struct _DUMP_CONTROL_BLOCK { UCHAR Type; CHAR Flags; USHORT Size; CHAR NumberProcessors; CHAR Reserved; USHORT ProcessorArchitecture; PDUMP_STACK_CONTEXT DumpStack; PPHYSICAL_MEMORY_DESCRIPTOR MemoryDescriptor; ULONG MemoryDescriptorLength; PLARGE_INTEGER FileDescriptorArray; ULONG FileDescriptorSize; … }DUMP_CONTROL_BLOCK, *PDUMP_CONTROL_BLOCK;
    • Identify and Initialize Crash Dump65 Drivers  IoInitializeCrashDump():  IoGetDumpStack()  IopGetDumpStack():  Fills IopDumpControlBlock.DumpInit:  Boot device type, geometry and hardware attributes  Locates all crash dump drivers: port, miniport and crash dump filter drivers  Copies them into memory with “dump_” prefix  No DRIVER_OBJECT or DEVICE_OBJECT!  Port driver will be one of dump_scsiport, dump_ataport or dump_storport; on disk either diskdump.sys (scsi/storport) or dumpata.sys (ataport)  Miniport can be named anything  Fills IopDumpControlBlock.DumpStack with linked list of copied drivers
    • IopDumpControlBlock.DumpStack66 typedef struct _DUMP_STACK_CONTEXT { DUMP_INITIALIZATION_CONTEXT Init; LARGE_INTEGER PartitionOffset; PVOID DumpPointers; ULONG PointersLength; PWCHAR ModulePrefix; LIST_ENTRY DriverList; ANSI_STRING InitMsg; ANSI_STRING ProgMsg; ANSI_STRING DoneMsg; PVOID FileObject; enum _DEVICE_USAGE_NOTIFICATION_TYPE UsageType; } DUMP_STACK_CONTEXT, *PDUMP_STACK_CONTEXT;
    • IopDumpControlBlock.DumpStack67  DumpPointers - contains hardware-specific information about the disk drive (via IOCTL_SCSI_GET_DUMP_POINTERS) which is used during write I/O operations to the crash dump file.  DriverList - contains a linked list of data structures that describe the driver image of each driver in the crash dump stack; used at actual crash dump time to initialize each driver  Init - of type DUMP_INITIALIZATION_CONTEXT (undocumented but exported), shown below, is only partially filled in during the 1st phase of initialization.
    • Usage68
    • Call Dump Driver Entry Points (1/3)69  During pre-initialization, drivers were only mapped into memory - no management blocks created, no entry points called  Each driver in the dump stack will now have its entry point called  The first driver in the stack is always the dump port and it is always called first  Two arguments: 1. NULL 2. IopDumpControlBlock.DumpInit
    • Call Dump Driver Entry Points (2/3)70 typedef struct _DUMP_INITIALIZATION_CONTEXT { ULONG Length; ULONG Reserved; PVOID MemoryBlock; PVOID CommonBuffer[2]; PHYSICAL_ADDRESS PhysicalAddress[2]; PSTALL_ROUTINE StallRoutine; PDUMP_DRIVER_OPEN OpenRoutine; PDUMP_DRIVER_WRITE WriteRoutine; PDUMP_DRIVER_FINISH FinishRoutine; struct _ADAPTER_OBJECT *AdapterObject; PVOID MappedRegisterBase; PVOID PortConfiguration; … } DUMP_INITIALIZATION_CONTEXT,*PDUMP_INITIALIZATION_CONTEXT;
    • Call Dump Driver Entry Points (3/3)71  OpenRoutine, WriteRoutine and FinishRoutine fields are populated:  pointers to functions exported by the dump port driver which provide the kernel the ability to write the crash dump data to the crash dump file  The dump miniport driver’s DriverEntry is called  registers with the dump port driver  All other dump driver’s DriverEntry are called with NULL arguments  According to MSDN, this notifies them to operate in “crash dump mode”
    • Call Dump Port Driver Callbacks72  KeBugCheck2()  IoWriteCrashDump():  IoInitializeDumpStack() – performs post-initialization of crash dump drivers  DiskDumpOpen() – this port driver export is called to prepare the crash dump file  Displays the dump string “Beginning dump of physical memory”, stored in the DUMP_CONTROL_BLOCK structure  Calculates the dump storage space required based on configuration  Fills a dump header with bug check codes and other debug information  Invokes all BugCheckDumpIoCallback callbacks registered with the kernel via KeRegisterBugCheckReasonCallback(), passing the dump header
    • Data Written to Dump File73  KeBugCheck2()  IoWriteCrashDump():  IoInitializeDumpStack() – performs post- initialization of crash dump drivers  One of the following functions calls DiskDumpWrite() until all crash dump data is written:  IopWriteSummaryHeader()  IopWriteSummaryDump()  IopWriteTriageDump()  Invokes all BugCheckSecondaryDumpDataCallback callbacks to allow drivers to append data to the completed crash dump file  Calls DiskDumpFinish() to close crash dump file  Invokes all BugCheckDumpIoCallback callbacks, informing them crash dump is complete.
    • 74 Appendix B Bootkit Defeat Technique for IDE Drives
    • Send IRB (IDE) – General Idea75
    • Send IRB (IDE) – Method 176  Relies on calling port driver internal functions  Mimic IdeDumpWritePending()  Allocate a CRB in DUMP_INITIALIZATION_CONTEXT.MemoryBlock at the correct offset (0x120 for x86, 0x1C0 for x64)  Allocate and fill in an IRB at offset 0x288 (0x3E8 for x64) in the CRB  Store a pointer to a callback function in the CRB at offset 0x4, which will be invoked when the dump port driver is notified that the I/O request is complete  Allocate an MDL at offset 0x50 (0x88 for x64) in the CRB  Send the CRB to DispatchCrb()  Wait via IdeDumpWaitOnRequest()function
    • Send IRB (IDE) – Method 277  Completely bypass dump port driver  Mimic IdeDumpWritePending()  Allocate a CRB in DUMP_INITIALIZATION_CONTEXT.MemoryBlock at the correct offset (0x120 for x86, 0x1C0 for x64)  Store a pointer to a callback function in the CRB at offset 0x4, which will be invoked when the dump port driver is notified that the I/O request is complete  Allocate and fill in an IRB at offset 0x288 (0x3E8 for x64) in the CRB  Replace DispatchCrb() with Call the miniport’s HwStartIo routine, which is stored at offset 0x2E in the  device extension, passing the device extension and the IRB  Replace IdeDumpWaitOnRequest() with:  Poll the device until the IRB status changes from zero by calling the miniport’s HwInterrupt routine which is stored at offset 0x2F in the device extension, passing the device extension only
    • Send IRB (IDE)78  IRB.Function - IRB_FUNCTION_ATA_COMMAND  IRB.Channel - should be set to the value stored in the channel extension’s Channel field which is at offset 0x8A (0xEA for x64) from the start of the CRB  IRB.TargetId - should be set to the value stored in the channel extension’s TargetId field which is at offset 0x45D (0x6A9 for x64) from the start of the CRB  IRB.Lun - should be set to the value stored in the channel extension’s Lun field which is at offset 0x45E (0x6AA for x64) from the start of the CRB