DynamoRIO / dynamorio

Dynamic Instrumentation Tool Platform
Other
2.67k stars 561 forks source link

support /clr:safe images #1224

Open derekbruening opened 9 years ago

derekbruening commented 9 years ago

From bruen...@google.com on July 22, 2013 16:31:34

/clr:safe images use a 32-bit PE that is modified when loaded on 64-bit kernel to be a 64-bit PE. Our injection bitwidth check gets this wrong, of course.

Furthermore, after disabling the check, bin64/drrun successfully injects but then the image entry point is not properly tweaked by mscoree, or something -- I haven't diagnosed fully. The symptoms are an app crash right up front.

This issue covers both detecting in the front-end launchers and running properly once injected.

My test app here is PCMark7Cmd.exe.

Need an elevated shell, else: ERROR: Failed to create process for "c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe": The requested operation requires elevation.

% bin32/drrun -v -- c:/Program\ Files/Futuremark/PCMark\ 7/bin/PCMark7Cmd.exe INFO: targeting application: "c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe" INFO: app cmdline: "c:/Program Files/Futuremark/PCMark 7/bin/PCMark7Cmd.exe" INFO: created child with pid 4204 for c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe ERROR: unable to inject: did you forget to run drconfig first?

10:41 AM ~/DynamoRIO-Windows-4.1.0-4 % bin64/drrun -v -- c:/Program\ Files/Futuremark/PCMark\ 7/bin/PCMark7Cmd.exe INFO: targeting application: "c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe" INFO: app cmdline: "c:/Program Files/Futuremark/PCMark 7/bin/PCMark7Cmd.exe" INFO: created child with pid 0 for c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe ERROR: Target process c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe is for the wrong architecture

Custom build w/o the arch check: % bin64/drrun -debug -v -msgbox_mask 15 -stderr_mask 15 -- c:/Program\ Files/Futuremark/PCMark\ 7/bin/PCMark7Cmd.exe INFO: targeting application: "c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe" INFO: app cmdline: "c:/Program Files/Futuremark/PCMark 7/bin/PCMark7Cmd.exe" INFO: created child with pid 788 for c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe INFO: waiting forever for app to exit... <Starting application c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe (788)> <Initial options = -code_api -probe_api -msgbox_mask 15 -stderr_mask 15 -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 -pad_jmps_mark_no_trace > <Stopping application c:\Program Files\Futuremark\PCMark 7\bin\PCMark7Cmd.exe (788)> Segmentation fault

ASYNCH intercepted exception in thread 2092 at pc 0x00000000206f10c1 exception code = 0x00000000c0000005, ExceptionFlags=0x0000000000000000 record=0x0000000000000000, params=2 PC 0x00000000206f10c1 tried to read address 0x00000000010021f4

Exception is in this fragment: Fragment 5, tag 0x0000000000c001ee, flags 0x1000030, shared, size 21: [PCMark7Cmd.exe] 0x00000000206f10b8 65 48 89 0c 25 30 16 mov %rcx -> %gs:0x00001630 00 00 0x00000000206f10c1 48 8b 0d 2c 11 91 e0 mov 0x00000000010021f4 -> %rcx 0x00000000206f10c8 e9 b3 2a ff ff jmp $0x00000000206e3b80 -------- exit stub 0: -------- <target: 0x00000000206e3b80> type: indjmp

interp: start_pc = 0x0000000000c001ee 0x0000000000c001ee ff 25 00 20 40 00 jmp 0x00000000010021f4 end_pc = 0x0000000000c001f4 0x0000000000bc0000-0x0000000000c4dfff PCMark7Cmd.exe entry=0x0000000000000000 count=-1 That's the executable entry point, which should have been modified to point at mscoree!_CorExeMain, or at least that's how stuff worked years ago. Needs further investigation. More info on the PE header: it's a PE32 header, modified by the kernel if mapped as an image (even w/ just DRload) to be a PE32+ header and placed in a non-WOW64 (i.e., native 64-bit) process if used in CreateProcess, but of course not modified if mapped as a non-image. _Original issue: http://code.google.com/p/dynamorio/issues/detail?id=1224_
derekbruening commented 9 years ago

From bruen...@google.com on July 23, 2013 09:42:47

I'm having -nocheck also disable the arch mismatch being a fatal error, so: % bin64/drrun -nocheck -debug -- c:/derek/dr/test/hello.exe WARNING: Target process c:\derek\dr\test\hello.exe appears to be for the wrong architecture. WARNING: Attempting to run anyway, but it may run natively if injection fails. Hello world!

derekbruening commented 9 years ago

From bruen...@google.com on July 23, 2013 11:10:53

\ DONE create small reproducer CLOSED: [2013-07-23 Tue 14:10]

int main() { return 0; } % cl /Zi /clr:safe clrsafe.cpp

=> the crash reproduces, and runs fine natively: % bin64/drrun -debug -nocheck -v -stderr_mask 15 -- c:/derek/dr/test/clrsafe.exe INFO: targeting application: "c:\derek\dr\test\clrsafe.exe" INFO: app cmdline: "c:/derek/dr/test/clrsafe.exe" INFO: created child with pid 3228 for c:\derek\dr\test\clrsafe.exe WARNING: Target process c:\derek\dr\test\clrsafe.exe appears to be for the wrong architecture. WARNING: Attempting to run anyway, but it may run natively if injection fails. INFO: waiting forever for app to exit... <Starting application c:\derek\dr\test\clrsafe.exe (3228)> <Initial options = -code_api -probe_api -stderr_mask 15 -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 -pad_jmps_mark_no_trace > <Stopping application c:\derek\dr\test\clrsafe.exe (3228)> Segmentation fault

\ TODO distinguish /clr:safe from other clr for front-end

\ TODO fix the crash

byron-hawkins commented 9 years ago

Note that there is no crash running PCMark8 on a 32-bit Windows 7 install. Everything works fine there.