Reverse Engineering Tools are Awesome; Except When You Don’t Want Them To Be
Published on July 31, 2019 by Sebastian Holst
Earlier this month, I had come across Scott Hanselman’s excellent blog post, What’s better than ILDasm? ILSpy and dnSpy are tools to Decompile .NET Code where he had shared his insights on the strengths and limitations of a laundry list of reverse engineering and debugging tools. In the comments that followed, someone had asked for an obfuscation recommendation for those times when a developer wants to protect their code against reverse-engineering (a reasonable question to be sure).
Unfortunately, comments had been disabled by that point, and so I had sent an email to Scott that mapped Dotfuscator’s anti reverse-engineering/tamper/debugging capabilities to the collection of developer tools that he had covered.
It seemed like an excellent opportunity – not to self-promote our work (work that, of course, we are very proud of) – but to call out one of the most labor-intensive aspects of what we do; tracking and responding to real-world app-monitoring/tampering developments.
In much the same way that antivirus software vendors update their products in response to shifting real-world threats, we are always updating our “in-app protection” and code obfuscation tools to counter evolving real-world reverse-engineering, debugging and monitoring tool capabilities.
…and soon after, Scott made an excellent suggestion – that we turn those notes into a generally available blog – thanks Scott!
This is a snapshot!
Regardless, there are a few points that persist across versions and product lines:
- If you are evaluating in-app protection tools (obfuscation, encryption & root, debug, tamper detection, etc), satisfy yourself that the vendor is regularly publishing updates (would you run a 2-year old version of your anti-virus software?).
- If you HAVE our tools (or a competitor’s), keep your software up-to-date! (same reason)
- Don’t lose sight of WHY you’re security your code – this also is a key requirements driver.
Use cases for “in-app protection” are multiplying and, consequently, so are requirements. Are you trying to protect Intellectual Property? (a traditional use case) Or, do you need to meet a PCI Compliance requirement to secure the data flowing through a Xamarin.Android app (or any one of a dozen other data privacy/security requirements)? Are there audit requirements? Incident detection and/or response requirements?
Thanks to Azure, business logic and sensitive data are migrating from the desktop to the relative safety of the cloud. However, Xamarin, .NET Core, and (soon) client side Blazor, each push code and data in the opposite direction – onto unknown devices and often beyond any kind of trusted control.
Developers increasingly have to translate abstract directives like “security by design and by default” into concrete controls and processes.
With all of this in mind, here’s a table based on the tools referenced in Scott’s post – I would encourage every organization to validate their own tool list of tools.
The following snapshot table shows to what extent these development tools can (and mostly cannot) overcome (in this case) Dotfuscator’s obfuscation, encryption, hardening and shielding transforms.
|Tools||Identifier de-mangling||Control Flow (code generation) Reversal||Mono Compatible Control Flow Reversal||String decryption||Runtime state check removal|
|ILSpy (Decompiler)||Cannot. Symbol names are permanently removed.||Can undo some transformations & remove some dead code.||Effective and are guaranteed to work inside any mono-compatible platform/runtime. Xamarin is included in this category.||Encrypted strings cannot be decrypted.||Checks to detect runtime issues such as a rooted Android device or the use of an unauthorized debugger cannot be extracted or circumvented. This includes anti-tamper, anti-debugger, Xamarin.Android Rooted device protection, and Android anti-tamper detection and response, etc.|
|dnSpy (Decompiler, Debugger, Editor)||Same as above|
|Reflector (Decompiler)||Cannot deconstruct transforms.|
|JustDecompile (Decompiler)||Same as above plus displays errors and/or crashes when clicking on classes & methods|
|dotPeek (Decompiler)||Cannot deconstruct transforms.|
|de4dot (De-obfuscator)||Attempts to, but fails often||Can undo some transformations & remove some dead code.||Fails with latest versions|
Impressive? We think so, but don’t take out word for it. You can always evaluate the latest version of any of our products HERE.