The battle between Game developers and Game Hackers - Part.1 How HiddenInt works

Harvest: Massive Encounter is a very unique strategic tower defense game published by Oxeye Game Studio. The game is amazing, but I won’t focus on that. I will discuss something interesting I discovered when hacking the game.

By hacking the game, I want to lock down the the number of Mineral that I have in the game. Mineral is the only key resource in the game, which is used to build or upgrade structures. Theoretically locking down a value is easy. Scan the memory for specific number for a few times to filter out the list of potential memory addresses. Then try them one by one. And finally figure out the proper address, then locked it down with the game hacking tool. Very standard approach, and supported by most of the game hacking tool.

But in Harvest, the story is quite different. By searching the mineral value, we can locate a specific address. But we can easily find that the value is only used for display instead of real game state data. In fact, Harvest uses a quite unique approach to protect its game status data! Oxeye guys call it the Hidden Int.

Here is the psudo-code explains how the it works:

HiddenInt Psudo implementation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class HiddenInt {
private int mask;
private int hashedValue;
private Random maskGenerator;
public HiddenInt(int initialValue) {
maskGenerator = new Random();
setValue(initialValue);
}
public void setValue(int value) {
this.mask = maskGenerator.next();
this.hashedValue = value ^ this.mask; // ^ is xor operator.
}
public int getValue() {
int value = this.hashedValue ^ this.mask;
setValue(value); // Generate a new mask and hashed value every time when the value is read.
return value;
}
public int modifyValue(int difference) {
int value = getValue();
value += difference;
setValue(value);
return value;
}
public ~HiddenInt() { // Destructor
delete maskGenerator;
}
}

So from the code, you can see, the plain value is never got stored in memory. Instead, it stored a “hashed” value, which is the plain value xor a random generated mask. And every time, when either the value being read or written, the mask changes. This kills the almost all kind of memory scanning features in all kind of game hacking tool! You cannot find the plain value in the memory, so you have to use “fuzzy scan”, which detects the values changes instead of scanning specific value. Again, the data in memory keeps changing even when the value doesn’t (I’ll explain why it happens later), so “fuzzy scan” doesn’t work either here!! That’s a master kill!

Besides of keeping mask changing, it also keeps reading the value out and writing it back, which kills most game editing tool “value frozen” feature! Unless you can ensure you freeze the mask and hashed value at the same time, or it breaks the value! Since the reading and writing happen in a very high frequency (Again I’ll explain why it happens later), so you have to lock down the value at a specific point, or the locked value will be overwritten immediately.

Furthermore, since this value is the key game value, which is displayed on Game UI all the time, the getValue() is called every time when game UI renders! And usually game UI renders in at least 60fps. So the value is read 60 times per second, and the mask changes 60 times per second! (This is why the value keep changing in a high frequency!)

So this is the almost invincible way to keep key game state data safe from common game hacking tools!

In the next post, I’ll explain how to find out a bypass to this security mechanism!

Process.nextTick Implementation in Browser

Recursion is a common trick that is often used in JavaScript programming. So infinite recursion will cause stack overflow errors.
Some languages resolves this issue by introduce automatically tail call optimization, but in JavaScript we need to take care it on our own.

To solve the issue, Node.js has the utility functions nextTick to ensure specific code is invoked after the current function returned.
In Browser there is no standard approach to solve this issue, so workarounds are needed.

Thanks to Roman Shtylman(@defunctzombie), who created the node-process for Browserify, which simulate the Node.js API in browser environment.
Here is his implementation:

node-process

Infinite Recursion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener;
if (canSetImmediate) {
return function (f) { return window.setImmediate(f) };
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
var source = ev.source;
if ((source === window || source === null) && ev.data === 'process-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('process-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();

Here is some comments on the implementation.

setTimeout

To simulate the nextTick behavior, setTimeout(fn, 0) is a well-known and easy to adopt approach. The issue of this method is that setTimeout function does heavy operations, call it in loop causes significant performance issue. So we should try to use cheaper approach when possible.

setImmidate

There is a function called setImmediate, which behaves quite similar to nextTick but with a few differences when dealing with IO stuff. But in browser environment, there is no IO issue, so we can definitely replace the nextTick with it.

Immediates are queued in the order created, and are popped off the queue once per loop iteration. This is different from process.nextTick which will execute process.maxTickDepth queued callbacks per iteration. setImmediate will yield to the event loop after firing a queued callback to make sure I/O is not being starved. While order is preserved for execution, other I/O events may fire between any two scheduled immediate callbacks.

setImmediate(callback, [arg], [...])Node.js

The setImmediate function is perfect replacement for nextTick, but it is not supported by all the browsers. Only IE 10 and Node.js 0.10.+ supports it. Chrome, Firefox, Opera and all mobile browsers don’t.

Note: This method is not expected to become standard, and is only implemented by recent builds of Internet Explorer and Node.js 0.10+. It meets resistance both from Gecko (Firefox) and Webkit (Google/Apple).

window.setImmediateMDN

window.postMessage

window.postMessage enable developer to access message queue in the browser. By adding some additional code, we can simulate nextTick behavior based on message queue. It works in most modern browser, except IE 8. In IE 8, the API is implemented in a synchronous way, which introduce an extra level of stack-push, so it cannot be used to simulate nextTick.

Overall, there is no perfect workaround to the nextTick issue for now. All the solutions have different limitations, we can only hope that this issue can be resolved in the future ECMAScript standard.

Android Studio 0.6.1 SDK recognition issue when using Android SDK 19 and Gradle

A few days ago I upgraded my Android Studio to version 0.6.1. And migrated my android project build system from Maven to Gradle. Then nightmare happened!

Android Studio Version

It looks there are some issue with Android Studio version 0.6.1, which cannot recognize the jar files in Android SDK 19 (4.4 Kit Kat). As a consequence that all the Android fundemantal classes are not recognized properly, which makes IDEA almost impossible to be used.

Classes Not Recognized

After spending days on googling and trying, I realize the issue is caused that Android Studio doesn’t recognize the sdk 19 content properly.

Here is the content of Android SDK 19 that Android Studio 0.6.1 identified:

SDK in Android Studio

As comparison, here is a list of proper content of Andrdoid SDK 19 with Google API:

SDK in IDEA

Here is a list of proper content of Andrdoid SDK 19 retrived from Maven Repository:

Maven SDK

In the list, you can easily figure out that the android.jar file is missing! It is the reason why the classes are not properly recognized! Even more if you compare the list against the JDK 1.6, you will find that most of the content are the same.

JDK

Ideally, to fix this issue should be quite easy. Android Studio provides a Project Settings dialog allow developer to adjust the SDK configurations.

Project Settings Dialog:

Project Settings

But for Gradle projects, Android Studio displays a greately simplified project settings dialog instead of the original one, which doesn’t allow developer to config the SDK in dialog any longer.

Gradle Project Settings Dialog:

Project Settings

Still now, I figured out several potentisal workarounds to this issue, hope these helps:

  1. Downgrade the SDK version from 19 to 18 fixes the issue.
    If you not really needs SDK 19 features, try to downgrade the SDK version to 18 to fix the issue.
  2. Use IntelliJ instead of Android Studio
    I encounters a different issue when using IDEA, it fails to sync the Gradle file.
  3. Use Maven or ANT instead of Gradle
    Gradle is powerful, but there are too many environment issues when using with IDEs… Maven is relatively more stable.

I haven’t figure out a perfect solution to this issue, just hope the Google can fix the issue as soon as possible.