Add Win10 1809 support: 32-bit hits ASSERT and CRASH on APC handling
This issue covers adding Win10 1809 support in general. Xref https://github.com/DynamoRIO/dynamorio/pull/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?