MindshaRE is our weekly look at some simple reverse engineering tips and tricks. The goal is to keep things small and discuss every day aspects of reversing. You can view previous entries here by going through our blog history.
WinDbg extensions are libraries that can be written to compliment the built in debugger commands. Many Microsoft provided extensions are already pre-bundled with the debugging tools for windows package. To allow others to contribute to the ever growing command list Microsoft also provides an SDK for creating third party plugins.
When WinDbg is started, it automatically loads the default extensions you have in your installation directories extension folder (c:\Program Files\Debugging Tools for Windows\(winext|winxp|win2k[chk|fre])\). Once loaded the exported commands available are executed using the ! prefix to the command name. Lets take a quick look at some handy default extension provided commands.
The !analyze command is very useful when an access violation occurs during a debugging session. It gathers all of the pertinent information regarding the violation and formats it so that it is easier to read. Here is the output from a crash.
(178c.16e4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0007f998 ebx=000b33c8 ecx=000b02c8 edx=00000000 esi=80000000 edi=000b33d4
eip=01012318 esp=0007f974 ebp=00000000 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
calc!mulnumx+0x4:
01012318 8b750c mov esi,dword ptr [ebp+0Ch] ss:0023:0000000c=????????
0:000> !analyze -v
FAULTING_IP:
calc!mulnumx+4
01012318 8b750c mov esi,dword ptr [ebp+0Ch]
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 01012318 (calc!mulnumx+0x00000004)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 0000000c
Attempt to read from address 0000000c
FAULTING_THREAD: 000016e4
PROCESS_NAME: calc.exe
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memoryat "0x%08lx". The memory could not be "%s".
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memoryat "0x%08lx". The memory could not be "%s".
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 0000000c
READ_ADDRESS: 0000000c
FOLLOWUP_IP:
calc!mulnumx+4
01012318 8b750c mov esi,dword ptr [ebp+0Ch]
NTGLOBALFLAG: 0
APPLICATION_VERIFIER_FLAGS: 0
DEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE
PRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCE
BUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE
LAST_CONTROL_TRANSFER: from 00000000 to 01012318
STACK_TEXT:
00000000 00000000 00000000 00000000 00000000 calc!mulnumx+0x4
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: calc!mulnumx+4
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: calc
IMAGE_NAME: calc.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 3b7d8410
STACK_COMMAND: ~0s ; kb
FAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_calc.exe!mulnumx
BUCKET_ID: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_calc!mulnumx+4
Followup: MachineOwner
---------
Using the -v option with analyze displays a great summarization of the process, and why it crashed. Some interesting things to note are the DEFAULT_BUCKET_ID, and LAST_CONROL_TRANSFER items.
The next extension provided command, which can be useful when working with malware, is the !dh command. !dh will display the image header specified, in an easy to read manner. Here is an example.
0:000> !dh calc
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (i386)
3 number of sections
3B7D8410 time date stamp Fri Aug 17 15:52:32 2001
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
10F characteristics
Relocations stripped
Executable
Line numbers stripped
Symbols stripped
32 bit word machine
OPTIONAL HEADER VALUES
10B magic #
7.00 linker version
12800 size of code
9C00 size of initialized data
0 size of uninitialized data
12475 address of entry point
1000 base of code
----- new -----
01000000 image base
1000 section alignment
200 file alignment
2 subsystem (Windows GUI)
5.01 operating system version
5.01 image version
4.00 subsystem version
1F000 size of image
400 size of headers
1D7FC checksum
00040000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
0 [ 0] address [size] of Export Directory
12B80 [ 8C] address [size] of Import Directory
16000 [ 8960] address [size] of Resource Directory
0 [ 0] address [size] of Exception Directory
0 [ 0] address [size] of Security Directory
0 [ 0] address [size] of Base Relocation Directory
1240 [ 1C] address [size] of Debug Directory
0 [ 0] address [size] of Description Directory
0 [ 0] address [size] of Special Directory
0 [ 0] address [size] of Thread Storage Directory
0 [ 0] address [size] of Load Configuration Directory
260 [ 80] address [size] of Bound Import Directory
1000 [ 228] address [size] of Import Address Table Directory
0 [ 0] address [size] of Delay Import Directory
0 [ 0] address [size] of COR20 Header Directory
0 [ 0] address [size] of Reserved Directory
SECTION HEADER #1
.text name
126B0 virtual size
1000 virtual address
12800 size of raw data
400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
(no align specified)
Execute Read
Debug Directories(1)
Type Size Address Pointer
cv 19 160c a0c Format: NB10, 3b7d8410, 1, calc.pdb
SECTION HEADER #2
.data name
101C virtual size
14000 virtual address
A00 size of raw data
12C00 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
(no align specified)
Read Write
SECTION HEADER #3
.rsrc name
8960 virtual size
16000 virtual address
8A00 size of raw data
13600 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
(no align specified)
Read Only
My next handy example will dump the SEH chain from the current process. We use this all the time to verify when an overflow has smashed the chain allowing simple code execution. To view this we use !exchain.
0:000> !exchain
0007faec: calc!terminate+10 (010128f8)
0007fb14: calc!terminate+1a (01012902)
0007fbcc: USER32!_except_handler3+0 (7e44048f)
0007fd88: USER32!_except_handler3+0 (7e44048f)
0007fde8: USER32!_except_handler3+0 (7e44048f)
0007ff10: calc!terminate+6 (010128ee)
0007ffb0: calc!_except_handler3+0 (010128e2)
0007ffe0: kernel32!_except_handler3+0 (7c839ac0)
In the case of an overflow we might see something like this.
0:000> !exchain
0007ffe0: 41414141
Invalid exception stack at 41414141
This tells us the pointers to the chain on the stack have been overwritten.
!handle will dump fantastic information pertaining to a specified handle. You can get a list of handles by issuing a 0 for the handle id. Here is an example of a handle to an open registry key.
0:000> !handle 28 f
Handle 28
Type Key
Attributes 0
GrantedAccess 0xf003f:
Delete,ReadControl,WriteDac,WriteOwner
QueryValue,SetValue,CreateSubKey,EnumSubKey,Notify,CreateLink
HandleCount 2
PointerCount 3
Name \REGISTRY\MACHINE
Object Specific Information
Key last write time: 15:16:40. 1/21/2009
Key name MACHINE
Of particular interest is the Name field associated with this handle. Note that this also works for file handles.
This is just a few of the numerous extensions provided with the debugging tools package. The following list are several other extensions provided by Microsoft, each containing dozens of commands.
Logger Extensions (Logexts.dll)
NDIS Extensions (Ndiskd.dll)
RPC Extensions (Rpcexts.dll)
ACPI Extensions (Acpikd.dll and Kdexts.dll)
NDIS Extensions (Ndiskd.dll)
Graphics Driver Extensions (Gdikdx.dll)
Kernel Streaming Extensions (Ks.dll)
SCSI Miniport Extensions (SCSIkd.dll and Minipkd.dll)
Kernel-Mode Driver Framework Extensions (Wdfkd.dll)
User-Mode Driver Framework Extensions (Wudfext.dll)
WMI Tracing Extensions (Wmitrace.dll)
OEM Support Extensions (Kdex2x86.dll)
0:002> !remotecall 01007C4C 0 10 5
calc!longtonum() will be run when execution is resumed
0:002> g
Files\Debugging Tools for Windows\winext\sdbgext.dll -
calc!longtonum() [conv=0 argc=8 argv=00C20488]
calc!longtonum() returned 000B32D8
We can see all of the extensions defined commands by issuing the !help command (Many commands have been omitted).
0:001> !load sdbgext
0:001> !help
Skywing Debugger Extensions (SDbgExt) help
!valloc [address] <size> <type> <protect> Allocates virtual memory
...
!loaddll <dllname> Loads a dll into the target process (from a new thread)
...
!heapalloc [heap] <size> Allocates heap memory (defaults to the process heap)
...
!loadsym <module> [symbol list file] [path] Loads custom symbols from a symbol list file.
...
!cmpmem <[[-a|-x] addr length] | [-e addr] | [-c addr] [-s addr] [-l]>
Compares memory over time.
...
More information about Skywing's extension can be found in his two part series on the extension at his blog.
Microsoft has really gone the extra mile to make their debugger full featured by providing extra extensions. Hundreds of useful commands are at your fingertips. Open the WinDbg help file and take a look. I hope you find something you've been wanting.
-Cody
