Today I’ll show you how to get the source code of any game that’s made using C#, the .NET Framework and Microsoft’s XNA Framework. Basically, this will also work for all .NET Applications, but for XNA Games it’s more difficult, so I will explain it for XNA here.
I hope you understand and like it, if there are any issues, please comment to help me improving this tutorial!
Warning: You may violate copyright laws in your country if you try to obtain property (in this case source code) that you don’t own! Check your legal situation before following this tutorial! I won’t be responsible for any criminal offence done with the information provided!
Step-by-step tutorial to disassemble the game
Things you need
- An XNA-based game
- .NET Reflector
- Visual Studio 2005/2008
- XNA Game Studio 1.0/2.0/3.0
Decompiling the binary file
First of all, you need a really great tool called .NET Reflector. You can download it from the official website or from my server. The .NET Reflector can look inside .NET binaries (.exe and .dll files) and disassemble the code to any of these programming languages: IL, C#, Visual Basic, Delphi, MC++ and Chrome.
Once you start .NET Reflector, it should look something like the image above. As you can see, on the left is a list of all Assemblies found on your computer, and on the right the code of the selected one. If you don’t see the yellow part on the right, just go into any Namespace and class and double-click on a function.
Here you can already play around with it and look into the .NET Framework source, maybe you find some interesting parts of code
Back to decompiling your game… I assume you have a complete game on your hard disk (the binary file and a content folder with all the game data inside).
For this tutorial, I’ll use Mircosoft’s PickingSample, I think I don’t violate any copyright laws doing it since it’s open source anyway. If I do, please tell me!
In .NET Reflector, select Open File, navigate to your game’s .exe file and double-click it. The application should immediately show the Assembly in the Assembly list. If you just want to have a look at the code, click at the Assembly and select the class/method you want, the Reflector will show the code on the right.
But we want to have the whole game’s code as a Visual Studio project. Rightclick on the Assembly (in this case “PickingSample”, click on “Export…” and enter the path where you want to project to be stored.
If you see a Window popping up like the one below, tell Reflector to load your XNA Framework binary files (click on the three dots on the right, then navigate to C:\Program Files\Microsoft XNA\XNA Game Studio\v3.0\References\Windows\x86 and select the required file, in this case Microsoft.Xna.Framework.Game.dll).
Creating a Visual Studio project
When the export is done, navigate to the directory where you exported the game to and open the project file .csproj (here PickingSample.csproj).
Probably, your Visual Studio will ask you to convert the outdated project file, allow to do it and there you are! Now we have the whole source code in a Visual Studio project and can work on it, make changes and recompile it!
The first compilation of the disassembled code
Press F5 to try to compile the project. The game will crash immediately after startup when trying to load models, sprites, sounds etc. because it can’t find your data files.
All the data files required are within the original game you want to decompile, but converted to the XNB file format. Currently, there is no way to reverse-engineer these files, so we will just let them be as they are. Copy your original game’s content folder into your new project’s \bin\Debug folder and compile the project again. Now it should work!
Missing things in the project
In your new project, all the comments of the original code will be gone, the structure may be different and settings and resource files may cause some problems. But all in all, you have the source code of the original game!
Additional steps
If you still want to get more, like the Windows Explorer icon of the game, use a free tool like IrfanView, drag the .exe file into it, save the icon as PNG and import it into your project.
Trouble-shooting
I copied the content folder into my new project, but the game still crashes when loading the media files!
Look properly at the error message you get. Is it similar to this one?
Error loading “Content\Fonts\Menu”. Cannot find ContentTypeReader Microsoft.Xna.Framework.Content.ListReader`1[[Microsoft.Xna.Framework.Rectangle, Microsoft.Xna.Framework, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d]].
In this case, the game was compiled using XNA Game Studio 2.0 and thus the Content Pipeline 2.0, but I was running Visual Studio 2008 with Game Studio 3.0. The new Game Studio seems to have problems using older files, so the only thing you can do is installing Visual Studio 2005 and Game Studio 2.0 again. The same thing for Game Studio 1.0
If you encounter any problems following this tutorial, please comment so I can search for solutions and make this tutorial more complete!






November 20th, 2008 at 4:29 am
hahaha, this is great. Reminds me of Flash. You can decompile it and your left with source code that acts and does exactly what it’s supposed to do but it’s usually slightly different than the original. Whats horrible is that you cannot get the comments out of the original source, is there any way to do that or is it not even included in the IL or whatever?
Amber
November 28th, 2008 at 11:35 pm
no, there is no way to get back the comments. the compiler just ignores them and doesnt put anything that reminds of them into the binary file.
March 17th, 2009 at 10:46 pm
Да уж. В этом блоге хоть комментаторы нормальные.. А то пишут обычно в комментарии ерунду всякую.
October 13th, 2009 at 10:56 am
He should write English… thats what Google Translate gives me:
“Yeah. In this blog though commentators normal .. And then usually write in the comments all nonsense.”
October 14th, 2009 at 7:14 am
Yep… Reflector is a great piece of software. I’ve had it for a while. I first got it many months ago to test the effectiveness of different obfuscators (which weren’t very impressive). But I’ve found other solutions to protect my work (which I can’t reveal, sorry!).
You’ll instantly realize you’ll need a new decompiler. Reflector will throw a error saying the target has no CLI header. Even with a native -> C/C++ decompiler, you will get rather junky/sloppy code, lose all the object names, and it may not even run! There’s actually a good analogy right here on this page. Right above, someone tried to translate the Russian guy’s comment to English. Imagine that the Russian comment is native binary, and he just tried to decompile it to C++ (English). Well, the syntax (grammar) is all messed up now, and we all known our brains (compiler) won’t compile English when it has syntax errors.
But that’s often what can happen when you decompile from native binaries, except it will make even less sense. You’ll have nonsense naming, like “a + b = e_1;”.
The author is right, comments are not put into the executable. When you declare a comment, you are basically telling the compiler “ignore”, or “don’t add this to exe”.
However, the author is also wrong. It’s funny, because I saw the same exact mistake in a book written by a professional moments ago, which is how I stumbled across this page (after searching for book reviews). .NET applications do NOT compile to binary… They DON’T… It’s that simple, but many people mistakenly think it does. Why do you think you can decompile it so easily, and keep the original object names? Try the same thing on a real native binary originally written in C/C++/etc, and see what you get.
.NET applications, since they aren’t native binaries (like UNmanaged/NON-.NET C/C++), actually compile to CIL (Common Intermediate Language). It’s almost like an intermediate form of assembly language. What happens with such managed code is that it’s actually run on a ‘virutal machine’; called the CLR (Common Language Runtime). In a sense, it’s very similar to the Java Runtime Environment; the virtual machine from Sun that runs Java on your PC (quite seamlessly). This is why you can decompile .NET code so easily, and maintain all of the hierarchies/preserve object names/references. During runtime, the CLR engine only compiles parts of the code which are executed, which is why people say .NET is slower than native binaries (only 2%, according to most benchmarks, which is rather unnoticeable). If you have a method in your code that does something, like print a document, and you don’t print, the method is never compiled and executed (as opposed to a native exe, which is totally compiled in advance). Because of this, .NET applications are actually more memory efficient. The CLR’s hailed “Garbage Collector” can dispose of parts of the code and free up unneeded memory. So even though you get that tiny performance cost, it’s actually canceled out by a performance GAIN (most of the time, since nothing is certain with computers).
I hope my rather long reply was enlightening/informative to at least someone, and I apologize if it was boring to you!
October 14th, 2009 at 11:21 am
@marvin:
Thanks for your long comment. Actually I’m aware that .NET applications aren’t compiled to real binaries and that the code is still somehow stored in it. At least that’s what it says in my book
I’m still calling the executables “binaries” because they’re stored in the bin/x86 folder, this “bin” just makes me think of the usual binaries when working with C++ or stuff like that.
And since I usually only differ between “compiling” for C/C++/C# and “parsing” for PHP/Perl, I still call it compiling, even though you are just debugging the project. That’s just my way of calling it.