Archive for April, 2020

Crash Dump Analysis Patterns (Part 265)

Thursday, April 30th, 2020

In addition to generic Invalid Pointer pattern that maps to visible pointer dereference in C and C++ code, plain NULL Code Pointers and NULL Data Pointers that are visible Small Values, and Wild Pointers showing ASCII or Regular Data (such as UNICODE fragments), we have implicit dereference (from C++ source code perspective) crash dump analysis patterns that we call Invalid Pointer (Objects). When seeing them in a high-level debugger (could be just an exception during debugging) developers are confused since they do not see the usual pointer dereference:

struct Resource
{
    void DoSomething()
    {
        ++m_usageCounter;
    }
    std::size_t m_usageCounter{};
}; 

However, the function call was ordinary (not virtual, otherwise we would have NULL Code Pointer), and the object address to access its members was passed via RCX register, but the memory of the object was invalid, hence we have an exception inside the method call when trying to access object members:

0:000> .ecxr
*** WARNING: Unable to verify checksum for InvalidPointerObject.exe
rax=0000022c837e0000 rbx=0000022c83905ca0 rcx=0000022c837e0000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000022c83907540
rip=00007ff6d65630ba rsp=00000098812ffc18 rbp=0000000000000000
r8=00000098812ffbe8 r9=0000000000000000 r10=0000000000000000
r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
InvalidPointerObject!Resource::DoSomething+0xa:
00007ff6`d65630ba 488b00 mov rax,qword ptr [rax] ds:0000022c`837e0000=????????????????

0:000> !address @rax

Usage:
Base Address: 0000022c`837e0000
End Address: 0000022c`837e1000
Region Size: 00000000`00001000 ( 4.000 kB)
State: 00002000 MEM_RESERVE
Protect:
Type: 00020000 MEM_PRIVATE
Allocation Base: 0000022c`837e0000
Allocation Protect: 00000004 PAGE_READWRITE

0:000> kL
# Child-SP RetAddr Call Site
00 00000098`812fe748 00007ffd`62278027 ntdll!NtWaitForMultipleObjects+0×14
01 00000098`812fe750 00007ffd`62277f0e KERNELBASE!WaitForMultipleObjectsEx+0×107
02 00000098`812fea50 00007ffd`63d871fb KERNELBASE!WaitForMultipleObjects+0xe
03 00000098`812fea90 00007ffd`63d86ca8 kernel32!WerpReportFaultInternal+0×51b
04 00000098`812febb0 00007ffd`6231f868 kernel32!WerpReportFault+0xac
05 00000098`812febf0 00007ffd`64ee4b32 KERNELBASE!UnhandledExceptionFilter+0×3b8
06 00000098`812fed10 00007ffd`64ecc6d6 ntdll!RtlUserThreadStart$filt$0+0xa2
07 00000098`812fed50 00007ffd`64ee121f ntdll!_C_specific_handler+0×96
08 00000098`812fedc0 00007ffd`64eaa289 ntdll!RtlpExecuteHandlerForException+0xf
09 00000098`812fedf0 00007ffd`64edfe8e ntdll!RtlDispatchException+0×219
0a 00000098`812ff500 00007ff6`d65630ba ntdll!KiUserExceptionDispatch+0×2e
0b 00000098`812ffc18 00007ff6`d656313c InvalidPointerObject!Resource::DoSomething+0xa
0c 00000098`812ffc20 00007ff6`d6568454 InvalidPointerObject!wmain+0×6c
0d (Inline Function) ——–`——– InvalidPointerObject!invoke_main+0×22
0e 00000098`812ffc70 00007ffd`63d37bd4 InvalidPointerObject!__scrt_common_main_seh+0×10c
0f 00000098`812ffcb0 00007ffd`64eaced1 kernel32!BaseThreadInitThunk+0×14
10 00000098`812ffce0 00000000`00000000 ntdll!RtlUserThreadStart+0×21

0:000> ub 00007ff6`d656313c
InvalidPointerObject!wmain+0×45:
00007ff6`d6563115 488b4c2428 mov rcx,qword ptr [rsp+28h]
00007ff6`d656311a e891ffffff call InvalidPointerObject!Resource::DoSomething (00007ff6`d65630b0)
00007ff6`d656311f 41b800400000 mov r8d,4000h
00007ff6`d6563125 33d2 xor edx,edx
00007ff6`d6563127 488b4c2420 mov rcx,qword ptr [rsp+20h]
00007ff6`d656312c ff15ce0e0200 call qword ptr [InvalidPointerObject!_imp_VirtualFree (00007ff6`d6584000)]
00007ff6`d6563132 488b4c2428 mov rcx,qword ptr [rsp+28h]
00007ff6`d6563137 e874ffffff call InvalidPointerObject!Resource::DoSomething (00007ff6`d65630b0)

0:000> u InvalidPointerObject!Resource::DoSomething
InvalidPointerObject!Resource::DoSomething:
00007ff6`d65630b0 48894c2408 mov qword ptr [rsp+8],rcx
00007ff6`d65630b5 488b442408 mov rax,qword ptr [rsp+8]
00007ff6`d65630ba 488b00 mov rax,qword ptr [rax]
00007ff6`d65630bd 48ffc0 inc rax
00007ff6`d65630c0 488b4c2408 mov rcx,qword ptr [rsp+8]
00007ff6`d65630c5 488901 mov qword ptr [rcx],rax
00007ff6`d65630c8 c3 ret
00007ff6`d65630c9 cc int 3

The example memory dump, the application PDB file, and source code can be downloaded from here.

- Dmitry Vostokov @ DumpAnalysis.org + TraceAnalysis.org -

Trace Analysis Patterns (Part 182)

Tuesday, April 14th, 2020

Source code can be considered as a type of a general trace from a corresponding generative narrative plane. We call it Generative Trace since it can generate different traces of execution. If such a trace contains logging code statements, then they form Declarative Trace as a subset of messages. Generative Trace also overlaps with the corresponding Moduli Trace. We can apply many trace and log analysis patterns and even consider line number axis as pseudo-time. The following diagram illustrates Linked Messages analysis pattern in the context of Generative Trace and generated traces:

- Dmitry Vostokov @ DumpAnalysis.org + TraceAnalysis.org -