https://bugs.winehq.org/show_bug.cgi?id=48291
Brendan Shanks bshanks@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |bshanks@codeweavers.com
--- Comment #52 from Brendan Shanks bshanks@codeweavers.com --- I've been working on supporting Red Dead Redemption 2, and now have a hack-y solution to handle its syscallls using seccomp.
RDR2 and the Rockstar Launcher use direct syscalls (with Windows syscall numbers) for some isolated uses. The launcher calls NtCreateFile/NtWriteFile. RDR2 calls NtQueryInformationProcess/NtQuerySystemInformation/NtGetContextThread for anti-debug checks, and sometimes NtCreateFile/NtReadFile/NtClose. Major/minor/build numbers are pulled from the PEB and used to branch to code that sets the right number and does the syscall.
I started out by trapping the specific syscall numbers in BPF, and then having the SIGSYS handler decide whether to execute the native syscall or have Wine handle it. This did work for the anti-debug calls, but had numerous problems:
- The arguments of some calls make it obvious whether they're meant for Linux or Windows, like R10/ProcessHandle of NtQueryInformationProcess often being -1. Most calls (like the file I/O calls) are not that easy.
- Once enabled, seccomp applies to the current thread, any threads that thread creates, and any child processes it spawns. Of course those spawned processes will not have a SIGSYS handler defined, and terminate when they execute a trapped syscall. I'm not sure how common it is for Wine to spawn non-Wine processes (I do remember seeing a recent patch that spawned 'ping'), but it's still not a great thing to break. I even had this problem with Wine itself, server_init_process() calls setsockopt(/NtQuerySystemInformation) and was crashing. My workaround was to call install_bpf() at the top of __wine_process_init().
- Windows system call numbers changing based on the version are problematic with every approach, but especially when they're hardcoded in the BPF program (can't be changed after it's enabled).
What I'm using now is to have BPF filter on the instruction pointer, since the game and launcher both load at 0x14000000. It's working well in this case, but clearly a hack.
My latest WIP branch is at https://github.com/mrpippy/wine/tree/rdr2-2 for anyone curious. There's a patch there (and I'll attach here) which adds symbols for Wine's syscall numbers, I think it could belong in the winebuild-Fake_Dlls staging patchset.