logo - Click here to go to the site home page... Click here to go to the site home page... Click here to go to the Blog page... Click here to go to the archives page... Click here to go to the about page...
"extremely impressive work"
- Mark Russinovich,
(referring to my BugChecker)
my face...
Homepage of Vito Plantamura (@), Windows Researcher, VPC Technologies SRL CEO. [user=Guest] - updated: August 08, 2007
 ..:: BugChecker Kernel-Mode Debugger ::..

    This article is obsolete. BugChecker now supports Windows XP (all service packs) and is open source. Check out its site here.    


BugChecker SMP is a Microsoft Windows 32-bit kernel-mode debugger (ala SoftICE) that is aimed mainly to reverse engineering enthusiasts. It is still under development and some features, such as full source code symbols support, have been coded but are still not exposed in the debugger itself.

At the time of this writing, BugChecker consists of over 100,000 lines of C and system assembler code and is the result of about 6 months of (hard) work of developing, researching and reverse engineering.

BugChecker is for me:

     An opportunity to learn things about Windows NT that I couldn't learn/discover otherwise. For me learning new things and solving complex problems are the two most important things when dealing with computers.
     An opportunity to develop what I think is one of the most interesting projects I can think of. With the amount of internet information about everything in the field of technology and development, I was searching something to develop that would force me to extract and deduce the required information myself, with reverse engineering, in this case. Nowadays developing any other type of application consists, in most cases, in doing a search in Google, CodeProject or MSDN and then putting together the found code samples...


BugChecker consists of two components:

     BugChecker Debugger driver: this is the debugger itself. It is implemented as a Windows NT Kernel Driver. This means that you can debug with it both user mode and kernel mode code.
     BugChecker Video driver: this NT Driver is required in order for the debugger to be used. Its start mode is set to "boot" and it is started when Windows 2000 is booted up. This simple driver (compared to the debugger driver itself), when started, hooks and patches some DirectDraw API entry points in order to be notified about the current video display mode and the start in kernel protected memory of the display framebuffer.


NOTE: partial / incomplete list.

     Kernel/user debugging of 32-bit code.
     SMP support. The debugger can be used also on multiprocessors systems (PIC/IOAPIC/APIC support): the reentrancy in the debugger code is prevented.
     Full source code support (via .pdb files). Coded, but still not exposed in the debugger (mixed source file/assembly view, stack trace, C types inspection etc.).
     Kernel and user breakpoints features. The user breakpoints are maintained in a special database that is synchronized with the NT Page Frame Database. The breakpoints of this type can be specified as process and/or module specific.
     Support of DirectDraw compatible video cards.
     Support of PS/2 Keyboards and Mouses with handling of keyboard LEDs status and restore of hotkey press/release state in OS when exiting from the debugger.
     Saving of the current floating point status (if used in the current NT process context) when entering in the debugger thus allowing the creation of macros that handle fp data, for example (without interfering with the current running process).
     Integration of a special C compiler written by Vito Plantamura in the debugger code itself. Every macro written and every command entered is compiled instantly and linked in realtime in a debugger special reserved memory area.
     Macro writing support.
     Text editor with basic clipboard commands for allowing the writing of macros and scripts.
     Scripts and macros can access and call a set of APIs that allow the writing of very complex breakpoint handlers and that can be used to "automate" the debugger itself.
     Symbol loader MFC application that allows the conversion of .PDB files in .BCS files for loading into the debugger memory.
     Support of resizable windows (ala SoftICE).


Note that I have focused my programming efforts (in this stage of the work) in implementing the basic subset of commands that constitutes the most important and complex-to-code foundation for the complete working of the debugger itself. Source code support is coded but not compiled (yet) in the final .sys file. System information commands (GDT, IDT, THREAD etc.) and memory manipulation commands (D, E etc.) are extremely simple to implement, compared to the rest of the code.

Breakpoint creation/manipulation.

     BC : Clear breakpoint. ( syntax: BC list|* )
     BD : Disable breakpoint. ( syntax: BD list|* )
     BE : Enable breakpoint. ( syntax: BE list|* )
     BL : List current breakpoints. ( syntax: BL (enter) )
     BPE : Edit breakpoint. ( syntax: BPE breakpoint-number )
     BPINT : Breakpoint on interrupt. ( syntax: BPINT interrupt-number )
     BPIO : Breakpoint on I/O port access. ( syntax: BPIO port [/R|/W|/RW][/Lsize][/DRreg] )
     BPMB : Breakpoint on memory access (byte size). ( syntax: BPMB address [/W|/RW][/G][/DRreg] )
     BPMD : Breakpoint on memory access (dword size). ( syntax: BPMD address [/W|/RW][/G][/DRreg] )
     BPMW : Breakpoint on memory access (word size). ( syntax: BPMW address [/W|/RW][/G][/DRreg] )
     BPX : Breakpoint on execution. ( syntax: BPX address [/DRreg|none][/Pname|none][/Mname|none] )

Other commands.

     ? : Evaluate expression as dword (integer). Use EVALF for fp. ( syntax: ? expression )
     CPU : Display informations about all the CPUs or a CPU in particular. ( syntax: CPU [(enter)|#cpu] )
     DASH : Go to dashboard. The execution will return to Windows. ( syntax: DASH (enter) )
     EC : Enable/disable code window. ( syntax: EC (enter) )
     EVALF : Evaluate expression as floating point. ( syntax: EVALF expression )
     HBOOT : Reboot the system (total reset). ( syntax: HBOOT (enter) )
     I3HERE : Direct INT3 to the debugger. ( syntax: I3HERE [ON|OFF|DRV] )
     VERSION : Display VpcICE version informations. ( syntax: VERSION (enter) )

Keyboard commands.

     F4 : In-place compilation of the Script File.
     F6 : Toggle the Code Window Mode.
     F7 : Toggle the Script Window Focus.
     F8 : Single step.


GIF/JPEG screenshots.

     The command "list breakpoints" (bl) was entered. There is only one breakpoint: note that in BugChecker the user breakpoints are maintained storing the relative byte address, the module name and the process name. You can however set a breakpoint that is process name generic (it will trigger in any process, regardless of its name) simply omitting the process name when setting the breakpoint itself.
     Note that a macro was defined in the script window. Its name is "test" and it accepts one parameter of type "int". After defining this macro, it is used in an expression specified as the address parameter of the "bpx" command, for setting an "execution breakpoint". Later, when the execution resumes in the OS, this same breakpoint triggers and the control returns to BugChecker.
     The same macro of the screenshot above is evaluated with the "?" command.
     An other macro was defined with the name "complex_macro". Note that the macros defined in the script window have to be compiled before their use in expressions for commands or other macros (this is accomplished pressing the F4 key). Later, the command "evalf" is used on the "complex_macro", specifing as parameters the results of two calls to the "test" macro. Note that "complex_macro" returns a float value, and takes as parameters two other float values. Everything you enter in BugChecker (script, macros, breakpoint handlers, commands) is first compiled, then executed in the private context of the debugger.
     As a proof of what stated above, you can see the debugger response when entering a wrong syntaxed command: the debugger tries to compile the command "evalf complex_macro ( s )", but the compiler is unable to understand the meaning of the "s" symbol.
     A "breakpoint on I/O port access" was set on the keyboard i/o port, for read and write operations and on the debug register 3. In the screenshot it triggers because of a keyboard interaction and the execution goes to BugChecker for debugging.
     A "breakpoint on memory access" was set on the address of the PCR structure in virtual memory. The FS:0 address refers to this same memory in kernel space.
     A screenshot of the symbol loader application.

Example of a output window dump (after startup).

BugChecker 32bit Debugger for Win2000/XP/S2003 (UP/SMP) - (Ver0.9 - Bld107).
Copyright (c) 2003-2004 Vito Plantamura Consulting. All Rights Reserved.
BugChecker: Settings File: "\SystemRoot\system32\drivers\bugchk.dat": Loaded.
BugChecker: Allocated 512Kb for Symbols.
BugChecker: User Probe Address is "0x7FFF0000".
BugChecker: Number of Processors in the System: 2.
BugChecker: Active Process List: ProcessListHead = 8055CC68, IdleProcess = 80547370.
BugChecker: Allocated 4286 KBytes for MiniC Compiler.
BugChecker: Allocated 131072 Bytes for BugChecker System Stack.
BugChecker: "MapViewOfImageSection" Entry Point located at 8051AB10.
BugChecker: "UnMapViewOfImageSection" Entry Point located at 805A838E.
BugChecker: "NtTerminateProcess" System Table Index located at E0.
BugChecker: Pentium TSC Calibration result: 999 MHz.
BugChecker: I/O Apic found at linear address "0xFFD06000".
BugChecker: Using Linear Address for accessing Per-Processor Local Apic at "0xFFFE0000".
BugChecker: BugChecker Inter-Processor Interrupt installed at Vector "0xF5". ISR at Linear Address "0x8053D08A".
BugChecker: Real Mouse Interrupt Vector detected at 0x52.
BugChecker: Real Keyboard Interrupt Vector detected at 0xB3.
BugChecker: Installing Mouse Trampoline for Interrupt Vector 0xF7.
BugChecker: Installing Keyboard Trampoline for Interrupt Vector 0xF6.
BugChecker: Installed trampoline for IRQ12 (PrevISR: "0x8053D098", NewISR: "0xBA7841C0").
BugChecker: Installed trampoline for IRQ1 (PrevISR: "0x8053D091", NewISR: "0xBA783B48").
BugChecker: Exiting "InstallBugCheckerInterruptHooks" with Success.
BugChecker: Debugger User Space Memory: Address: 6F800000, Size: 8000.
BugChecker: PS/2 Mouse detected. Device ID = 0x03.
BugChecker: Load32 -> START=75050000  SIZE=2C000  KPEB=8523A860  MOD=netmsg.dll
BugChecker: Exit32 -> PID=4B0  MOD=net1
BugChecker: Unload32* -> MOD=net1.exe
BugChecker: Unload32* -> MOD=ws2help.dll
BugChecker: Unload32* -> MOD=ws2_32.dll
BugChecker: Unload32* -> MOD=wsock32.dll
BugChecker: Unload32* -> MOD=netmsg.dll
BugChecker: Unload32* -> MOD=samlib.dll
BugChecker: Unload32* -> MOD=NETAPI32.DLL
BugChecker: Unload32* -> MOD=netrap.dll
BugChecker: Unload32* -> MOD=rpcrt4.dll
BugChecker: Unload32* -> MOD=WLDAP32.DLL
BugChecker: Unload32* -> MOD=dnsapi.dll
BugChecker: Unload32* -> MOD=ntdsapi.dll
BugChecker: Unload32* -> MOD=msvcrt.dll
BugChecker: Unload32* -> MOD=NTDLL.DLL
BugChecker: Unload32* -> MOD=ADVAPI32.DLL
BugChecker: Unload32* -> MOD=secur32.dll
BugChecker: Unload32* -> MOD=KERNEL32.DLL
BugChecker: Exit32 -> PID=588  MOD=net
CPU|PCR-Base|IDT-Base|GDT-Base|IRQL(Priority)| TID|       CS:EIP|Proc(ID)
00 |FFDFF000|8003F400|8003F000|  DISPATCH(41)|0000|0008:8053C66C|Idle(0000)
01 |85E83000|85E873C8|85E87BE8|  DISPATCH(41)|0000|0008:8053C66C|Idle(0000)


Currently the debugger is compatible only with Windows 2000 SP4. I consider making it compatible also with Windows XP / Windows Server 2003 / Longhorn a very low-priority task. Infact the porting itself consists of the following fixes to the debugger code:

     Checking for fields offset changes in the PCR, KTEB, KPEB and DriverSection system structures.
     Fixing the system functions search routines for discovering the correct addresses of the following functions: "MapViewOfImageSection", "UnMapViewOfImageSection", "NtTerminateProcess" (when symbols are not available). It is necessary to check whether the prototypes and logic of the aforementioned functions is still the same in Windows XP and Windows 2003 (probably yes...).
     Implementing a VAD Walking Function that is compatible with Windows 2003 (where the Virtual Address Descriptors structures and algorithms have changed.)
     Checking whether the Process List iterator still works with WinXP.


You can download a very preliminary version of BugChecker from this page.

"Among the Windows experts I know personally, no one can beat Vito Plantamura."
- Francesco Balena, Code Architects SRL

"Your NDIS Monitor application, is amongst the most impressive networking code I have seen on the .Net framework."
- Ben Hakim.
Various images from italian conferences and events (keep the mouse on a thumbnail for a short description):
Me at the Microsoft/HP/Intel organized Route64 event in Milan in May 2005, explaining how COM+ behaves on 64-bit Microsoft operating systems. I was there with the friends of Code Architects.
Me at the Microsoft Security Roadshow event in Bari in April 2006, explaining how the logon process works in Windows NT. There were 250 attendees.
Microsoft Security Roadshow 2006 in Treviso. This is an image of the huge 700-seats conference room.
Me at the Microsoft Security Roadshow 2006 in Treviso. This is a moment of the 3-hours session.
 Site login
NOTE: Actually the login feature is used only for administrative and content management purposes.


Everything here (code, binaries, text, graphics, design, html) is © 2010 Vito Plantamura and VPC Technologies SRL (VATID: IT06203700965).
If you download something (compilable or not) from the site, you should read the license policy file.
If you want to contact me via email, write at this address.