Skip to content

Commit

Permalink
Update 2501 post
Browse files Browse the repository at this point in the history
  • Loading branch information
Sonicadvance1 committed Jan 8, 2025
1 parent e18110a commit 6d25b41
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions _posts/2025-01-07-FEX-2501.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@ WINE may not integrate directly in to these builds yet. Check out our [wiki](htt
information about getting this hooked up.

## Partial support for inline self-modifying code and trap flag
As we work towards supporting more edge-case behaviour of anti-tamper and anti-debugger software. We have spent some time this month implementing support for inline self-modifying code and the trap flag.
In particular Denuvo uses inline self-modifying code which is relatively annoying to support, but we can use the fact that it tends to generate
invalid instructions to determine that a block of code is invalid early, thus letting it work. There's some more work towards making this more robust
but this gets a decent number of games running.
As we work towards supporting more edge-case behaviour of anti-tamper and anti-debugger software. We have spent some time this month implementing support for inline self-modifying code (SMC) and the trap flag, allowing for complete Denuvo support.

Inline self-modifying code is used by Denuvo in patterns like

<blockquote>
inc dword ptr [rip+6]
<br>
&lt;opcode for cpuid&gt; - 1
<br>
dec dword ptr [rip-2]
</blockquote>

to obfuscate checks. FEX's previous SMC handling operated purely at a block level using memory protection: an SMC write would invalidate all cached code in the touched page and then continue to the end of the current block, at which point any modified code would be regenerated. With inline SMC however this isn't enough, since guest instructions that map to the currently executing block of host code are being changed, the host code needs to be changed too, waiting until the end of the block isn't enough. This is now handled in FEX by detecting such cases, reconstructing the x86 context of the instruction performing the SMC (the inc in the above example), regenerating the host code at the x86 PC but limiting the length to the single modifying instruction and then jumping to that. At which point the same SMC will be detected again but since the block doesn't contain the guest instruction being modified it has been reduced back to the first case which is handled as described prior.

The trap flag on the other hand is interesting because this is an anti-debugger tactic that some badly behaving launchers use. This is because of how
debuggers treat the trap flag versus how it works when a debugger isn't running, this lets the application detect the debugger and throw an error.
FEX didn't quite handle this correctly which was causing these launchers to throw their hands up and stop running.
FEX didn't handle this at all prior which was causing these launchers to throw their hands up and stop running.

A note is that some of this work is only wired up on the WINE side rather than the FEX-Emu Linux emulation side, so mileage may vary!

Expand Down

0 comments on commit 6d25b41

Please sign in to comment.