반응형
Crash Dump Analysis Patterns (Part 5b)


This is a follow up to Optimized Code patternwritten previously. Now I discuss the following feature that often bewilders beginners. It is called OMAP code optimization. It is used to make code that needs to be present in memory smaller. So instead of flat address space for compiled function you have pieces of it scattered here and there.This leads to an ambiguity when you try to disassembleOMAP code atits address because WinDbg doesn’t knowwhether it shouldtreat addressrange as a function offset (starting from the beginning ofthe function source code) or just a memory layout offset (starting from the address of that function). Let me illustrate this on IoCreateDevice function code.

Lets first evaluate a random address starting from the first address of the function (memory layoutoffset):

kd> ? nt!IoCreateDevice
Evaluate expression: -8796073668256 = fffff800`01275160
kd> ? nt!IoCreateDevice+0×144
Evaluate expression: -8796073667932 = fffff800`012752a4
kd> ? fffff800`012752a4-fffff800`01275160
Evaluate expression: 324 = 00000000`00000144

Ifwe try todisassemblecodeat the same addressthe expression will also be evaluated asthe memory layoutoffset:

kd> u nt!IoCreateDevice+0×144
nt!IoCreateDevice+0×1a3:
fffff800`012752a4 83c810 or eax,10h
fffff800`012752a7 898424b0000000 mov dword ptr [rsp+0B0h],eax
fffff800`012752ae 85ed test ebp,ebp
fffff800`012752b0 8bdd mov ebx,ebp
fffff800`012752b2 0f858123feff jne nt!IoCreateDevice+0×1b3
fffff800`012752b8 035c2454 add ebx,dword ptr [rsp+54h]
fffff800`012752bc 488b1585dcf2ff mov rdx,qword ptr [nt!IoDeviceObjectType]
fffff800`012752c3 488d8c2488000000 lea rcx,[rsp+88h]

You see the difference: we give +0×144 offset but the code is shown from +0×1a3! This is because OMAP optimization moved the code fromthe function offset +0×1a3 tomemory locations starting from +0×144. The following picture illustrates this:

If you see this when disassembling a function name+offset address from a thread stack trace you can useraw address instead:

kd> k
Child-SP RetAddr Call Site
fffffadf`e3a18d30 fffff800`012b331e component!function+0×72
fffffadf`e3a18d70 fffff800`01044196 nt!PspSystemThreadStartup+0×3e
fffffadf`e3a18dd0 00000000`00000000 nt!KxStartSystemThread+0×16
kd> u fffff800`012b331e
nt!PspSystemThreadStartup+0×3e:
fffff800`012b331e 90 nop
fffff800`012b331f f683fc03000040 test byte ptr [rbx+3FCh],40h
fffff800`012b3326 0f8515d30600 jne nt!PspSystemThreadStartup+0×4c
fffff800`012b332c 65488b042588010000 mov rax,qword ptr gs:[188h]
fffff800`012b3335 483bd8 cmp rbx,rax
fffff800`012b3338 0f85a6d30600 jne nt!PspSystemThreadStartup+0×10c
fffff800`012b333e 838bfc03000001 or dword ptr [rbx+3FCh],1
fffff800`012b3345 33c9 xor ecx,ecx

Youalso see OMAP in action also when you try to disassemblethe function body using uf command:

kd> uf nt!IoCreateDevice
nt!IoCreateDevice+0×34d:
fffff800`0123907d 834f3008 or dword ptr [rdi+30h],8
fffff800`01239081 e955c30300 jmp nt!IoCreateDevice+0×351



nt!IoCreateDevice+0×14c:
fffff800`0126f320 6641be0002 mov r14w,200h
fffff800`0126f325 e92f5f0000 jmp nt!IoCreateDevice+0×158
nt!IoCreateDevice+0×3cc:
fffff800`01270bd0 488d4750 lea rax,[rdi+50h]
fffff800`01270bd4 48894008 mov qword ptr [rax+8],rax
fffff800`01270bd8 488900 mov qword ptr [rax],rax
fffff800`01270bdb e95b480000 jmp nt!IoCreateDevice+0×3d7
nt!IoCreateDevice+0xa4:
fffff800`01273eb9 41b801000000 mov r8d,1
fffff800`01273ebf 488d154a010700 lea rdx,[nt!`string’]
fffff800`01273ec6 488d8c24d8000000 lea rcx,[rsp+0D8h]
fffff800`01273ece 440fc10522f0f2ff xadd dword ptr [nt!IopUniqueDeviceObjectNumber],r8d
fffff800`01273ed6 41ffc0 inc r8d
fffff800`01273ed9 e8d236deff call nt!swprintf
fffff800`01273ede 4584ed test r13b,r13b
fffff800`01273ee1 0f85c1a70800 jne nt!IoCreateDevice+0xce


- Dmitry Vostokov -

반응형