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
(wn*)object)->__vptr
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* 068 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))) 064
(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
!address>
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 http://www.codeguru.com/cpp/w-p/win32/tutorials/article.php/c9535/.