Disassembling and Modifying C#
Recently I was working with a C# tool and found it didn’t quite do what I was expecting. Knowing that C# is fairly similar to Java in terms of compiling down to bytecode and running on a language VM I figured I might have a go at disassembling the C# executable and attempting to patch what I needed.
As a Java developer who occasionally has to deal with bugs in third party, closed-source, libraries I have become fairly adept at disassembling code to figure out what’s going on and potentially patch it to have the behaviour I need. Reverse engineering should never be the first option to try, and it is more often than not against the ToS and licenses of whatever third party code you’re meddling with (sometimes Oracle post crazy rants against third party investigations of their code) but sometimes it’s the only way to truly find out what is going on, especially when the documentation is short on details or outright incorrect.
With Java, the JVM runs Java Bytecode which is what Java compiles down to when you call javac. Other languages that target the JVM such as JRuby, Clojure, Scala, Groovy and others also compile down to Java Bytecode so they can be run on the JVM.
.Net works in a similar way with the Common Language Infrastructure which defines how CIL bytecode runs on a CLR. Languages like C#, VB.Net, F#, Boo, Eiffel and others compile down to CIL bytecode so they can be run on the CLR.
After a brief trip to Duck Duck Go I found out Visual Studio comes with a command, ildasm, which will disassemble .NET applications for you in much the same way Java comes with javap. Normally with Java I would use JD Gui or IntelliJ IDEA for my disassembly debugging but as I didn’t want to spend a long time learning to use C# tools I figured the provided command line tool was good enough for my needs.
The whole process was actually fairly simple. For my examples I shall call the bit of .NET software I wanted to modify Foo.exe.
- Open the Developer Command Prompt for Visual Studio
- Navigate to the folder containing Foo.exe (i.e.
cd c:\Foo-Folder
) - Run
ildasm Foo.exe /out:foo.il
- This should create a foo.il in the same folder as Foo.exe. It should also have extracted some .resources files from the executable which for my purposes don’t need to be touched
Once I had the .il file I opened it up in my text editor of choice and started reading. The Wikipedia page listing all CIL instructions was very handy as I’d never looked at CIL before.
The application I wanted to modify had been obfuscated which made things harder as there was no debug information left in the file, like variable names, but thankfully the issue I had was with behaviour triggered when a checkbox was ticked. This meant I could search for the string associated with the checkbox on screen and work backwards from there to find the obfuscated checkbox name. With that I could see what behaviour was dependant on the checkbox state.
For me it turned out that there was a condition which was testing the state of the checkbox incorrectly and the CIL showed the test was a beq.s (Branch to target if equal, short form) and could easily flip the condition by changing it to bne.un.s (Branch to target if unequal or unordered, short form).
Once my simple change was made I then had to re-assemble an application. Thankfully Visual Studio comes with another command to do this, ilasm. To get my patched executable I only had to run the following command:
ilasm /resource:foo.res /output:foo-fixed.exe foo.il
This should assemble a foo-fixed.exe with the modifications made to the CIL from the disassembled file and when running foo-fixed.exe you should see your changes work if you coded it correctly!
This post isn’t a full guide on disassembling software, Java or .Net, or a guide on how to modify obfuscated third party code. Hopefully it just serves as a little bit of information to let people know that when you hit a problem with someone else’s code and it’s not open source you don’t always have to just deal with it or work around the problems.
With a little bit of curiosity, a few searches online and an hour or two of reading you can start getting stuck in and fixing problems that most people shy away from. And provided you don’t use these skills to bad purposes they’re good skills to have.