Register Usage

EAX return value of the last function call if it can be stored in a register (see below).
ECX used to hold the 'this' pointer when in a method call.
EDX used to point to the vtable entry of the function to be called when dispatching a virtual function.

Loading SOS

Using WinDBG

.NET 1.x .load clr10\sos
.NET 2.0, 3.0, 3.5 .loadby sos mscorwks
.NET 4.0 .loadby sos clr

Working out where a COM Object comes from

If you’ve got a lot of DLLs that contain an implementation of a particular interface and you want to know which one you need to compile in debug mode for a particular case.

If you’re calling from C++ look at


In Visual Studio look this value up in the Modules list to find out which it belongs to. If you’re in WinDBG then the incantation would be something like

0; dv
     pstm = 0x000c7568
0; dt psf
Lr @ 0x7cc2c Type IStream*
 0 __VFN_table : 0x1c9c8e84
0; ln 0x1c9c8e84
(4)   SomeDLL!SomeClass::`vftable'

If you’re calling from C# it’s more involved (slightly), in the intermediate window do

&l _dbg_attr;
f(int*)(((System.__ComObject)instrumentNavigator).GetIUnknown(out _dbg_attr)))

(If you don’t get 0x.. the value is in decimal). Then look this value up.

If you can’t find a module that spans the address of the vtable then the COM objects been written in C# and you’ve got the address of the JIT’ed code. Unfortunately I haven’t found a good trick for turning that into a DLL name.

Return Values

(Assuming the standard Windows calling convention.)

Simple types that can fit in a register are returned as EAX.

Doubles and floats are pushed on to the top of the floating point stack (ST0 register).

Classes and Structs are returned with a pointer to the object in EAX.

The same applies to the CLR. If you have SOS loaded you can get information on the returned value by doing


Garbage Memory Values

0xCDCDCDCD Clean memory, allocated with malloc or new but not filled.
0xDDDDDDDD Dead memory, released with delete or free.
0xFDFDFDFD Fence memory, put either side of allocated memory as a buffer zone (ie. seen when array indices go out of bounds or similar).
0xABABABAB Allocated Block, allocated by LocalAlloc.
0xBAADF00D Allocated by LocalAlloc with LMEM_FIXED.
0xCCCCCCCC Unassigned local variable (requires code to be compiled with the `/GZ` flag). `CC` is the single byte INT 3 opcode which will break into the debugger, so if the stack starts executing you may get lucky (in debug mode).
0xFEEEFEEE OS filled heap memory which was marked for usage but wasn't allocated with HeapAlloc() or LocalAlloc(), or memory that has been freed with HeapFree().

For a good explanation for how these are fitted together in see