Cheat prevention?

Started by
36 comments, last by ApochPiQ 10 years, 7 months ago


It’s very easy to exploit.

Does this work arbitrarily deep? For example, if you have a pointer to a changing pointer address to a changing variable address? :)

Advertisement

It is arbitrarily deep. Anything the game does to figure where the real value is can be emulated via hacks.

In fact, programmer laziness often betrays the programmer who tries to make things overly complex. A programmer will often make a deep and complex system that may even involve decryption to a small degree, but in order to save time he or she will make a single function that does all the work.

A hacker will notice this function and save it as a reference while trying to follow the pointer trail. If the pointer trail goes bad or is too complex, the hacker may just decide to call that function manually and get the result. It requires DLL injection and a bit of time, which is why the hacker will prefer to follow pointers if possible, but it still works as a last-ditch effort.

So even if you did make a very complex string of pointers to follow, you would likely not be thwarting anyone even if you left no holes to exploit, and leaving no holes is non-trivial at best.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

 


I got into this conversation with a friend, and he suggested modifying the compiler to use fewer registers, preserving "important stuff" in those newly unallocated registers.  It's a very heavy-handed way to go about it, will lead to serious repercussions in performance, and still isn't fool-proof, but it's damned hard to get around because it requires a lot of inside knowledge to know what gnarly asm to inject.

Wat?

Using "fewer registers" doesn't make any sense. First of all, that means more stuff will be spilled to stack memory, where it's actually easier to find and modify. Secondly, it's going to be transiently limited to the runtime of a single function at most, so those values still have to go back to stack or free-store memory at some point. Finally, on platforms like x86-32, there's already so few registers available that this is just... not smart to try.
The high level view of "using fewer registers" and putting data in "unallocated" registers is that it cannot obfuscate anything.
The same data is read and written in arbitrary memory location and registers of your choice using exactly the same instructions. Compare these two x86 code fragments:


POP ECX
MOV EBX, EAX
ADD EBX, ECX


POP EBX
MOV EDX, EAX
ADD EDX, EBX


Which one is harder to comprehend and hack?

Omae Wa Mou Shindeiru

There is no reason one would be more cryptic to a hacker than the other; they do exactly the same thing.

The high-level idea behind using fewer registers is flawed and ApochPiQ correctly pointed out those flaws.

Reiterating, it means more spills, which means more RAM dumped onto the stack, which is easier to access than registers (to access registers you have to have an actual debugger attached and apply breakpoints and stop the program at just the right instruction).

And it is limited to a single function’s scope. Eventually, whatever data you want to protect will be written to RAM in the end anyway.

If you are suggesting that it is not only possible but sane to use a register for a single value for the life of the entire game then you are simply crazy.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

I think the java hackers are currently sharpening their teeth on the Android platform...

Though mostly they just strip DRM-stuff now, but they do it by modifying the bytecode of the executable to remove the calls.

Simple hacks, sure, but I don't think you should feel safe just because you run your game in java.

There is no reason one would be more cryptic to a hacker than the other; they do exactly the same thing.

The high-level idea behind using fewer registers is flawed and ApochPiQ correctly pointed out those flaws.

Reiterating, it means more spills, which means more RAM dumped onto the stack, which is easier to access than registers (to access registers you have to have an actual debugger attached and apply breakpoints and stop the program at just the right instruction).

And it is limited to a single function’s scope. Eventually, whatever data you want to protect will be written to RAM in the end anyway.

If you are suggesting that it is not only possible but sane to use a register for a single value for the life of the entire game then you are simply crazy.

L. Spiro

No, that's exactly it. The whole point is that you don't save the registers in question to the stack frame. Basically, you modify the compiler to use fewer registers (easily done in LLVM at least), and then access the unused register with in-line assembly. It's not difficult to do, but it's an absurdly expensive method to protect a single word of memory, and still won't work if the attacker realizes you're doing it (for the very reasons you stated). It is pretty hard to detect relative to other protection schemes though.

I never said it was practical. If anything, it goes to show just how far you can go and still lose to someone that actually wants to cheat in your game.

Theres 2 ore more diferent types of hacks

(DLL Injection)

(Engine Hack)

Engine hacks seem to be the hardest to detect.

:)

No, that's exactly it. The whole point is that you don't save the registers in question to the stack frame. Basically, you modify the compiler to use fewer registers (easily done in LLVM at least), and then access the unused register with in-line assembly. It's not difficult to do, but it's an absurdly expensive method to protect a single word of memory, and still won't work if the attacker realizes you're doing it (for the very reasons you stated). It is pretty hard to detect relative to other protection schemes though.

I never said it was practical. If anything, it goes to show just how far you can go and still lose to someone that actually wants to cheat in your game.



It depends on who your enemy is.

A script kiddie with nothing more than a memory editor might be confused. An actual reverse engineer with more than a couple trivial hacks under his belt will smell this a million miles away and laugh at you.

A reverser will actually use tools like debuggers and register snapshots to examine your program behavior. All you've done is make his job easier because the target value he wants just "happens" to always sit in a nice register.


It's sort of like saying that carrying a wooden carving of a handgun is protection. It might fool really stupid people, but anyone who's serious about hurting you is just going to be amused.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement