Search code examples
windbgsos

How to reference 32bit integer data in a 64 bit dump


If I have a System.Int32 at a known memory address of a 64-bit .Net process dump, how can I reference its data in a condition or expression in windbg? For example:

? poi(000000ba2e4de938) == 0n27 is displaying as 0 instead of 1, even though I know that the value at that address is 27 (dt int 000000ba2e4de938 displays 0n27). It is doing so, because it picks up 32 junk bits after the value I am attempting to access, since poi grabs pointer-sized data.

Is there a way to grab data of a certain size to use within expressions? I have so far only found ways to dump the data, but not use it within expressions or conditions.


Solution

  • Short answer: use dwo(...) for 32 bits, qwo(...) for 64 bits and poi(...) for architecture dependent size.

    Long answer:

    Let's look at an Int32 with SOS first:

    0:014> .symfix
    0:014> .reload
    0:014> .loadby sos clr
    0:006> !name2ee *!System.Int32
    Module:      000007feecab1000
    Assembly:    mscorlib.dll
    Token:       00000000020000f0
    MethodTable: 000007feed1603d0
    EEClass:     000007feecb71810
    Name:        System.Int32
    [...]
    0:006> !dumpheap -mt 000007feed1603d0
             Address               MT     Size
    00000000028376d8 000007feed1603d0       24 
    
    0:006> !do 00000000028376d8 
    Name:        System.Int32
    MethodTable: 000007feed1603d0
    EEClass:     000007feecb71810
    Size:        24(0x18) bytes
    File:        C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
    Fields:
                  MT    Field   Offset                 Type VT     Attr            Value Name
    000007feed1603d0  400055f        8         System.Int32  1 instance             8868 m_value
    

    From that output, you can see that the value (m_value) of the Int32 is at the address of the object + an offset of 8.

    The length of Int32 is 32 bit, so we need the dd (dump DWORD) to look at the memory:

    0:006> dd 00000000028376d8+8 L1
    00000000`028376e0  000022a4
    

    Convert that into decimal and it'll be what has been displayed by SOS before:

    0:006> ? 22a4
    Evaluate expression: 8868 = 00000000`000022a4
    

    To use it in a condition, use dwo (DWORD size) instead of poi (pointer size, which is qwo on 64 bits):

    0:006> ? dwo(00000000028376d8+8)
    Evaluate expression: 8868 = 00000000`000022a4