Debugging the Debugger

Have you ever tried to debug a debugger when it debugs a debuggee? Is it possible? Good question. I never asked it to myself until today. And tried. And it works! First I tried to attach WinDbg.exe to an instance of WinDbg.exe executing ‘!analyze -v’ command and got these stacks:

0:002> ~*kL 100
0 Id: 1ff0.104c Suspend: 1 Teb: 7ffdf000 Unfrozen
ChildEBP RetAddr
0006df38 7739d02f ntdll!KiFastSystemCallRet
0006ff7c 01055e36 USER32!NtUserWaitMessage+0xc
0006ffc0 77e523e5 windbg!_initterm_e+0x170
0006fff0 00000000 kernel32!BaseProcessStart+0x23

1 Id: 1ff0.1af8 Suspend: 1 Teb: 7ffde000 Unfrozen
ChildEBP RetAddr
00ac3448 030a5677 dbghelp!CAllPubNameTrav::next+0x1b
00ac345c 0301e16e
dbghelp!CDiaEnumTraversalCSymRow::Next+0x48
00ac44fc 0301e452 dbghelp!diaGetGlobals+0x8fe
00ac4524 0304967a dbghelp!diaGetSymbols+0x42
00ac453c 03045ca3 dbghelp!diaEnumSymbols+0x1a
00ac4554 03031e5a dbghelp!modEnumSymbols+0x43
00ac459c 030338a5 dbghelp!ModLoop+0x10a
00ac6570 030391d8 dbghelp!EnumSymbols+0x155
00ac65a0 0220947b dbghelp!SymEnumSymbolsW+0x48
00ac7600 0220a53d dbgeng!FindTypeInfoInMod+0x18b
00aca5cc 0220caa2 dbgeng!TypeInfoFound+0xced
00acb62c 0220c95f dbgeng!SymbolTypeDumpNew+0xa2
00acb654 0220d36b dbgeng!FastSymbolTypeDump+0xef
00acb700 0213c753 dbgeng!SymbolTypeDump+0xbb
00acc25c 0147d632 dbgeng!ExtIoctl+0x1073
00acc2f4 0150e10e ext!GetFieldData+0xe2
00accc14 014f9f00 ext!UaThread::_Extract_UIThread+0x34e
00accc24 014fa1f9 ext!UaThread::CallExtractors+0x20
00accc34 01511126 ext!UaThread::ExtractAttributes+0x99
00accd78 015212e2
ext!UserAnalyze::ExtractAttributes+0x376
00acd02c 01521467 ext!UeFillAnalysis+0x462
00acd10c 01521650 ext!UeAnalyze+0x147
00acd208 0147c90c ext!AnalyzeUserException+0x1a0
00acd23c 02141299 ext!analyze+0x28c
00acd2c8 021414d9 dbgeng!ExtensionInfo::CallA+0x2e9
00acd458 021415a2 dbgeng!ExtensionInfo::Call+0x129
00acd474 0213feb1 dbgeng!ExtensionInfo::CallAny+0x72
00acd8ec 02181698 dbgeng!ParseBangCmd+0x661
00acd9dc 02182b29 dbgeng!ProcessCommands+0x508
00acda20 020c9049 dbgeng!ProcessCommandsAndCatch+0x49
00acdeb8 020c92aa dbgeng!Execute+0x2b9
00acdee8 010283bf dbgeng!DebugClient::ExecuteWide+0x6a
00acdf88 0102883b windbg!ProcessCommand+0xff
00acffa4 0102aabc windbg!ProcessEngineCommands+0x8b
00acffb8 77e6608b windbg!EngineLoop+0x3dc
00acffec 00000000 kernel32!BaseThreadStart+0x34

# 2 Id: 1ff0.116c Suspend: 1 Teb: 7ffdd000 Unfrozen
ChildEBP RetAddr
00fdffc8 7c845ea0 ntdll!DbgBreakPoint
00fdfff4 00000000 ntdll!DbgUiRemoteBreakin+0x36

Next I thought, wait a moment, we are debugging dump analysis session. Can we debug a debugger debugging a running process? So I attached WinDbg.exe to an instance of WinDbg.exe attached to an instance of notepad.exe and got these stacks:

0:002> ~*kL
0 Id: 11f0.164c Suspend: 1 Teb: 7ffde000 Unfrozen
ChildEBP RetAddr
0006df38 7739d02f ntdll!KiFastSystemCallRet
0006ff7c 01055e36 USER32!NtUserWaitMessage+0xc
0006ffc0 77e523e5 windbg!_initterm_e+0x170
0006fff0 00000000 kernel32!BaseProcessStart+0x23

1 Id: 11f0.1bb0 Suspend: 1 Teb: 7ffdd000 Unfrozen
ChildEBP RetAddr
00adff0c 7c822124 ntdll!KiFastSystemCallRet
00adff10 77e6bad8 ntdll!NtWaitForSingleObject+0xc
00adff80 020bf8aa kernel32!WaitForSingleObjectEx+0xac
00adffa0 0102aa42
dbgeng!DebugClient::DispatchCallbacks+0x4a
00adffb8 77e6608b windbg!EngineLoop+0x362
00adffec 00000000 kernel32!BaseThreadStart+0x34

# 2 Id: 11f0.100c Suspend: 1 Teb: 7ffdc000 Unfrozen
ChildEBP RetAddr
00beffc8 7c845ea0 ntdll!DbgBreakPoint
00befff4 00000000 ntdll!DbgUiRemoteBreakin+0x36

Given that many functions from dbghelp.dll and dbgeng.dll are described in WinDbg help you can quickly reverse engineer WinDbg.exe and its extensions code.

- Dmitry Vostokov -

3 Responses to “Debugging the Debugger”

  1. rr Says:

    i dont believe you dont know either ctrl+p enter in cdb or .dbgdbg command in windbag

    0:002> ~*k;.shell -ci “version” findstr “command”

    0 Id: 880.81c Suspend: 1 Teb: 7ffde000 Unfrozen
    ChildEBP RetAddr
    0006cf24 7c90e306 ntdll!KiFastSystemCallRet
    0006cf28 7c80c8d8 ntdll!ZwReleaseSemaphore+0xc
    0006cf3c 020bf9e8 kernel32!ReleaseSemaphore+0×14
    0006cf94 0102acd0 dbgeng!DebugClient::ExitDispatch+0xd8
    0006cfa4 01027915 windbg!UpdateEngine+0×30
    0006cfac 01027a0f windbg!FinishCommand+0×15
    0006cfd0 01014994 windbg!AddStringCommand+0xef
    0006cfe8 01012569 windbg!CmdExecuteCmd+0xa4
    0006d044 01018f77 windbg!WinCommand::OnNotify+0×469
    0006d1a8 77d48709 windbg!WinBase::BaseProc+0xc87
    0006d1d4 77d487eb USER32!InternalCallWinProc+0×28
    0006d23c 77d4b743 USER32!UserCallWinProcCheckWow+0×150
    0006d278 77d4b7ab USER32!SendMessageWorker+0×4a5
    0006d298 74e8abfa USER32!SendMessageW+0×7f
    0006d4d0 74e4fe1d RICHED20!CW32System::SendMessage+0×3d
    0006d50c 74e50d60 RICHED20!CTxtWinHost::TxNotify+0xd0
    0006ddf4 77d48709 RICHED20!RichEditWndProc+0×19b
    0006de20 77d487eb USER32!InternalCallWinProc+0×28
    0006de88 77d489a5 USER32!UserCallWinProcCheckWow+0×150
    0006dee8 77d489e8 USER32!DispatchMessageWorker+0×306

    1 Id: 880.5b8 Suspend: 1 Teb: 7ffdd000 Unfrozen
    ChildEBP RetAddr
    00d7ff98 7c90d85c ntdll!KiFastSystemCallRet
    00d7ff9c 7c9279d4 ntdll!NtDelayExecution+0xc
    00d7ffb4 7c80b50b ntdll!RtlpTimerThread+0×47
    00d7ffec 00000000 kernel32!BaseThreadStart+0×37

    # 2 Id: 880.8e4 Suspend: 1 Teb: 7ffda000 Unfrozen
    ChildEBP RetAddr
    00f6d238 02141299 ext!analyze
    00f6d2c4 021414d9 dbgeng!ExtensionInfo::CallA+0×2e9
    00f6d454 021415a2 dbgeng!ExtensionInfo::Call+0×129
    00f6d470 0213feb1 dbgeng!ExtensionInfo::CallAny+0×72
    00f6d8e8 02181698 dbgeng!ParseBangCmd+0×661
    00f6d9d8 02182b29 dbgeng!ProcessCommands+0×508
    00f6da1c 020c9049 dbgeng!ProcessCommandsAndCatch+0×49
    00f6deb4 020c92aa dbgeng!Execute+0×2b9
    00f6dee4 010283bf dbgeng!DebugClient::ExecuteWide+0×6a
    00f6df84 0102883b windbg!ProcessCommand+0xff
    00f6ffa0 0102aabc windbg!ProcessEngineCommands+0×8b
    00f6ffb4 7c80b50b windbg!EngineLoop+0×3dc
    00f6ffec 00000000 kernel32!BaseThreadStart+0×37
    command line: ‘F:\windbgwithdbgengsym\cdb.exe -server npipe:icfenable,pipe=cdb_
    pipe -p 2176′ Debugger Process 0×8EC
    .shell: Process exited
    0:002>

    the crashdump i was looking at while i posted this

    BugCheck 35, {85e14008, 0, 0, 0}

    *** WARNING: Unable to verify timestamp for HDAudBus.sys
    *** ERROR: Module load completed but symbols could not be loaded for HDAudBus.sys
    Probably caused by : HDAudBus.sys ( HDAudBus+13bb0 )

    Followup: MachineOwner
    ———

    kd> .dbgdbg
    Debugger spawned, connect with
    “-remote npipe:icfenable,pipe=cdb_pipe,server=PRV”

    kd> !analyze -v
    […]

    NO_MORE_IRP_STACK_LOCATIONS (35)
    A higher level driver has attempted to call a lower level driver through
    the IoCallDriver() interface, but there are no more stack locations in the
    packet, hence, the lower level driver would not be able to access its

  2. Dmitry Vostokov Says:

    Two years ago when I wrote this post I didn’t know that :-)

  3. Crash Dump Analysis » Blog Archive » Debugging the Debugger (16-bit) Says:

    […] it looks like WinDbg double debugging is much more robust despite it bigger file size (debug.exe is […]

Leave a Reply

You must be logged in to post a comment.