Crash Dump Analysis Patterns (Part 6a)

This is a specialization of Invalid Pointer pattern called NULL Pointer and it is the most easily recognized pattern with a straightforward fix most of the time according to my experience. Checking the pointer value to be non-NULL might not work if the pointer value is random (Wild Pointer pattern) but at least it eliminates this class of problems. NULL pointers can be NULL data pointers or NULL code pointers. The latter happens when we have a pointer to some function and we try to call it. Consider this example:

0:002> r
eax=00000000 ebx=00000000 ecx=93630000 edx=00000000 esi=00000000 edi=00000000
eip=00000000 esp=0222ffbc ebp=0222ffec iopl=0  nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
00000000 ??              ???

0:002> kv
ChildEBP RetAddr  Args to Child             
WARNING: Frame IP not in any known module. Following frames may be wrong.
0222ffb8 7d4dfe21 00000000 00000000 00000000 0×0
0222ffec 00000000 00000000 00000000 00000000 kernel32!BaseThreadStart+0×34

Clearly we have a NULL code pointer here and if we disassemble backwards the return address 7d4dfe21 or BaseThreadStart+0×34 we would suspect that BaseThreadStart function tried to call a thread start procedure:

0:002> ub 7d4dfe21
kernel32!BaseThreadStart+0x10:
7d4dfdfd mov     eax,dword ptr fs:[00000018h]
7d4dfe03 cmp     dword ptr [eax+10h],1E00h
7d4dfe0a jne     kernel32!BaseThreadStart+0x2e (7d4dfe1b)
7d4dfe0c cmp     byte ptr [kernel32!BaseRunningInServerProcess (7d560008)],0
7d4dfe13 jne     kernel32!BaseThreadStart+0x2e (7d4dfe1b)
7d4dfe15 call    dword ptr [kernel32!_imp__CsrNewThread (7d4d0310)]
7d4dfe1b push    dword ptr [ebp+0Ch]
7d4dfe1e call    dword ptr [ebp+8]

0:002> dp ebp+8 l1
0222fff4  00000000

To confirm this suspicion we can write a code that calls CreateThread function similar to this one:

typedef DWORD (WINAPI *THREADPROC)(PVOID);

DWORD WINAPI ThreadProc(PVOID pvParam)
{
  // Does some work
  return 0;
}

void foo()
{
  //..
  THREADPROC thProc = ThreadProc;
  //..
  // thProc becomes NULL because of a bug
  //..
  HANDLE Thread = CreateThread(NULL, 0, thProc, 0, 0, NULL);
  CloseHandle(hThread);
}

- Dmitry Vostokov @ DumpAnalysis.org -

6 Responses to “Crash Dump Analysis Patterns (Part 6a)”

  1. Crash Dump Analysis » Blog Archive » NULL code pointer, changed environment and hooked functions: pattern cooperation Says:

    […] 2009 (0×7D9) - The Year of Debugging 2010 (0×7DA) - The Year of Dump Analysis It was reported that after an upgrade to the new version of a productivity software package one unrelated GUI application started to crash frequently. One crash dump was collected and the following stack trace pointed to a NULL code pointer: […]

  2. Crash Dump Analysis » Blog Archive » Crash Dump Analysis Patterns (Part 6b) Says:

    […] Analysis NULL Data Pointer is a special version of the more general Invalid Pointer pattern like NULL Code Pointer. The effective address is below 0xFFFF and it is usually a register with 0 value and the small […]

  3. Crash Dump Analysis » Blog Archive » Stack trace, invalid code pointer and hooked functions: pattern cooperation Says:

    […] looking at a stack trace of one crashed process we noticed an invalid code pointer. It is not a NULL code pointer but has the same stack trace […]

  4. Crash Dump Analysis » Blog Archive » Hunting for a Driver Says:

    […] resulted effective address is a NULL code pointer (EAX=3, major code and ESI is […]

  5. Crash Dump Analysis » Blog Archive » Icons for Memory Dump Analysis Patterns (Part 9) Says:

    […] Today we introduce an icon for NULL Pointer (code) pattern: […]

  6. Dmitry Vostokov Says:

    Some runtime implementations replace NULL code pointers with some default functions which provide additional diagnostics, for example, in the case of C++ pure virtual call:

    0:008> kc
    #
    00 ucrtbase!abort
    01 VCRUNTIME140!_purecall
    WARNING: Stack unwind information not available. Following frames may be wrong.
    02 ClientTelemetry!Microsoft::Applications::Telemetry::LogManager::checkup
    03 ClientTelemetry!Microsoft::Applications::Telemetry::EventProperty::type_name
    04 ClientTelemetry!Microsoft::Applications::Telemetry::EventProperty::type_name
    05 ClientTelemetry!Microsoft::Applications::Telemetry::EventProperty::type_name
    06 ClientTelemetry!Microsoft::Applications::Telemetry::EventProperty::type_name
    07 wininet!InternetIndicateStatus
    08 wininet!CFsm::RunWorkItem
    09 wininet!CSocket::ReceiveCompletion
    0a wininet!CWxSocket::IoCompletionCallback
    0b KERNELBASE!BasepTpIoCallback
    0c ntdll!TppIopExecuteCallback
    0d ntdll!TppWorkerThread
    0e kernel32!BaseThreadInitThunk
    0f ntdll!__RtlUserThreadStart
    10 ntdll!_RtlUserThreadStart

Leave a Reply