Hey, this is a very brief tutorial on scanmem, a memory manipulation tool for Linux that's well suited to game hacking. I'll be using GZDoom as an example, but you should be able to follow along with any game you want.
Firstly, install scanmem. Check your distro's repositories as there's a very good chance it's in there. If you need to compile from source, you can download it here.
$ # Arch Linux users would do the following:
$ sudo pacman -S scanmem
Now you'll need to start scanmem. It's a command-line tool, so you need to do it from a shell. scanmem doesn't ask for much, just root privileges and the PID of the game you want to hack, which you can specify as a parameter when starting it:
$ sudo scanmem `pidof gzdoom`
You'll initially be greeted with some copyright information, followed by a pretty courteous prompt:
Please enter current value, or "help" for other commands.
What it wants you to do now is enter the current value of the variable you want to change. I suggest that you pick something easily changed by legitimate means, like health. In my example with GZDoom, I'll be modifying the amount of shotgun ammo I have, so I would enter:
It will now scan through the process memory for everything that could be interpreted as a 13, and spit out a message about having some absurd amount of matches.
info: we currently have 22290 matches.
We're going to have to narrow that down. Go back to your game and change the value. If it's health you're trying to modify, go get hit by an enemy. For me, I'll fire off some shotgun rounds.
When you're done, you need to let scanmem know how the value changed. You can give it another literal value, like "12", but scanmem provides a few helpful shortcuts.
> tells it that it generally increased,
< tells it that it generally decreased, and
= tells it that it stayed the same.
..........info: we currently have 5 matches.
Wow, that really narrowed it down. Just wash, rinse and repeat until that number of matches stops changing.
If you manage to narrow it down to 1, good job! You can just use the
set command to set the variable like this:
1> set 65535
Although for me, it's stuck at four results. That's not bad, though. You just need to experiment with writing to those potential addresses. You'll first need to
list the addresses it found:
[ 0] 345e214, 2 + ecf214, heap, 11, [I32 I16 I8 ]
[ 1] 34606c4, 2 + ed16c4, heap, 11, [I32 I16 I8 ]
[ 2] 346bc90, 2 + edcc90, heap, 11, [I64 I32 I16 I8 ]
[ 3] 3ecb358, 2 + 193c358, heap, 11, [I32 I16 I8 ]
There's a bit more information than we need here, but that's no problem. The second column contains the memory address it thinks is the variable, and the last column is the possible integer types. (I8 is an 8-bit signed or unsigned integer, for example). What we're going to do now is write the value we want to those addresses until the change we want happens. This is done with the
write command, which takes the integer type, the address, and the value as parameters.
4> write i32 34606c4 65535
4> write i32 345e214 65535
4> write i32 346bc90 65535
4> write i32 3ecb358 65535
And eventually, you will be rewarded.