TLDR
By using LD_PRELOAD
, we can use our custom shared object with player class attributes. We tweak some parameters that determine the character behavior when jumping, allowing us to fly in the game!
The Video
Introduction
Having the ability to fly in games almost always lends your character a big advantage over the enemy, whether they are controlled by the game itself or by other players. It is also a great way to discover the map a lot faster than by just walking around. In this episode of the Pwn Adventure 3: Pwnie Island video series, we'll look at how we can implement a flying ability for our character using existing game code. So, how can we do it?
The Method
LD_PRELOAD
As discussed in the previous article, using the LD_PRELOAD
command in Linux terminal allows you to load a custom shared object that is used by the LD_PRELOAD
instead of the game's version of the shared object. In your version, you can then have customized classes with different behaviors for your character. By preloading your customized shared object, you change how things behave in-game, such as the walking speed or mana quantity. This is the technical foundation that we need so that we can make our character fly... and collect our first flag!
When I Say Jump...
Unfortunately for us, there isn't a simple bool enable_flying = true
that we can set and be done with. However, there is something else we can do...
That's right, we can probably tweak something in the player class using the existing jumping "infrastructure" to enable flying! And effectively, there's a nifty parameter we can set for our player:
player->m_jumpSpeed
Setting it to 99999
was a good way to test what happened. We then compiled our shared object, preloaded it so the game used it, and then headed over into the game to try out the jump (see previous article for instructions). We found out that with player->m_jumpSpeed = 99999
jump speed it wasn't really a jump anymore, but more of a rocket launch into the upper bounds of the atmosphere... but what matters is that it works.
Now that we know that this works, we lowered the jump speed a lot, and added a jump hold time so that our character can jump up and stay there, which is a step towards flying. We set the following parameters:
player->m_jumpSpeed = 999;
player->m_jumpHoldTime = 99999;
With those numbers in, we compile and preload the shared object, and head in-game. Our character can now jump and keep ascending as long as we hold the spacebar key down. Interestingly enough, once we release the spacebar key, we cannot ascend anymore (or jump again, for that matter) until our character touches the ground again. Not quite flying yet, but we're getting there!
From Jumping to Flying
After snooping around a little more in the player class code, we found a single line that might hold the keys to progressing more:
virtual bool CanJump();
Since this function returns a boolean, let's try just returning True
every time it's called.
And, lo and behold...
There we go! We can fly now! The horizontal speed is really slow once we're in the air which is a downside, but we can at least reach elevated spaces without too much work now.
Getting Our First Flag
The horizontal speed aspect of flying is not conducive to making covering large distances, but you may remember from a previous video that we can walk on water just as we would on land, where we have a sweet walking speed set to 99999
. This allows us to just run to the island we saw when we launched into the atmo ahem, jumped quite high.
When we got there, we met the Cow King, and then immediately got killed. Great. We respawned and had a chat with Michael Angelo, who gave us a magic Rubick's cube that could contain and steal the lightning powers from the Cow King. So, equipped with the cube, we confronted the Cow King once more, held up the cube to swallow up the lightning, and equip us with the ability to dish out some high voltage juice ourselves. And dish out we did, so much so that we killed the Cow King, and completed the "Until the Cows Come Home" quest from the first episode in the series. We also kept the static link weapon, gained the Cowboy Coder gun, and clinched a Monster Kill achievement. Not bad!
And what is that in the chest?!
Yup, it's the Flag of the Cow! The key reads "I should've used dynamic link". During the original Ghost in the Shellcode CTF competition in 2015, this flag would've been worth 100 points, which is the lowest amount awarded... but that's fine! We found a flag, that's already huge progress on its own!
A good challenge to pursue now is to get the other flags from this CTF competition. We'll go over the rest of these in the next videos in the Pwn Adventure 3 series.