DynamoRIO/dynamorio

Add Win10 1809 support: 32-bit hits ASSERT and CRASH on APC handling

derekbruening opened this issue · 0 comments

This issue covers adding Win10 1809 support in general.
Xref #3206.

The main thing to fix is a CRASH and ASSERT handling APC's on 32-bit:

$ DrMemory-Windows-1.11.17835-1/dynamorio/bin32/drrun -debug -- notepad
<WARNING: Running on unsupported Windows 10+ version>
<Starting application C:\WINDOWS\system32\notepad.exe (5540)>
<Application C:\WINDOWS\system32\notepad.exe (5540).  Internal Error: DynamoRIO debug check failure: ..\..\dynamorio\core\win32\callback.c:3780 instr_get_opcode(&instr) == OP_lea && (opnd_get_disp(instr_get_src(&instr, 0)) == 0x10 || opnd_get_disp(instr_get_src(&instr, 0)) == 0x2dc)

Just disabling the assert shows there's a more serious issue:

% dynamorio/bin32/drrun -- d:/derek/dr/git/build_x86_dbg_tests/suite/tests/bin/win32.winapc.exe
<WARNING: Running on unsupported Windows 10+ version>
<Starting application d:\derek\dr\git\build_x86_dbg_tests\suite\tests\bin\win32.winapc.exe (10904)>
<Initial options = -no_dynamic_options -code_api -probe_api -stack_size 56K -max_elide_jmp 0 -max_elide_call 0 -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct -no_aslr_dr -pad_jmps_mark_no_trace >
Before _beginthreadex
QueueUserAPC returned 1
<ERROR: intercept_nt_continue: xip=0x1aa624b9 not an app pc!>
<Application d:\derek\dr\git\build_x86_dbg_tests\suite\tests\bin\win32.winapc.exe (10904).  Internal Error: DynamoRIO debug check failure: D:\derek\drmemory\git\src\dynamorio\core\win32\callback.c:3980 false

Looking more closely at the assert:

0:000> U @@(apc_entry)
ntdll!KiUserApcDispatcher:
77d627b0 833dfc17e17700  cmp     dword ptr [ntdll!LdrDelegatedKiUserApcDispatcher (77e117fc)],0
77d627b7 740e            je      ntdll!KiUserApcDispatcher+0x17 (77d627c7)
77d627b9 8b0dfc17e177    mov     ecx,dword ptr [ntdll!LdrDelegatedKiUserApcDispatcher (77e117fc)]
77d627bf ff15e041e177    call    dword ptr [ntdll!__guard_check_icall_fptr (77e141e0)]
77d627c5 ffe1            jmp     ecx
77d627c7 8d8424e0020000  lea     eax,[esp+2E0h]
77d627ce 648b0d00000000  mov     ecx,dword ptr fs:[0]
77d627d5 ba9027d677      mov     edx,offset ntdll!KiUserApcExceptionHandler (77d62790)
77d627da 8908            mov     dword ptr [eax],ecx
77d627dc 895004          mov     dword ptr [eax+4],edx
77d627df 64a300000000    mov     dword ptr fs:[00000000h],eax
77d627e5 8d7c2414        lea     edi,[esp+14h]
77d627e9 8b742410        mov     esi,dword ptr [esp+10h]
77d627ed 83e601          and     esi,1
77d627f0 58              pop     eax
77d627f1 8bc8            mov     ecx,eax
77d627f3 ff15e041e177    call    dword ptr [ntdll!__guard_check_icall_fptr (77e141e0)]
77d627f9 ffd1            call    ecx
77d627fb 8b8fcc020000    mov     ecx,dword ptr [edi+2CCh]
77d62801 64890d00000000  mov     dword ptr fs:[0],ecx
77d62808 56              push    esi
77d62809 57              push    edi
77d6280a e8c1e0ffff      call    ntdll!NtContinue (77d608d0)
77d6280f 8bf0            mov     esi,eax
77d62811 56              push    esi
77d62812 e8f9290100      call    ntdll!RtlRaiseStatus (77d75210)
77d62817 ebf8            jmp     ntdll!KiUserApcDispatcher+0x61 (77d62811)
77d62819 c21000          ret     10h
77d6281c 8d642400        lea     esp,[esp]

That first lea offset is 0x2e0 instead of the expected 0x2dc.
It doesn't matter much though: what we care about is the CONTEXT offset
which is the 2nd lea which seems to have changed? It's 0x14 instead of
0x0c? Except it's now before the pop, so we'd expect 0x10. So is esp
shifted, explaining the 0x2dc+4 too?

0:000> g
Breakpoint 0 hit
eax=008912ce ebx=0156fcc8 ecx=0125e630 edx=00000000 esi=00000001 edi=0156fcc8
eip=77d627b0 esp=0156f9a0 ebp=0156fcec iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
ntdll!KiUserApcDispatcher:
77d627b0 833dfc17e17700  cmp     dword ptr [ntdll!LdrDelegatedKiUserApcDispatcher (77e117fc)],0 ds:002b:77e117fc=00000000
0:001> dds esp
0156f9a0  77d1bb20 ntdll!RtlDispatchAPC
0156f9a4  00891090 win32_winapc!apc_func [d:\derek\dr\git\src\suite\tests\win32\winapc.c @ 68]
0156f9a8  00000025
0156f9ac  00000000
0156f9b0  00000001
0156f9b4  00010003
0156f9b8  77ddc4b7 ntdll!RtlpValidateHeap+0x21
0156f9bc  502c016b
0156f9c0  0156f9e0
0:001> dt CONTEXT esp+14
win32_winapc!CONTEXT
   +0x000 ContextFlags     : 0x10003
   +0x004 Dr0              : 0x77ddc4b7
   +0x008 Dr1              : 0x502c016b
   +0x00c Dr2              : 0x156f9e0
   +0x010 Dr3              : 0x77d31f3e
   +0x014 Dr6              : 0
   +0x018 Dr7              : 0x77d31f3e
   +0x01c FloatSave        : _FLOATING_SAVE_AREA
   +0x08c SegGs            : 0x156fc0c
   +0x090 SegFs            : 0x77d686d0
   +0x094 SegEs            : 0xd1d1116b
   +0x098 SegDs            : 0xfffffffe
   +0x09c Edi              : 0x156fcc8
   +0x0a0 Esi              : 1
   +0x0a4 Ebx              : 0x156fcc8
   +0x0a8 Edx              : 0
   +0x0ac Ecx              : 0
   +0x0b0 Eax              : 0x8912ce
   +0x0b4 Ebp              : 0x156fcec
   +0x0b8 Eip              : 0x77d607ec
   +0x0bc SegCs            : 0x23
   +0x0c0 EFlags           : 0x206
   +0x0c4 Esp              : 0x156fc88
   +0x0c8 SegSs            : 0x2b
   +0x0cc ExtendedRegisters : [512]  "< ???"
0:001> U 77d607ec L2
ntdll!NtDelayExecution+0xc:
77d607ec c20800          ret     8

Indeed it's at esp+0x14.
To solve, and future-proof: scan stack looking for SegCs==0x23 or sthg?