Qwokka / Cetus

Browser extension for hacking WebAssembly games a la Cheat Engine
Apache License 2.0
528 stars 45 forks source link

request: Pattern matching #60

Open Riddle1001 opened 1 year ago

Riddle1001 commented 1 year ago
        i32.load8_s align=0 offset=64
        i32.const 0
        i32.ne 
        tee_local 1
        i32.const 100

I have some code like this, but every time the game has some updates (whether it be big, or a small hotfix), I have to find the function again. The game gets updated often, but never has the body of this function changed, none the less I have to find this function because it's index changed. Possibly a feature to pattern match & replace some specific code could be useful. In the above snippet example, I need to replace i32.const 0 with i32.const 1. Would be a nice feature, possibly I will try to add it soon. Perhaps it's really hard to generalize a pattern automatically like this, i don't know.

Qwokka commented 1 year ago

Good suggestion.

It's been a while since I've used pattern matching in gamehacking tools. Last I remember it looked something like "x??x??x??x" where "x" refers to a specific byte and "?" can refer to anything.

Is that still the standard or are their better examples of pattern matching?

Riddle1001 commented 1 year ago

Good suggestion.

It's been a while since I've used pattern matching in gamehacking tools. Last I remember it looked something like "x??x??x??x" where "x" refers to a specific byte and "?" can refer to anything.

Is that still the standard or are their better examples of pattern matching?

I haven't really done to much gamehacking, just knew about the concept of pattern matching, but researching I found someone reply to a similar question with this:

In simple terms:

First of all pattern scanning is only useful if the provided pattern is unique or the first result is relevant.
Now you need to mask out the "may change" bytes like pointers or offsets.
However most plugins automatically do that masking for you.

For instance, the mask will look like this
Code:
"xxx????xx??xx"
Or the more popular way lately
Code:
"01 8B 01 8B ? ?"
Note, that the first example will also need a byte array to check against the mask.
The second example shows a byte "array" combined with the mask. In this case "?" denotes an unknown byte and anything else a constant byte.

Now everything you need to do is loop through the memory region this code pattern is in (bytewise),
and for every iteration you parse the pattern string and compare it to the real bytes.
If the comparison was successful, you found the code pattern and return the address to the first byte matching.
Qwokka commented 1 year ago

I think I like the second example a bit more. I'll try to work on this. If anyone has any suggestions related in the meantime, please put them here.

Jack