Breaking the Minecraft client

#reversing#java#minecraft#bytecode#injection::alemi::2020-06-06 18:50

Learning reversing with Minecraft

I have always loved Minecraft: the lack of goal but complete freedom it gives makes it very appealing to me.

Like everyone I started by punching trees but quickly moved to "modpacks" introducing complex relations and recipes. When that was no longer enough, I started discovering the potential of builtin game concepts: did you know minecraft redstone can be used to make turing-complete machines? Eventually automating the game from inside wasn't enough for me, I really wanted to make external tools.

I started by messing with the network: once I found the protocol spec, I started building some simple scripts to keep the player online, then some crude proxies and automated bots.

But the real fun started once I moved to injecting modifications at runtime. After learning what Forge is and what it does, I had a simple but complete framework to modify the game behavior directly.

But Forge has its limitations: it provides some "hooks" which can call your code, but not everything is possible. I needed to go deeper.

Bytecode modification frameworks exist in the minecraft developer world, and the most widely used is Spongepowered Mixin. This allows to rewrite whole methods in classes at the bytecode level at runtime, but using "plain" java. As interesting as it sounded, I felt like it would be "another Forge", where I would eventually hit the brick wall. So I decided to skip this step and go deeper.

Thanks to objectweb ASM library and some modloader magic (specific to minecraft), it's possible to write JVM assembly and insert that wherever you want. It's possible to rewrite access modifiers, completely reroute methods and mess up the stack in so many extremely obscure ways (array errors when you pop too much are just soooooo fun to debug!).

But this was it: I could now do anything I wanted, from rendering the tablist larger, to detaching the camera from the player, even making the client believe water is solid. I was so proud of my new skills I had to put them to use.

I started participating in developing hacks mods for the game. It was so fun it quickly became addictive: the server source code is available for reading, and there are so many weird edge cases to find in Mojang messy Java! Spot a weird bug, make a mod which abuses it, enjoy an easier game, rinse and repeat!

I want to stress that I never abused these mods against unknowing people: while it's just a game, I really would hate to ruin the experience to others thanks to unfair advantages. I'm doing this to learn, not to win!


After helping for some time other projects, I decided I didn't just want to add mods here and there, refactor badly written implementations and clean up messy settings. I wanted to build a whole new environment. I thus decided to make a new utility mod from scratch, together with a lightweight patching framework. This fresh project aims to suit exactly my use cases while being modular and hackable. While it's nowhere as complete as my previous solutions were, it's clean and minimal, two features I really care about.

This is a cooperative project with some friends, and all source code is hosted on our shared server.

bscv -- lll -- loader