Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jit emuhacks detected by games (Metal Gear Solid: Peace Walker demo) #3365

Open
unknownbrackets opened this issue Aug 24, 2013 · 5 comments
Open

Comments

@unknownbrackets
Copy link
Collaborator

The jit, to detect when the game modifies its code, writes "emuhack" instructions over the original MIPS instructions. This way, if it's changed from an emuhack, we know that the code has likely been rewritten, and we need to recompile it. It also makes it faster since the emuhack tells us where the jitted code is.

However, this only works because virtually all games just run MIPS code, they don't read it themselves. Metal Gear Solid: Peace Walker demo actually hashes its own code, and then (it seems intentionally) goes into an infinite loop because it doesn't match.

The interpreter works fine since it doesn't need the emuhacks.

We should collect any other games with similar behavior here.

  • Metal Gear Solid: Peace Walker demo:
    Happens at 0x09C92818 or 08CCD80C when v1 == 00003119 (which reads from 0x09C92818.)

    Can be worked around by changing 0x0880FAE4 to 0A203F39 (j 0x0880FCE4), skipping the hash compare.

-[Unknown]

@xsacha
Copy link
Collaborator

xsacha commented Jun 26, 2014

Is it possible to detect reads to the jitted code and present a version without emuhacks?

@hrydgard
Copy link
Owner

Possible in non-fast-mem, yes. but would require heavy checks for every read so is a non-starter performance-wise.

I've been thinking about trying some simple 2-level hash table instead of of overwriting instructions, PCSX2 uses that approach with good results but I don't know how it would compare speed-wise to the current approach.

@unknownbrackets
Copy link
Collaborator Author

It's hard to know how many games this affects. We can guess, but some things can also be jit bugs.

We could make it so that slow/safe mem (or some new dev option) makes all reads in the "possible emuhack op ranges" go through ReadInstruction. This would probably be a lot slower, but we could use it to safely determine which games might be affected.

Or we could just change it, but I suspect anything we do will make it slower, but maybe not really much slower.

-[Unknown]

@unknownbrackets unknownbrackets changed the title Jit funny business being detected (Metal Gear Solid: Peace Walker demo) Jit emuhacks detected by games (Metal Gear Solid: Peace Walker demo) Aug 19, 2021
@Linblow
Copy link
Contributor

Linblow commented Jun 22, 2023

@unknownbrackets
The same issue arises with SOCOM FireTeam Bravo 1 and 2 when the server sends anti-cheat queries to the client.
For example, server sends a hash query, which the client (game) executes, and of course it always results in different hashes because of the emuhacks thus triggering a false positive. Is there any workaround for this, such as invalidating the Icache before performing a memory read of the game's instructions? Could there be a good alternative to the jit blocks hack?

@hrydgard
Copy link
Owner

The right way is to separate the block lookup from RAM and stop overwriting first-instruction-in-a-block, although we'd lose the inherent "change detection" of emuhacks (when they get overwritten, we necessarily end up recompiling).

Detecting changes can be done in other ways like playing games with page protection and exception handling, although been reluctant to go this route because it's hard to support on some of the ports we support (or would like to support).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants