Convert your AOB script from ‘jump 5’ to ‘jump 14’

Section's for general approaches on hacking various options in games. No online-related discussions/posts OR warez!
Post Reply
Paul44
Table Makers
Table Makers
Posts: 391
Joined: Thu Jul 27, 2017 9:02 am
Reputation: 183

Convert your AOB script from ‘jump 5’ to ‘jump 14’

Post by Paul44 »

I recently got confronted with a situation whereby a Win 11 gamer received constant 'offset too big' errors upon using my (AC Syndicate) table. The strange thing is that the very same table runs just fine on Win 10 (and earlier Win versions). After some research/reading - guided by our contributors @CEF - I was able to solve the matter.
Since it took me some time to figure this out - and I'm expecting more of such "confrontations" myself in the foreseeable future - I wrote up this little paper (which might help out some of my colleagues here as well).

Before anything: a big thx to #VixHexven for his 'above and beyond' Q&A service. Since I never really got confronted with these errors, it was entirely up to him to test every change; and report back accordingly. And he did so 'with panache' ;)

You can find the doc here: [ [Link] ]

If you know of similar techniques/approaches, do let me/us know.

Sidenote: the use of that particular "game_gap" was actually introduced to me by #Sunbeam some years back (as he was using that technique in one of his tables I was researching; back some years ago... already)

Some other stuff to (possibly) look into:
1. extend game exe memory during launch ? $process, getModule()
2. 32b programs and/or win x32 possible issues ?
3. trampoline ?

User avatar
SunBeam
RCE Fanatics
RCE Fanatics
Posts: 4116
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 3485

Re: Convert your AOB script from ‘jump 5’ to ‘jump 14’

Post by SunBeam »

Mentioned this several times in the past 5-10 years, quite often I'd say. I guess it takes people a while to assimilate what the fuck I was talking about :D

viewtopic.php?p=104318#p104318
viewtopic.php?p=63305#p63305
viewtopic.php?p=97853#p97853
viewtopic.php?p=31616#p31616
viewtopic.php?p=79247#p79247
viewtopic.php?p=40968#p40968

And so on :D

The solution I recommend is using trampolines. What this means is from your address you first JMP to a cave inside the game process. And since you forcefully do that, the JMP will always be 5-bytes. I personally use the PE header, whereas I make writable the memory at $process+0x500 till $process+0x1000 <- this is where the executable code starts. Here you then JMP (14-bytes) to your allocated cave.

So like this (Lua code, but you can always convert it to auto-assembler):

Code: Select all

-- define our Trampolines spot
local gameModule = getAddress( process )
local offset = 0x500
t = gameModule + offset
fullAccess( t, 0x1000 - offset )
unregisterSymbol( "Trampolines" )
registerSymbol( "Trampolines", t, true )
Then in the actual script, I do this:

Code: Select all

// Trampolines+00

[ENABLE]

alloc( InfiniteOxygenHook, 0x1000 )
registersymbol( InfiniteOxygenHook )
label( InfiniteOxygen_o )
registersymbol( InfiniteOxygen_o )

InfiniteOxygenHook:
// ..
// your code here
// ..
InfiniteOxygen_o: // original 6 bytes below read via readmem
readmem( InfiniteOxygen, 6 )
jmp far InfiniteOxygen+6

align 10 CC // this makes sure that the address of whatever is assembled below this will end in a 0; so you get "16-bytes aligned" addresses
// ^ cave ends here

// our trampoline
Trampolines+00:
jmp far InfiniteOxygenHook

align 10 CC

// our hook
InfiniteOxygen:
jmp Trampolines+00
nop 1

[DISABLE]

InfiniteOxygen:
readmem( InfiniteOxygen_o, 6 )

unregistersymbol( InfiniteOxygen_o )
dealloc( InfiniteOxygenHook )
unregistersymbol( InfiniteOxygenHook )
So what the code above does is to place a JMP (5-bytes) at "InfiniteOxygen" address. This JMP will hop over to "Trampolines+00" address (which is at
gameModule + offset = $process + 0x500). Here it will write another JMP (14-bytes this time) that will hop over to the allocated "InfiniteOxygenHook", where our cave is. In there, another "jmp far" will hop back to original hook spot (at "InfiniteOxygen+6").

Short version: code jumps to trampoline; trampolines jumps to cave. You got a middle-man in-between, 5-bytes JMP hopping over to a 14-bytes JMP :D

Another thing I recommend doing is not using direct reads of variables. Get used to writing things like this:

Code: Select all

mov rax,MyStoredAddress
mov rax,[rax]
Instead of:

Code: Select all

mov rax,[MyStoredAddress]
Why? Because this 1 line above may cause the same "offset too big" error when attempted to be assembled.

BR,
Sun

User avatar
Rhark
Fearless Donors
Fearless Donors
Posts: 1541
Joined: Tue Apr 16, 2019 1:27 am
Reputation: 681

Re: Convert your AOB script from ‘jump 5’ to ‘jump 14’

Post by Rhark »

SunBeam wrote:
Fri Apr 15, 2022 7:06 pm
...
I can highly recommend these methods, since you helped me with the Dark Alliance table I have been using the trampolines for all UE4 games since these are the games I've experienced the most 14-byte jmps. I use a separate LUA method for Mono games from panraven (viewtopic.php?p=204222#p204222) which I highly recommend also.

User avatar
SunBeam
RCE Fanatics
RCE Fanatics
Posts: 4116
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 3485

Re: Convert your AOB script from ‘jump 5’ to ‘jump 14’

Post by SunBeam »

Rhark wrote:
Fri Apr 15, 2022 8:14 pm
SunBeam wrote:
Fri Apr 15, 2022 7:06 pm
...
I can highly recommend these methods, since you helped me with the Dark Alliance table I have been using the trampolines for all UE4 games since these are the games I've experienced the most 14-byte jmps. I use a separate LUA method for Mono games from panraven (viewtopic.php?p=204222#p204222) which I highly recommend also.
Ah nice :D So it scans the module the hook address belongs to for 0xCCs it can overwrite (much like 0x90s) and plant there the trampoline JMPs :) Since you only need 5, it won't be too much hassle. Might be an issue if you have lots of injections (and not enough 0xCC groups of 5). The same can be done for normal modules (non-Unity), I believe :P

Paul44
Table Makers
Table Makers
Posts: 391
Joined: Thu Jul 27, 2017 9:02 am
Reputation: 183

Re: Convert your AOB script from ‘jump 5’ to ‘jump 14’

Post by Paul44 »

^ @SunBeam: I did not know that method is actually called a 'trampoline'... which i showcase in the 2nd example :ph34r:.
I came across the term a few times while reading through them CEF topics; but the technique wasn't all that clear to me then... And yeah, never really felt the need for it... till now.
^^ @Rhark: thx for bringing that too my/our attention: again, did some UE 3/4 games, and had/have no need for such a technique so far. But the fact that the script searches_for/collects (CC) gaps is definitely worth looking into it. I have not researched it (yet), but assume it does this dynamically ? Hence why i opted to go for the '+500~1000' mem_region for being (near) guaranteed availability... (while these/certain CC_gaps could/can change location-wise per game_session/save_load/etc)

User avatar
Rhark
Fearless Donors
Fearless Donors
Posts: 1541
Joined: Tue Apr 16, 2019 1:27 am
Reputation: 681

Re: Convert your AOB script from ‘jump 5’ to ‘jump 14’

Post by Rhark »

I've only ever encountered one game that was using the area of memory at $process+500 which I think was Marvel's Avengers. Otherwise, it's a solid spot to have your trampolines.

Post Reply

Who is online

Users browsing this forum: No registered users