https://bugs.winehq.org/show_bug.cgi?id=49828
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Ever confirmed|0 |1 Status|UNCONFIRMED |NEW URL|https://cdn.discordapp.com/ |https://web.archive.org/web |attachments/653168829891084 |/20211230172933/https://cdn |298/754540922972274790/Dn_F |.discordapp.com/attachments |amiTracker_ASAN.exe |/653168829891084298/7545409 | |22972274790/Dn_FamiTracker_ | |ASAN.exe
--- Comment #2 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming. I assume you use LLVM MinGW to build Wine.
The address sanitizer init code hooks several API in TLS callback (before entry point) by trying different hooking techniques.
https://github.com/llvm/llvm-project/blob/e356027016c6365b3d8924f54c33e2c63d...
https://github.com/llvm/llvm-project/blob/e356027016c6365b3d8924f54c33e2c63d...
--- snip --- bool OverrideFunction( uptr old_func, uptr new_func, uptr *orig_old_func) { #if !SANITIZER_WINDOWS64 if (OverrideFunctionWithDetour(old_func, new_func, orig_old_func)) return true; #endif if (OverrideFunctionWithRedirectJump(old_func, new_func, orig_old_func)) return true; if (OverrideFunctionWithHotPatch(old_func, new_func, orig_old_func)) return true; if (OverrideFunctionWithTrampoline(old_func, new_func, orig_old_func)) return true; return false; } --- snip ---
ASAN hook via 'OverrideFunctionWithDetour' technique on Wine's 'kerne32.RaiseException':
--- snip --- ... 7B60CE89 | 90 | nop | 7B60CE8A | 90 | nop | 7B60CE8B | E9 F0D4FC84 | jmp <dn_famitracker_asan.___asan_wrap_RaiseExc... | <kernel32.RaiseException>: 7B60CE90 | EB F9 | jmp kernel32.7B60CE8B | 7B60CE92 | 55 | push ebp | 7B60CE93 | 8BEC | mov ebp,esp | 7B60CE95 | 5D | pop ebp | 7B60CE96 | FF25 DCA9637B | jmp dword ptr ds:[&_RaiseException@16] | 7B60CE9C | 90 | nop | 7B60CE9D | 90 | nop | 7B60CE9E | 90 | nop | 7B60CE9F | 90 | nop | ... --- snip ---
'OverrideFunctionWithDetour' expects a hotpatch prolog (0x8B,0xFF) and enough padding (5 x nop or 5 x int3) before. You can check the linked llvm source code for details.
kernel32 API which import from kernelbase get their hotpatch thunks automatically generated which allows the first hooking technique 'OverrideFunctionWithDetour' to succeed here.
https://source.winehq.org/git/wine.git/blob/58b1dc9f47310ba868cbcb3083de1b42...
Now to the problematic one(s) ...
ASAN can't hotpatch 'kernelbase.RaiseException' with any hooking technique.
(1) OverrideFunctionWithDetour
* no hotpatch entry * not enough preceding padding
(2) OverrideFunctionWithRedirectJump
* no relative jump at entry
(3) OverrideFunctionWithHotPatch
* first instruction needs to be at least two-byte opcode * not enough preceding padding
(4) OverrideFunctionWithTrampoline
* it can't decode the two-byte 0x89,0xe5 'mov ebp, esp' instruction that llvm/mingw emits
It only handles the 0x8B,0xec form:
--- snip --- case 0xEC8B: // 8B EC : mov ebp, esp --- snip ---
https://github.com/llvm/llvm-project/blob/e356027016c6365b3d8924f54c33e2c63d...
But even then it wouldn't be able to decode another one:
0x83,0xE4,0xFC 'and esp,FFFFFFFC'
Note, it requires 5 bytes to be copied into the trampoline because they get overwritten by the jump, hence 4 instructions need to be decoded (rounded up).
--- snip --- ... 7B0103BC | C2 0400 | ret 4 | 7B0103BF | 90 | nop | kernelbase._RaiseException@16: 7B0103C0 | 55 | push ebp | 7B0103C1 | 89E5 | mov ebp,esp | 7B0103C3 | 56 | push esi | 7B0103C4 | 83E4 FC | and esp,FFFFFFFC | 7B0103C7 | 83EC 50 | sub esp,50 | 7B0103CA | 8B45 10 | mov eax,dword ptr ss:[ebp+10] | 7B0103CD | 8B4D 0C | mov ecx,dword ptr ss:[ebp+C] | 7B0103D0 | 8B55 08 | mov edx,dword ptr ss:[ebp+8] | 7B0103D3 | 891424 | mov dword ptr ss:[esp],edx | 7B0103D6 | 83E1 01 | and ecx,1 | 7B0103D9 | 894C24 04 | mov dword ptr ss:[esp+4],ecx | 7B0103DD | C74424 08 00000000 | mov dword ptr ss:[esp+8],0 | ... --- snip ---
Apart from fixing instruction decoding issues, having LLVM MinGW implementing 'ms_hook_prologue' attribute would have helped here as well but it was rather short-lived:
https://github.com/llvm/llvm-project/issues/10584
You can test/work around by running the app with +relay which uses relay thunks that have hotpatch prolog:
https://source.winehq.org/git/wine.git/blob/58b1dc9f47310ba868cbcb3083de1b42...
====
@Roman (comment #1)
--- quote --- Maybe related: bug 50993. --- quote ---
Well, if you turn bug reports into meta-issues a la "make ASAN executables work", then of course they are related. But that's not really good practice.
Stable download link via Internet Archive:
https://web.archive.org/web/20211230172933/https://cdn.discordapp.com/attach...
$ sha1sum Dn_FamiTracker_ASAN.exe 3ab8880ae1d536363353e753dc97b1fee6b8cc41 Dn_FamiTracker_ASAN.exe
$ du -sh Dn_FamiTracker_ASAN.exe 5.6M Dn_FamiTracker_ASAN.exe
Regards