views:

30

answers:

1

I've been asked to patch a few minor flaws in a game of the unreal series. It uses the unrealscript language which produces bytecode in a similar way to Java.

One of the issues is that it's possible to edit any packages downloaded to a client and insert a goto instruction to jump over important bits of code.

It isn't possible to prevent this so I'm wondering what sort of strategies could be applied to make the task more difficult. There's two approaches that come to mind:

  1. An automatic internal state checking mecanism for anything that is clientside. The way it be done would be to have a before and after check for each function call. One peculiarity of the language is the out keyword in functions (see below).

    http://wiki.beyondunreal.com/Legacy:UnrealScript_Language_Reference/Functions#Function_Parameter_Specifiers

    The "out" specified lets you tell a function that it should actually modify the variable that is passed to it, rather than making a local copy. This is useful, for example, if you have a function that needs to return several values to the caller. You can just have the caller pass several variables to the function which are "out" values.

  2. A serverside checking mecanism that takes action if something incoherent happens or there is a timeout. Obviously, code can't be bounced between the client and server every tick because of the overhead it would generate but it would be possible to have some information exchanged, say, every x seconds.

    Perhaps the two approaches could be combined. What is your opinion on this?

+1  A: 

If the purpose is to determine if any of the code has changed, then the straightforward solution is to checksum the code (like at initialization—or even earlier, like before being downloaded) and periodically verify that the code's checksum hasn't changed.

Then the problem becomes detecting whether the checksum checking code hasn't been hacked.

The only time I was defeated as a hacker was an expensive package with the target code using more than five checksum routines called from seemingly random different points in the code. It was more trouble than it was worth to figure out how to work around it. Just be sure to initialize each of the checksums using a different function but make the call of the initialization hard to track down. Doing all of them in a row during initialization makes it really easy to defeat.

wallyk
Thanks for the input wallyk. Checksums are possible. This apparently requires overriding a specific standard class as disk I/O is practically inexistant (probably by design).
James P.