3. XDBG – Debugger Prototype
CONTENTS
OS Support APIs
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading Support
Kernel Mode Device Driver
4. Dbghelp.dll [Windows NT 4.0 onwards]
Provides a set of routines to help you deal with the .pdb files and retrieve necessary
symbol information.
Also provides API to help you automatically retrieve symbol information using symbol
stores / servers.
Has an API which allows access Source servers. This enables a client to retrieve the
exact version of the source files that were used to build the application.
Using dbghelp.dll, an application can also write a mini-dump file to debug crashes at a
later time.
Imagehlp.dll [Windows 95 onwards]
Provides API access to portable executable (PE) image files (.exe, .dll, .ocx etc).
Functions are broadly categorized as –
Image Access Functions - Read the PE/COFF file information
Image Modification Functions - Bind Image, Change load address of dll etc
Image Integrity Functions - Add certificate to an executable image.
OS Support APIs
5. Psapi.dll [Windows NT 4.0 onwards]
Allows you to retrieve list of running processes and their loaded modules.
Also useful for querying a process’s memory usage info, working set size
etc.
Tlhelp32.h + kernel32.dll [Windows 95 onwards]
Allows you to take a “snapshot” of the system and then retrieve list of
running threads, processes and loaded modules.
Also facilitates heap-walking.
Debug Interface Access SDK
The new COM based DIA SDK provides programmatic access to the .pdb
symbol files.
The DIA SDK was made available to shield a debugger writer from constant
revisions of the .pdb format.
OS Support APIs
6. XDBG – Debugger Prototype
CONTENTS
OS Support APIs
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading Support
Kernel Mode Device Driver
7. PE - DISASSEMBLER
Overview of the PE file format –
PE file format is derived from the earlier COFF
(common object file format) described in VMS/VAX
architectures.
A “Portable Executable” File Format supported on all
CPUs on which Windows OS runs.
File Extensions include .exe, .dll, .cpl, .ocx
New PE32+ format is described for IA64 architecture.
Windows CE uses the PE format with support for new
processors.
.NET binaries are also in the PE format.
9. PE - DISASSEMBLER
Overview of the PE file format –
Mapping of the PE file is consistent on disk and in
memory.
Offsets of some sections may differ on disk and in
memory.
Some parts of a PE file may be read but not mapped
in memory. (e.g. relocation section)
Some parts of a PE file may not be mapped in at all
(e.g. debug section)
All #defines, definitions and enumerations are in the
WINNT.H file.
10. PE - DISASSEMBLER
PE file contents -
DOS Header
PE File Header
PE Optional Header
PE Section Headers
PE Sections
Code Sections (.code)
Data Sections (.rdata, .idata, .pdata)
Text Section (.text)
Resource Section (.rsrc)
Relocation Section (.reloc)
API Import and Export tables
Custom Sections
#pragma data_seg (“CUSTOM_SECTION”)
DataDirectory
(Array of 16
Structures)
11. PE - DISASSEMBLER
DOS Header Contents –
A 2-byte magic field, set to 0x5A4D (ascii ‘Z’, ’M’ ).
A linker created stub which prints out the message
“This program cannot be run in DOS mode” when the
image is run in MS-DOS. At offset 0x3C, the stub has
the file offset to the PE signature.
The above mentioned 4-byte PE signature “PE00”.
12. PE - DISASSEMBLER
PE (File) Header – Offset Size Field
0x0 2 bytes Machine
0x2 2 bytes NumberOfSections
0x4 4 bytes TimeDateStamp
0x8 4 bytes PointerToSymbolTable
0xC 4 bytes NumberOfSymbols
0x10 2 bytes SizeOfOptionalHeader
0x12 2 bytes Characteristics
May have multiple
characteristics
[Screenshot from the XDBG prototype]
13. PE - DISASSEMBLER
PE Supported CPU Architectures –
Always look in WINNT.H first !
Commonly Supported architectures – (look at Offset 0x0)
Value CPU Type
0x184 Alpha AXP processor
0x1C0 ARM Processor
0x284 Alpha AXP processor (64 Bit)
0x14C Intel i386 compatible (32 bit)
0x200 Intel IA64 processor
0x268 Motorola 68000 series
0x366 MIPS processor
0x466 MIPS processor with FPU
Value CPU Type
0x1F0 PowerPC (Little Endian Format)
0x162 MIPS processor (Little Endian)
0x166 MIPS processor (Little Endian)
0x168 MIPS processor (Little Endian)
0x1A2 Hitachi SH3 processor
0x1A6 Hitachi SH4 processor
0x0 Unknown Architecture
14. PE - DISASSEMBLER
The PE Optional Header –
Loader reads the PE Optional Header.
Size of the PE Optional Header is not fixed.
At present, we are ignoring the PE32+ format.
Offset Size Header Part
0 28 bytes Standard Fields
0x1C 68 bytes Windows Specific Fields
0x60 Variable Data Directories
16. PE - DISASSEMBLER
Section Headers –
Each row of the Section Table, in effect, is a section header.
This table immediately follows the optional header. Hence
the PE File Header does not contain a direct pointer to the
section table.
Offset Size Header Part
0x1C 4 bytes PointerToLineNumbers
0x20 2 bytes NumberOfRelocations
0x22 2 bytes NumberOfLineNumbers
0x24 4 bytes Characteristics
Offset Size Header Part
0 8 bytes Name
0x8 4 bytes VirtualSize
0xC 4 bytes VirtualAddress
0x10 4 bytes SizeOfRawData
0x14 4 bytes PointerToRawData
0x18 4 bytes PointerToRelocations
18. PE - DISASSEMBLER
Exports Section –
The Export Directory Table (described in WINNT.H by
the structure IMAGE_EXPORT_DIRECTORY) is used to
resolve references to the functions exported within
from the image.
Offset Size Field
0 4 bytes Export Flags
0x4 4 bytes Time/Date Stamp
0x8 2 bytes Major Version
0xA 2 bytes Minor Version
0xC 4 bytes Name RVA
0x10 4 bytes Ordinal Base
Offset Size Field
0x14 4 bytes Address Table Entries
0x18 4 bytes Number of Name Pointers
0x1C 4 bytes Export Address Table RVA
0x20 4 bytes Export Name Pointer RVA
0x24 4 bytes Export Ordinal Table RVA
19. PE - DISASSEMBLER
Exports Section –
On the next slide we will “try to” see all the
functions exported by kernel32.dll
Export Ordinal Table
* We are ignoring
Export Forwarding
for now.
[Picture taken from Matt Pietrek’s article, msdnmag - FEB 2002
21. PE - DISASSEMBLER
Imports Section –
There is One Import Directory Table (described in WINNT.H by
IMAGE_IMPORT_DESCRIPTOR) for each imported binary module
(DLL).
The Import Directory Table consists of an array of Import Directory
Entries, one entry for each DLL the image references.
Offset Size Field
0x0 4 bytes Import Lookup Table (RVA)
0x4 4 bytes Time-Date Stamp
0x8 4 bytes Forwarder Chain
0xC 4 bytes Imported DLL Name (RVA)
0x10 4 bytes Import Address Table (RVA)
22. PE - DISASSEMBLER
Imports Section - Import Address Table
[Picture taken from Matt Pietrek’s article, msdnmag - FEB 2002
23. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading
Support
Kernel Mode Device Driver
24. SYMBOL HANDLER
SYMBOL HANDLER -
For creating a source-level debugger, the most
important module is the Symbol Handler.
For the time being, we will be working with the .PDB
(program database) symbol files only.
.PDB files are convenient as the debug information is
stored separately from the binaries.
Microsoft provides DBGHELP.DLL library to aid
symbol handling.
25. SYMBOL HANDLER
SYMBOL FILES -
Debuggers can determine if debug symbols are
stored outside the binary (E.g. in separate .pdb files)
by searching for the IMAGE_FILE_DEBUG_STRIPPED
characteristic.
Windows OS also distributes debug symbols for
several system dlls.
However the line, variable, source info are stripped
from those OS symbols. They provide only public
symbols and FPO data for call stack viewing.
26. [Screenshot from the XDBG prototype]
Source
Files with
which the
binary
links
Binary’s Symbol
Table loaded
28. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading
Support
Kernel Mode Device Driver
29. P-T-M Enumerator
P-T-M Enumeration –
A debugger must be able to enumerate processes
and threads (and the modules loaded in their address
spaces) are currently running on the system.
If sufficient privileges available, the debugger can
attach to processes and start debugging them.
In that case, debug symbols will almost always be
unavailable….but that is for later
31. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading
Support
Kernel Mode Device Driver
32. Responsibilities of a Debugger Engine -
Attaching to an existing process. Alternatively starting a process
under debugger.
Waiting on OS notifications inside a “debug loop” –
Process creation / destruction
Thread creation / destruction
Module Load / Unload
Exceptions generated inside debuggee.
Responding to User Commands –
Interacting with Symbol handler and Breakpoint/Watchpoint modules to
set breakpoints or to single-step.
Showing Call Stacks, Memory Dumps, loaded module list etc.
Detaching from debuggee
Terminating debugger / debuggee
Suspending, Resuming threads.
DEBUG EVENTS
33. DEBUG EVENTS
PROCESS DEBUGGING –
Instead of attaching to an active process, the
debugger can open a process for debugging from a
binary execution image.
The CreateProcess() function enables a debugger to
start this process and debug it.
fdwCreate ->
DEBUG_PROCESS : debugger debugs the new
process and all of the process's descendants.
DEBUG_ONLY_THIS_PROCESS : debugger debugs
the new process but not its descendants.
34. DEBUG EVENTS
DEBUG EVENTS -
Debugger can monitor the Debug Events generated
by the Debuggee.
The following events can be monitored –
Process Creation (or Attachment) Events.
Thread Creation Events.
Generated Exceptions
Thread Exit Events
Process Exit Events
DLL Load Events
DLL Unload Events
Debugger Communication Events
35. DEBUG EVENTS
DEBUG EVENTS –
CREATE_PROCESS_DEBUG_EVENT
Generated whenever the debugger begins
debugging an already active process.
Also generated whenever a new process is created
in a process being debugged.
The system generates this debugging event
before the process begins to execute in user
mode and
before the system generates any other
debugging events for the new process.
36. DEBUG EVENTS
DEBUG EVENTS –
CREATE_THREAD_DEBUG_EVENT
Generated whenever the debugger begins
debugging an already active process.
Also Generated whenever a new thread is
created in a process being debugged or
This debugging event is generated before the
new thread begins to execute in user mode.
37. DEBUG EVENTS
DEBUG EVENTS –
EXIT_PROCESS_DEBUG_EVENT
Generated whenever the last thread in a process
being debugged exits.
This debugging event occurs immediately after the
system unloads the process's DLLs and updates
the process's exit code.
The debugger deallocates any internal structures
associated with the process on receipt of this
debugging event.
38. DEBUG EVENTS
DEBUG EVENTS –
EXIT_THREAD_DEBUG_EVENT
Generated whenever a thread that is part of a process
being debugged exits.
The system generates this debugging event
immediately after it updates the thread's exit code.
The debugger deallocates any internal structures
associated with the process on receipt of this debugging
event.
This debugging event does not occur if the exiting
thread is the last thread of a process.
39. DEBUG EVENTS
DEBUG EVENTS –
LOAD_DLL_DEBUG_EVENT
Generated whenever a process being debugged
loads a DLL by calling LoadLibrary() function.
This debugging event occurs when the system
loader resolves links to a DLL (loaded inside the
debuggee’s address space.)
If the DLL's reference count falls to 0, the DLL is
unloaded. The next time the DLL is loaded, this
event will be generated again.
40. DEBUG EVENTS
DEBUG EVENTS –
UNLOAD_DLL_DEBUG_EVENT
Generated whenever a process being debugged unloads
a DLL by calling FreeLibrary() function.
This debugging event only occurs the last time a DLL is
unloaded from a process's address space (that is, when
the DLL's usage count is zero).
Typically, a debugger unloads a symbol table associated
with the DLL on receipt of this debugging event.
When a process exits, the system automatically unloads
the process's DLLs, but does not generate an
UNLOAD_DLL_DEBUG_EVENT debugging event.
41. DEBUG EVENTS
DEBUG EVENTS –
OUTPUT_DEBUG_STRING_EVENT
Generated when a process being debugged
uses the OutputDebugString() function.
The OutputDebugString() function sends a
string to the debugger for display
This method is used by the debuggee to
communicate with the debugger.
42. DEBUG EVENTS
DEBUG EVENTS –
EXCEPTION_DEBUG_EVENT
Generated whenever an exception occurs in
the process being debugged.
Possible exceptions include –
attempting to access inaccessible memory
executing breakpoint instructions
attempting to divide by zero
other exception noted in Structured Exception
Handling.
43. [Screenshot from the XDBG prototype]
Debuggee
(Process being debugged)
Debugger
(Monitors Debug Events in Debug Loop)
44. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading
Support
Kernel Mode Device Driver
47. BREAKPOINTS
HARDWARE BREAKPOINTS –
On IA-32 Processors, Hardware Debugging Support is
enabled through -
Debug Registers DR0 – DR7
Support Hardware Breakpoints
Model Specific Registers (MSRs)
Monitors & Records the following –
Branches Taken
Occurred Interrupts
Occurred Exceptions
48. BREAKPOINTS
HARDWARE BREAKPOINTS –
1 to 4 Hardware Breakpoints can be set.
For each Breakpoint the following info can be
specified and detected –
32 Bit Linear Address of the Breakpoint
Length (size) of the Breakpoint Location
Breakpoint Trigger Condition
Is the Breakpoint enabled ?
49. BREAKPOINTS
DR0 – DR5 Registers -
DR0 – DR3 hold the 32 Bit Linear Addresses
of the breakpoints.
DR4 – DR5 are reserved registers *
Breakpoint comparisons are made before
the physical address translation occurs
* Reserved when DE flag in CR4 set, else aliased to DR6, DR7
50. BREAKPOINTS
DRO – DR5 Registers -
31 0
RESERVED
31 0
BREAKPOINT 0 - 32 Bit LINEAR ADDRESS
31 0
BREAKPOINT 1 - 32 Bit LINEAR ADDRESS
31 0
BREAKPOINT 2 - 32 Bit LINEAR ADDRESS
31 0
BREAKPOINT 3- 32 Bit LINEAR ADDRESS
31 0
RESERVED
DR0
DR1
DR4
DR3
DR2
DR5
51. BREAKPOINTS
DR6 Register -
DR6 is a Debug Status Register, reporting the conditions
under which the hardware breakpoint was triggered.
DR6 Fields are -
Fields Meaning Description
B0 – B3 Breakpoint Condition Detected Debug Exception was generated because the
associated breakpoint condition was met.
BD Debug Register Access Detected Next Instruction will access one of the Debug
Registers DR0 – DR7.
BS Single Step Flag Debug Exception was generated by Single-Stepping
Execution Mode.
BT Task Switch Flag Debug Exception resulted from a Task Switch where
the Trap Flag in the TSS of target task was set.
DR6 fields must be cleared by the Debugger, before returning to the interrupted task.
52. BREAKPOINTS
DR6 Register –
31 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Reserved (Set to 1) B
T
B
S
B
D
0 1 1 1 1 1 1 1 1 B
3
B
2
B
1
B
0
D
R
6
Reserved Fields
Breakpoint
Condition
Detected
Flags
Debug
Register
Access
Detected
Flag
Task
Switch
Flag
Single
Step
Flag
53. BREAKPOINTS
DR7 Register -
The DR7 Register is the Debug Control Register. It
Enables/Disables breakpoints and
Sets breakpoint conditions.
DR7 Fields are –
Fields Meaning Description
L0 – L3 Local Breakpoint Enable Enables the trigger condition for associated Hardware
Breakpoint for current task
G0 – G3 Global Breakpoint Enable Enables the trigger condition for associated Hardware
Breakpoint for all tasks
GD General Detect Enable Causes Debug Exception to be generated prior to any MOV
instruction that access a Debug Register (DR0 – DR7)
Continued on next slide….
54. BREAKPOINTS
DR7 Register -
DR7 Fields are (Continued from Previous Slide) –
Fields Meaning Description
LE Local Exact Breakpoint
Enable
Processor can detect exact instruction that caused the
Local Breakpoint Condition to trigger.
GE Global Exact Breakpoint
Enable
Processor can detect exact instruction that caused the
Global Breakpoint Condition to trigger.
R/W0 –
R/W3
Read/Write Breakpoint
Condition
Specifies the data read, data write, instruction execution,
instruction fetch conditions on which to trigger.
LEN0 –
LEN3
Breakpoint Location Size Specifies length of the memory location at the address
specified in corresponding address registers (DR0–DR3)
55. BREAKPOINTS
DR7 Register -
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
LEN
3
R/W
3
LEN
2
R/W
2
LEN
1
R/W
1
LEN
0
R/W
0
0 0 G
D
0 0 1 G
E
L
E
G
3
L
3
G
2
L
2
G
1
L
1
G
0
L
0
D
R
7
Local Breakpoint Enable
Global Breakpoint Enable
Read/Write Breakpoint
Condition
Breakpoint Location Size
Reserved Fields
General
Detect Enable
Global Exact Breakpoint Enable
Local Exact Breakpoint Enable
57. [Screenshot from the XDBG prototype]
Triggering
Hardware
Breakpoint
Inside
Debuggee
Detected
by
Debugger
58. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading Support
Kernel Mode Device Driver
59. VIRTUAL ADDRESS SPACE VIEWER
Address Spaces for 32 bit processes
Total 4 GB Virtual Address Space
0x00000000 to 0xFFFFFFFF
Only lower 2 GB available to a process
0x00000000 to 0x7FFFFFFF
Upper 2 GB reserved by Windows
0x80000000 to 0xFFFFFFFF
65,536 bytes Guard Region
60. State of an address [FREE] –
This is the initial State of an address.
An address in FREE state can be
RESERVED for future use
COMMITTED to memory
Any attempt to access an address in FREE state
results in an “Access Violation Exception”
VIRTUAL ADDRESS SPACE VIEWER
61. State of an address [RESERVED] –
Reserves a FREE address range until needed,
protecting them from other allocation requests.
Reserving is mainly done to prevent the Windows
Loader from loading a DLLs or resources into the
specified addresses.
Any attempt to access an address in FREE state
results in an “Access Violation Exception”.
VIRTUAL ADDRESS SPACE VIEWER
62. State of an address [RESERVED] –
Reserving does not mean that these addresses are mapped
to physical memory. No pages of physical memory are
committed in this process.
Reserving a range of addresses is no guarantee that at a
later time there will be physical memory available to
commit to those addresses.
Reserving only makes an entry into the process's virtual
address descriptor (VAD) tree.
At present I have not idea how windows implements
this !
VIRTUAL ADDRESS SPACE VIEWER
63. State of an address [COMMITTED] –
To use any address, it must be in a COMMITTED state, i.e.
it must be mapped to physical memory.
For Committing Memory,
Minimum Size -> 1 Page Size (4 KB ?)
Maximum Size -> Biggest contiguous range available
Committed memory can have,
Page Read Only Access
Page Read Write Access
Page No Access
VIRTUAL ADDRESS SPACE VIEWER
64. VIRTUAL ADDRESS SPACE VIEWER
Protection for Committed addresses-
Read Write Execute Read-on-write Copy-on-write
PAGE_EXECUTE - - Y - -
PAGE_EXECUTE_READ Y - Y - -
PAGE_EXECUTE_READWRITE Y Y Y - -
PAGE_EXECUTE_WRITECOPY - - Y Y Y
PAGE_READONLY Y - - - -
PAGE_NOACCESS - - - - -
PAGE_READWRITE Y Y - - -
PAGE_WRITECOPY - - - - Y
66. VIRTUAL ADDRESS SPACE VIEWER
Translation of Virtual Addresses -
Let us do an example address 0x186F103A.
In Binary 00011000 01101111 00010000 00111010
We need to split the address as follows –
So we get - 00011000 01101111 00010000 00111010
All 10-bit offsets to be padded with lower order zeros –
0001 1000 0100
1011 1100 0100
0000 0011 1010
31 22 21 12 11 0
10 bit offset 10 bit offset 12 bit offset
Padded with zeros
67. VIRTUAL ADDRESS SPACE VIEWER
Paging Example
0 (PDE)
: (PDE)
:(PDE)
:(PDE)
1023
0(PTE)
:(PTE)
:(PTE)
:(PTE)
1023(PTE)
4096
KB
Page
Directory
Page
Table
Page
Frame
0001 1000 0100
Offset into Page
Directory
Location of
Page Table
1011 1100 0100
Offset into Page
Table
Location of
Page Frame
Offset of referred
byte in frame
0000 0011 1010
Physical address not available to user !Virtual address available to user !
69. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading Support
Kernel Mode Device Driver
70. MEMORY DUMPER
Hex Dump of Memory locations –
A Memory location can be read only if a virtual address in
mapped to that physical location (i.e. COMMITTED).
Also it must have a READ protection enabled (either
PAGE_READWRITE, PAGE_EXECUTE_READWRITE,
PAGE_EXECUTE_READ, PAGE_READONLY).
Else an access violation exception will be generated !
72. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading Support
Kernel Mode Device Driver
73. CALL STACK VIEWER
Function Call Mechanism –
Consider the caller code …..
.
.
.
Callee ( a, b, c, &d ) ; // calls the callee
.
.
Consider the callee code ……
void callee ( int i, double d, char c, int * pi )
{ // local variables
int x ;
Char y ;
}
74. CALL STACK VIEWER
Function Call Mechanism –
Control is with the caller.
ESPa (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)ESP
Initially
Arguments
pushed on
stack
Return
Address on
stack
ESPEIP (ret addr)
a (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
75. CALL STACK VIEWER
Function Call Mechanism –
Control goes to callee. (the prolog begins)
Base (Frame)
pointer goes
on stack
EBP saved
EIP (ret addr)
a (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
ESP EBP saved
EIP (ret addr)
a (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
ESP
ESP copied
into EBP
EBP
Y (1 byte)
X (4 bytes)
EBP saved
EIP (ret addr)
a (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
ESP
EBP
Locals on stack
PUSH EBP
MOV EBP, ESP
SUB ESP, 0x5
76. CALL STACK VIEWER
Function Call Mechanism –
Control still with callee. (the epilog begins)
EBP saved
EIP (ret addr)
a (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
ESPEBP
ESP
decremented.
ESPEIP (ret addr)
a (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
EBP restored
by popping
stack
MOV ESP, EBP
POP EBP
77. CALL STACK VIEWER
Function Call Mechanism –
Control returns to caller.
ESPa (4 bytes)
b (8 bytes)
c (1 byte)
&d (4 bytes)
EIP used to
return, now
popped
ESP
Done !
78. CALL STACK VIEWER
Calling Conventions -
Calling
Convention
Argument Passing Stack Maintenance Name Decoration Notes
__cdecl Right to left Caller removes
arguments from
Stack
Yes Default for
C/C++
Functions
__stdcall Right to left Callee removes
arguments from stack
yes Used by almost
all Win32 API
functions.
COM methods
also use this.
__fastcall First two DWORD params
in ECX and EDX registers.
Rest in right to left
Callee removes
arguments from
Stack
yes Applies only to
Intel CPUs.
this Right to left. The
this parameter is
passed in ECX
register
Caller removes
arguments from
Stack
none default for C++
class methods.
naked Right to left Caller removes
arguments from
Stack
none custom prolog
and epilog
79. CALL STACK VIEWER
Frame Pointer Omission –
Methods to walk the stack
Manually, using the call mechanism just described
Using Debug Symbols (.pdb files)
Why the latter is preferred ?
Compiler optimizations can force frequently accessed
variables onto registers instead of the stack.
In some cases, the compiler might not generate the
stack frame at all.
Compiler generates FPO data during such optimizations
Lookup WINNT.H for FPO structures.
81. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading
Support
Kernel Mode Device Driver
82. SINGLE STEPPING MODE
Single Stepping Mode -
In this mode it becomes possible to implement the
following functionalities –
Step Into, Step Over, Step Out
All of the above mentioned functionality work on one-shot
software breakpoints.
Single Stepping at source level requires a complete
implementation of the symbol Engine.
Also for single stepping at assembly level, requires a
complete implementation of the PE disassembler to retrieve
instruction lengths.
Consequently, I have decided to implement this module
only in the end.
83. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space
Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading
Support
Kernel Mode Device Driver
84. IA-32 PROCESSOR FEATURES
Intel CPU Identification -
Originally, Intel published small code snippets that could
detect architectural implementation.
Later, with the advent of the i386 processor, Intel
implemented “processor signature” identification that upon
reset provided the following
processor family,
Model encoding,
stepping numbers.
With the Pentium Family onwards the CPUID instruction
provides not only the “processor signature”, but also
provides information on processor supported features.
85. IA-32 PROCESSOR FEATURES
Processor Signature –
32 bit signature with 6 fields.
Execute CPUID (opcodes 0x0F, 0xA2) with EAX = 0x1,
The Processor Signature is returned in EDX
31 28 27 20 19 16 15 14 13 12 11 8 7 4 3 0
Reserved Extended
Family
Extended
Model
Reserved Type
Encoding
Family
Code
Model
Encoding
Stepping
ID
EAX
Value Description
0x00 Original OEM Processor
0x01 Overdrive Processor
0x10 Dual Processor
0x11 Reserved
Model of Processor within
Processor Family
Processor Family
Revision
Number
of
Processor
Model
86. IA-32 PROCESSOR FEATURES
Brand ID –
Is an extension to the processor signature.
Only supported P3 family upwards (check Intel Manual).
Execute CPUID with EAX = 0x1, the Brand Id is returned in
EBX[7:0]
Brand String –
96 bit ASCII String indicating ID + Max Operating Freq.
Only supported P4 family upwards (check Intel Manual).
EAX Description
0x80000002 EAX, EBX, ECX, EDX – Brand String Start
0x80000003 EAX, EBX, ECX, EDX – Brand String Continued
0x80000004 EAX, EBX, ECX, EDX – Brand String Continued
CPUID with
88. IA-32 PROCESSOR FEATURES
Feature Flags + Extended Feature Flags –
Complete list of processor supported features.
Execute CPUID with EAX = 0x1, the Feature Flags are
dumped into EDX, ECX registers.
If corresponding bit is set, feature is available.
Similarly, executing CPUID with EAX = 0x80000001, the
Extended Feature Flags are placed in EDX.
Some of the feature flags of interest are –
Bits Flag Name
EDX[1] Virtual Mode Extension
EDX[2] Debugging Extension
EDX[5] Model Specific Registers
EDX[9] On-Chip APIC Support
EDX[21] Debug Store
Bits Flag Name
EDX[28] Hyperthreading Support
ECX[3] MONITOR / MWAIT
ECX[4] CPL Qualified Debug Store
ECX[10] (L1 cache mode) Context Id
EDX[29] Intel EMT-64 *
Extended
Feature
Flag
89. [Screenshot from the XDBG prototype]
Processor
supported
Features
Feature Flags
+
Extended
Feature Flags
90. IA-32 CACHE CONFIGURATION
Cache & TLB Configuration –
When CPUID executed with EAX = 0x2 --->
EAX, EBX, ECX, EDX loaded with 8-bit Cache, TLB descriptors.
Descriptor Decode Values are available from Intel Manuals
Lower 8 bits of the
EAX register (AL)
= Number of times CPUID has to be executed to obtain a
complete image of the processor’s caching system.
EAX[31]
EBX[31]
ECX[31]
EDX[31]
=
=
=
=
Validity of EAX[31:24], EAX[23:16], EAX[15:8], EAX[7:0] descriptors.
Validity of EBX[31:24], EBX[23:16], EBX[15:8], EBX[7:0] descriptors.
Validity of ECX[31:24], ECX[23:16], ECX[15:8], ECX[7:0] descriptors.
Validity of EDX[31:24], EDX[23:16], EDX[15:8], EDX[7:0] descriptors.
* Move sequentially from MSB to LSB for all descriptors
91. IA-32 CACHE CONFIGURATION
TLB Buffers –
Translation Lookaside Buffer is nothing but a cache buffer.
Frequently accessed Virtual addresses and their associated
page frames numbers are stored in the TLB.
TLB flushes on context switches.
Trace Caches –
After instructions are retired from the execution pipeline,
they are stored in a trace cache.
If program counters access that instruction frequently,
It is reloaded from the trace cache
This action reduces the pre-fetch bandwidth.
92. [Screenshot from the XDBG prototype]
Get configuration of –
1. L1 Data Cache
2. L1 Instruction Cache
3. L2 Unified Cache
4. L3 Unified Cache
5. Trace Cache
6. Data TLB
7. Instruction TLB
8. Prefetch Buffer
93. HYPERTHREADING SUPPORT
We have currently defined four status flags
for Hyperthreading support –
Hyper Threading NOT SUPPORTED
EDX[28] i.e. hyperthreading bit is disabled. Host processor does
not have the facility to support hyperthreading.
Hyper Threading NOT DETECTED
If (process affinity mask != system affinity mask), then it means
that some physical processors have been disabled. Hence
hyperthreading cannot be detected.
Hyper Threading DISABLED
If (logical processor count = 1), then
Hyperthreading disabled by system BIOS.
Hyper Threading ENABLED
Hyper Threading Supported and Enabled.
94. [Screenshot from the XDBG prototype]
System & Process Affinity
Hyperthreading disabled
Only one physical processor
On a Uniprocessor
95. [Screenshot from the XDBG prototype]
System & Process Affinity
Hyperthreading enabled
two logical processors per
physical processor core
On Hyperthreaded processor
96. XDBG – Debugger Prototype
CONTENTS
PE - Disassembler
Symbol Handler
P-T-M Enumerator
Debug Events
Breakpoints
Virtual Address Space Viewer
Memory Dumper
Call Stack Viewer
Single Stepping Mode
Architecture Analyzer
Processor Features
Cache Configurations
Hyperthreading Support
Kernel Mode Device Driver
97. KERNEL MODE DEVICE DRIVER
Need For Kernel Model Device Driver -
Among other things, XDBG’s Hardware Event
Monitor
Needs to read/write several IA-32 Model Specific
Registers.
Needs to set up a DS (Debug Store) Interrupt
Service Routine for Precise Event Based Sampling
(PEBS) of Hardware Events.
All of these above-mentioned operations have to be
performed in Kernel Mode.
98. KERNEL MODE DEVICE DRIVER
Standard Driver Routines –
XDBG’s Kernel mode Driver conforms to the
WDM model.
Hence it contains the following standard Driver
routines to handle IO request packets (IRP) –
Driver Entry Routine
Add Device Routine
Dispatch Routine
Driver Unload Routine
Initializes Driver
Initializes Device
Processes IO Request Packets
Unloads Driver
99. KERNEL MODE DEVICE DRIVER
IO Control Codes -
We are using I/O control codes (IOCTLs) for communication
between our user-mode debugger and the Kernel Mode Driver.
We are defining our own IOCTLs for Reading & Writing MSRs
The following shows the layout of an IOCTL -
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
C Device Type Req
Acc
C Function Code T
T
Transfer
Type
Function
Code
CustomCommon
Device
Type
Required
Access
100. KERNEL MODE DEVICE DRIVER
IO Control Codes –
From the IOCTL Layout –
We use the system-supplied CTL_CODE macro (defined in
wdm.h) to define new I/O control codes
The DeviceIoControl() function sends the IO control code
directly to the kernel mode driver.
Device Type Identifies Device type. Values greater than 0x8000 can be used.
Required Access Specifies the access rights required by IO Manager to create IRP.
Function Code Identifies the function to be performed by the driver.
Transfer Type Indicates how the system will handle data passed between user
mode application and kernel mode device driver that handles the
IRP