An anticheat assumes some specific layout of KiUserExceptionDispatcher (in an 64 bit app). After checking two bytes (obviously instruction opcode) at (KiUserExceptionDispatcher + 1), it extracts memory address from this instruction and places its hook function address at that address, expecting that to be called on CPU exceptions (but not software raised exceptions).
I tried to make something out of it so supporting this mechanics is not completely artificial and fits into our implementation. I don't know if that hook has really something to do with wow64 in Windows implementation (while I guess that's possible), but it seems to me in our implementation doing it this way is a bit more straightforward. Specifically, it seems to me a bit easier to follow when a single function (KiUserExceptionDispatcher) doesn't mix different unwind models (while having the same runtime function info).
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/4290
When running wineserver under valgrind there is a bunch of uninitialised bytes warnings when sending the req_get_mapping_info reply.
This warning can easily be reproduced by running `valgrind wineserver -f` and then `winecfg`.
Tested using self compiled wine.
Reason is the `pe_image_info_t` struct having bitfields:
```
unsigned char contains_code : 1;
unsigned char wine_builtin : 1;
unsigned char wine_fakedll : 1;
```
The last 5 bits are never initialized. This MR fixes this by zeroing the entire struct before it is filled.
I hope "issues" like this are allowed to be fixed so valgrind has less false positives.
Valgrind message for reference:
```
==628662== 716 errors in context 3 of 3:
==628662== Syscall param writev(vector[1]) points to uninitialised byte(s)
==628662== at 0x49C3A87: writev (writev.c:26)
==628662== by 0x14C2F3: send_reply (request.c:268)
==628662== by 0x14C50F: call_req_handler (request.c:316)
==628662== by 0x14C5D2: read_request (request.c:339)
==628662== by 0x158F52: thread_poll_event (thread.c:388)
==628662== by 0x120FC9: fd_poll_event (fd.c:505)
==628662== by 0x1212A6: main_loop_epoll (fd.c:599)
==628662== by 0x121882: main_loop (fd.c:955)
==628662== by 0x12CBE0: main (main.c:238)
==628662== Address 0x53ec56e is 62 bytes inside a block of size 88 alloc'd
==628662== at 0x48416D4: malloc (vg_replace_malloc.c:431)
==628662== by 0x1348D0: mem_alloc (object.c:119)
==628662== by 0x14BEB9: set_reply_data_size (request.c:160)
==628662== by 0x1301C1: req_get_mapping_info (mapping.c:1291)
==628662== by 0x14C494: call_req_handler (request.c:305)
==628662== by 0x14C5D2: read_request (request.c:339)
==628662== by 0x158F52: thread_poll_event (thread.c:388)
==628662== by 0x120FC9: fd_poll_event (fd.c:505)
==628662== by 0x1212A6: main_loop_epoll (fd.c:599)
==628662== by 0x121882: main_loop (fd.c:955)
==628662== by 0x12CBE0: main (main.c:238)
==628662== Uninitialised value was created by a client request
==628662== at 0x134873: mark_block_uninitialized (object.c:110)
==628662== by 0x1348EA: mem_alloc (object.c:120)
==628662== by 0x134B87: alloc_object (object.c:199)
==628662== by 0x134F92: create_named_object (object.c:337)
==628662== by 0x12F12B: create_mapping (mapping.c:939)
==628662== by 0x12FFE9: req_create_mapping (mapping.c:1250)
==628662== by 0x14C494: call_req_handler (request.c:305)
==628662== by 0x14C5D2: read_request (request.c:339)
==628662== by 0x158F52: thread_poll_event (thread.c:388)
==628662== by 0x120FC9: fd_poll_event (fd.c:505)
==628662== by 0x1212A6: main_loop_epoll (fd.c:599)
==628662== by 0x121882: main_loop (fd.c:955)
```
--
v3: server: Fully initialize pe mapping struct to avoid uninitialized memory when sending req_get_mapping_info reply (valgrind)
https://gitlab.winehq.org/wine/wine/-/merge_requests/4414