Sometimes the assembly code looks almost wild (not like generated by your favourite compiler). For example (that also shows .NET runtime native unhandled exception processing):
0:000> kL 100
ChildEBP RetAddr
0014dbb4 77189254 ntdll!KiFastSystemCallRet
0014dbb8 75fec244 ntdll!ZwWaitForSingleObject+0xc
0014dc28 75fec1b2 kernel32!WaitForSingleObjectEx+0xbe
0014dc3c 72605389 kernel32!WaitForSingleObject+0x12
0014dc6c 726058e7 mscorwks!ClrWaitForSingleObject+0x24
0014e128 72608084 mscorwks!RunWatson+0x1df
0014e86c 7260874a mscorwks!DoFaultReportWorker+0xb59
0014e8a8 72657452 mscorwks!DoFaultReport+0xc3
0014e8cc 7265c0c7 mscorwks!WatsonLastChance+0x3f
0014e924 7265c173 mscorwks!CLRAddVectoredHandlers+0x209
0014e92c 7603f4be mscorwks!InternalUnhandledExceptionFilter+0x22
0014e9e8 771a85b7 kernel32!UnhandledExceptionFilter+0×127
0014e9f0 77139a14 ntdll!__RtlUserThreadStart+0×6f
0014ea04 771340f4 ntdll!_EH4_CallFilterFunc+0×12
0014ea2c 77189b99 ntdll!_except_handler4+0×8e
0014ea50 77189b6b ntdll!ExecuteHandler2+0×26
0014eb00 771899f7 ntdll!ExecuteHandler+0×24
0014eb00 03ca0141 ntdll!KiUserExceptionDispatcher+0xf
WARNING: Frame IP not in any known module. Following frames may be wrong.
0014ee28 634c2f42 0×3ca0141
0014ee34 67715e44 System_ni+0×132f42
0014ee70 72431b4c System_ServiceProcess_ni+0×25e44
0014ee80 724421f9 mscorwks!CallDescrWorker+0×33
0014ef00 72456571 mscorwks!CallDescrWorkerWithHandler+0xa3
0014f03c 724565a4 mscorwks!MethodDesc::CallDescr+0×19c
0014f058 724565c2 mscorwks!MethodDesc::CallTargetWorker+0×1f
0014f070 724afac5 mscorwks!MethodDescCallSite::CallWithValueTypes+0×1a
0014f1d4 724af9e5 mscorwks!ClassLoader::RunMain+0×223
0014f43c 724aff35 mscorwks!Assembly::ExecuteMainMethod+0xa6
0014f90c 724b011f mscorwks!SystemDomain::ExecuteMainMethod+0×456
0014f95c 724b004f mscorwks!ExecuteEXE+0×59
0014f9a4 72f57c24 mscorwks!_CorExeMain+0×15c
0014f9b4 75fe4911 mscoree!_CorExeMain+0×2c
0014f9c0 7716e4b6 kernel32!BaseThreadInitThunk+0xe
0014fa00 7716e489 ntdll!__RtlUserThreadStart+0×23
0014fa18 00000000 ntdll!_RtlUserThreadStart+0×1b
We set exception context:
0:000> kv 100
ChildEBP RetAddr Args to Child
[...]
0014e9e8 771a85b7 0014ea18 77139a14 00000000 kernel32!UnhandledExceptionFilter+0×127 (FPO: [SEH])
[…]
0:000> .exptr 0014ea18
----- Exception record at 0014eb18:
ExceptionAddress: 03ca0141
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000000
Attempt to read from address 00000000
----- Context record at 0014eb34:
eax=00000001 ebx=08394ff8 ecx=00000000 edx=00000001 esi=056a2a94 edi=00000000
eip=03ca0141 esp=0014ee00 ebp=0014ee28 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
03ca0141 3909 cmp dword ptr [ecx],ecx ds:0023:00000000=????????
Then we disassemble the code at crash point and it looks strange including calls through DS data segment:
0:000> .asm no_code_bytes
Assembly options: no_code_bytes
0:000> u 03ca0141
03ca0141 cmp dword ptr [ecx],ecx
03ca0143 call dword ptr ds:[36067C0h]
03ca0149 mov ecx,dword ptr [esi+5Ch]
03ca014c cmp dword ptr [ecx],ecx
03ca014e call dword ptr ds:[3606D10h]
03ca0154 mov dword ptr [ebp-1Ch],0
03ca015b mov dword ptr [ebp-18h],0FCh
03ca0162 push 3CA0180h
However further disassembly finally reaches RET instruction:
0:000> u
03ca0167 jmp 03ca0169
03ca0169 movzx edx,byte ptr [ebp-24h]
03ca016d mov ecx,dword ptr [ebp-28h]
03ca0170 call System_ServiceProcess_ni+0x25140 (67715140)
03ca0175 pop eax
03ca0176 jmp eax
03ca0178 lea esp,[ebp-0Ch]
03ca017b pop ebx
0:000> u
03ca017c pop esi
03ca017d pop edi
03ca017e pop ebp
03ca017f ret
03ca0180 mov dword ptr [ebp-18h],0
03ca0187 jmp 03ca0178
03ca0189 add byte ptr [eax],al
03ca018b add byte ptr [eax],al
and backward disassembling shows the matching function prolog code:
0:000> ub 03ca0141
03ca0127 movzx eax,byte ptr [ebp-24h]
03ca012b test eax,eax
03ca012d je 03ca0154
03ca012f cmp dword ptr [esi+60h],0
03ca0133 je 03ca013e
03ca0135 mov ecx,dword ptr [esi+60h]
03ca0138 call dword ptr ds:[3C20010h]
03ca013e mov ecx,dword ptr [esi+58h]
0:000> ub 03ca0127
03ca0114 push esi
03ca0115 push ebx
03ca0116 sub esp,1Ch
03ca0119 xor eax,eax
03ca011b mov dword ptr [ebp-18h],eax
03ca011e mov dword ptr [ebp-28h],ecx
03ca0121 mov dword ptr [ebp-24h],edx
03ca0124 mov esi,dword ptr [ebp-28h]
0:000> ub 03ca0114
03ca0102 retf
03ca0103 add eax,dword ptr [eax+36h]
03ca0106 retf
03ca0107 add ebx,dword ptr [esi+esi-35h]
03ca010b add esi,esp
03ca010d cmp eax,8B550360h
03ca0112 in al,dx
03ca0113 push edi
From stack trace I suspected this code as JIT-compiled .NET code of the the main assemebly method. And indeed I found the similar call signatures like mine
03ca0141 cmp dword ptr [ecx],ecx
03ca0143 call dword ptr ds:[36067C0h]
in the following MSDN article:
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
Hence the name of this pattern: JIT Code.
- Dmitry Vostokov @ DumpAnalysis.org -