# eternal life, ammo, scores in games

a man asked me how to find where games keep scores, eternal life or ammo. the answer is simple and I doubt is it worth to be published here or not. well, let’s try and see.

as a general rule, scores are stored “as is”, I mean: if you have 666 scores, some memory cells keep 9Ah 02h (dec2hex, and remember the byte order, the less significant byte comes first).

you don’t need IDA Pro to do that. use any memory dumper. personally, I prefer soft-ice (dumping memory via history; another way to do that is using extensions like IceExt), but there is a lot of dumpers anyway.

ok. check your safety belts, we’re blasting off:
1) dump the process when you have the certain score;
2) dump the process again with the same score, but something different (move player to the next place for example, open a door, etc);
3) do something to change the score and dump the process once more;

ok, you have three dumps with two different scores.

1) compare first two dumps to find unmatched bytes – they are definitely not the score (since, first and second dumps have the same score);
2) delete the unmatched bytes out of the dumps;
3) compare first and third dumps to find unmatched bytes – some of them definitely keep the score;
4) find the best candidates for “scores”. if you’re lucky, you have only one hit equaling to scores, which you got in the game. but quite often you have two or more locations, keeping the scores (or something looks like). some of them – is nothing just false positives (more dumps – less false positives), but some of them are natural “copies” of “original” score. the program can store the score-value in the global variable, passing it to many functions, so you have to find out which one is genuine. it’s simple. just change the memory cell with your favorite debugger return to the game. if the score-window doesn’t react, you’re dealing with “forgery”. try the next one. however, score-windows might accept your value, entered in the debugger, leaving the actual score unchanged. this is because of using local copy of original score variable for score-window;

5) ok. you have found the exactly memory location of the original score variable – set hardware breakpoint on access and debugger helps you to discover the code reading or writing it;

6) modify the code as you wish, for example, if it adds 10 points, you might change 10 to 100;

btw, to compare dumps, I wrote quick-n-dirty utility. yeah, it’s a very silly tool, so feel free to rewrite it.

// usage: fck.exe dump_1 dump_2 dump_3 ... dump_n
// note: find the "hot" bytes.
// dump_1 and dump_2 are supposed to have matched "hot"-bytes,
// while the other dump are supposed to have unmatched "hot"-bytes.
#include

#define MAX_DUMPS 0x10
main(int c, char **v)
{
int pos=0;
int a,b,flag;
FILE* f[MAX_DUMPS];
unsigned char ch[MAX_DUMPS];

if (c-- < 4) return printf("-err: need more files\n");

for (a=0;a<c;a++)
if (!(f[a]=fopen(v[a+1],"rb"))) return printf("-err: cant open %s\n",v[a+1]);
printf("raw offset");for (a=1;a<c;a++) printf("\t%s",v[a+1]);

while(1)
{
for(a=0;a<c;a++) if (!fread(&ch[a],1,1,f[a])) return 0; pos++;
if (ch[0] - ch[1]) continue;
for(a=flag=1;a<c;a++) for(b=a;b<c;b++) if ((a-b) && (ch[a]==ch[b])) flag=0;
if (flag) for (printf("\n%08Xh:",pos-1),a=1;a<c;a++) printf("\t%02Xh",ch[a]);
} printf("\n");
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: