Reverse engineering

Demystifying Dot NET reverse engineering, part 1: Big introduction

October 24, 2012 by Soufiane Tahiri


This, and all upcoming parts, are made with a strict and pure educational purpose just to gain insights into dot NET programs. What you’re going to do with this and all upcoming parts is your own responsibility. I will not be held responsible for your eventual action and use of this.

All techniques used in this and all upcoming parts have been used only to demonstrate theories and methods described. The scope of this paper and all upcoming parts as well as any other paper written by me (Soufiane Tahiri) is of sharing knowledge and improving reverse engineering techniques.
And please note that disassembling and / or reversing software is prohibited by almost all international laws, if you like software then please BUY IT.

This will be a kind of “saga” of papers that will talk essentially talk about dot NET oriented reverse engineering. We are already on the stable version 4.5 (4.5.50709) / 15 August 2012 of Microsoft .NET Frameworks for Visual Studio 2012 and distributed with Windows 8, Windows Server 2012, but we are still not seeing enough papers about reversing applications developed using dot NET technology.

I’ll try to fill this lack of papers, and this first article is supposed to be a part of an upcoming series that would explain some basics and clarify dot NET architecture to the extent of making a few concepts clearer for reverse engineers.

Before starting, I strongly recommend you take a few hours to teach yourself at least one of the dot NET languages, and I recommend either Visual Basic .NET or C#. It may seem to some that reversing dot NET programs is way easier then reversing “traditional” programs, which is wrong in my point of view.

The concept of dot NET can be easily compared to the concept of JAVA and Java Virtual Machine, at least when talking about compilation. Unlike most traditional programming languages like C/C++, applications developed using dot NET frameworks are compiled to a Common Intermediate Language (CIL or Microsoft Common Intermediate Language MSIL) – which can be compared to bytecode when talking about Java programs – instead of being compiled directly the native machine executable code, the Dot Net Common Language Runtime (CLR) will translate the CIL to the machine code at runtime.

This will definitely increase execution speed, but has some advantages since every dot NET program will keep all classes’ names, functions’ names variables and routines’ names in the compiled program, and this, from a programmer’s point of view, is such a great thing since we can make different parts of a program using different programming languages available and supported by frameworks.

Figure 1. Visual overview of the Common Language Infrastructure (CLI) / Wikipedia

What does this mean to a reverse engineer?

Basically every compiled dot NET application is not more than its Common Intermediate Language representation, which still has all the pre-coded identifiers just the way they were typed by the programmer.

Arizona, California, Colorado, Florida, Georgia

Technically, knowing this Common Intermediate Language will simply lead to identifying high level language instructions and structure, which means that from a compiled dot NET program we can reconstitute back the original dot NET source code, with even the possibility of choosing to which dot NET programming language you want this translation to be made and this is a pretty annoying thing!

When talking about dot NET applications, we talk about “reflection” rather than “decompilation”, this is a technique which lets us discover class information or assembly at runtime, this way we can get all properties, methods, functions, etc. with all parameters and arguments, we can also get all interfaces, structures, etc.

Nowadays there are plenty of tools that can “reflect” the source code of a dot NET compiled executable; a good and really widely used one is “Reflector” with which you can browse classes, decompile and analyze dot NET programs and components. It allows browsing and searching CIL instructions, resources and XML documentation stored in a dot NET assembly. But this is not the only tool we will need when reversing dot NET applications. I’ll try to introduce each one every time we are in need of it.

What will you learn from this first paper?

This first essay will show you how to deal with Reflector to reverse a very simple practice oriented Crack-ME I did the very basic way, and it does not pretend to explain real software protection (that will come via the next articles).

Let’s practice

Our Crack-ME is a simple one form dot NET application that asks us for a password. I made it to show you some very basics about dot NET reverse engineering, usually we start by looking at the target and see its behavior, this way we can determinate what should we look for!

This displays a nasty message box when filling in a bad password:

Let us now see why this piece of compiled code shows us “Invalid password”. Open up Reflector, at this point we can configure Reflector via the language’s drop down box in the main toolbar, and select whatever language you may be familiar with. I’ll choose Visual Basic, but the decision is up to you of course.

Figure 2. Choosing the main language

Load this Crack-ME up into it (File > Open menu) and look for anything that would be interest us.
Technically, the Crack-ME is analyzed and placed in a tree structure. We will develop nodes that interest us:

Figure 3. Our Crack-ME is loaded up

You can expand the target by clicking the “+” sign:

Keep on developing the tree and see what is inside of this Crack-ME:

Now we can see that our Crack-ME is composed of References, Code and Resources.

  1. Code: this part contains the interesting things, and everything we will need at this point is inside of InfoSecInstitute_dotNET_Reversing (which is a Namespace).
  2. References: is similar to “imports”, “includes” used in other PE files.
  3. Resources: for now this is irrelevant to us, but it is similar to ones in other Windows programs.

By expanding the code node we will see the following tree:

Reflector detects the only form our Crack-ME has called Form1, with all variables, procedures, functions and Graphical User Interface elements, and as explained above it recognized original names, which makes things easier for us and lets us guess what everything is supposed to do. For example, the function btn_Chk_Click(Object, EventArgs) that seems to be triggered when the button “btn_Chk” is clicked, btn_About_Click(Object, EventArgs) which is presumably called when button “btn_About” is clicked…

Since this is an application to practice, it has not a lot of forms and functions, which makes things easier for us; we can now say that what interests us is what the function btn_Chk_Click () has to say. We want to know what our Crack-ME actually does once we click on btn_Chk, and this can be translated to the language we choose (refer to Figure 2).

To see actual source code, double click on the function name. Reflector shows us the decompiled source code in the language chosen, in this example we will get:

Nothing magical, we can see clearly as sun what this function does, everyone with very basic knowledge in any programming language can see that this function / procedure tests if the password typed is “p@55w0rd!”, and by checking this we get:

This is pretty easy! We can explore more abilities like patching this Crack-ME to accept all typed passwords, which will be certainly the next part of this course.

I tried to avoid giving you complex explanations regarding dot NET application and decided not to flood you in this first part with information that may discourage you. I tried to show you the clearest way to deal with a very basic protection, hopefully this taught you few more things that matter while reversing dot NET programs. In the next parts, I’ll try to introduce more in-depth knowledge about how dot NET programs really work


Posted: October 24, 2012
Articles Author
Soufiane Tahiri
View Profile

Soufiane Tahiri is is an InfoSec Institute contributor and computer security researcher, specializing in reverse code engineering and software security. He is also founder of and practiced reversing for more then 8 years. Dynamic and very involved, Soufiane is ready to catch any serious opportunity to be part of a workgroup. Contact Soufiane in whatever way works for you: Email: Twitter: LinkedIn: Website:

42 responses to “Demystifying Dot NET reverse engineering, part 1: Big introduction”

  1. S. G. says:

    Can you use ollydebug or IDA Pro to reverse engineer .NET?

    • Technically OllyDBG is useless since dot NET applications are not as “traditional” PE files and they are “executed” inside of the Common Language Runtime, but could be used for doing some manual unpacking, but you can use IDA (which we may see in some of upcoming parts) it supports dot NET programs:
      “The IDA disassembler can disassemble a portable executable (PE) file that contains Microsoft intermediate language (MSIL) code. The Common Language Infrastructure (CLI) is the ECMA standard that describes the core of the .NET Framework world.”

  2. pirko0 says:

    Finally some .net reversing stuff! 🙂 When is the next part coming? It would be great if you dedicate one of the articles to reversing obfuscated code, and maybe bypassing license check. 😉

  3. pirko0 says:

    Btw. article is in the wrong category/ It should be in “Reverse Engineering” not “Hacking”! 🙂

    • sarah says:

      Thank you 🙂 fixed

    • Thank you, The second is on way it will be about some basics byte patching, this will be an “ongoing” series I’ll try to dedicate some licence checks bypassing chapter ! and maybe presenting obfuscation as well just stay tuned it’s gonna be a quite long series about dot NET reversing!

  4. skywalk3r says:

    thnx for the article 😀

  5. Daniel says:

    That’s why you never should compare a password against a string (in .Net). Better create a hash and compare the hashed input against.
    Something like:

    var pwdHash = @”Rmg78oBTSaoJyaRFviEEJRXSkAA=”;
    var sha1 = System.Security.Cryptography.SHA1.Create();
    var encoder = new System.Text.UTF8Encoding();
    var encoded = encoder.GetBytes(this.txt_Pwd.Text);
    var base64Hash = Convert.ToBase64String(sha1.ComputeHash(encoded));

    if (base64Hash == pwdHash)

    Of course you must compute the pwdHash (“Rmg78…”) before. I.e. sha1.ComputeHash(@”p@55w0rd!”)

    • I would say NEVER hard code passwords nor serials and at this point even hashing it will be useless since all the code source is reflected and can be easily reversed. The aim was introducing dot NET, dot NET reverse engineering and Reflector since the “protection” defeated in this paper is actually rarely used in real life cases where we talk more about Encryption Obfuscation or NecroBit Protection in addition to the algorithms used to generate serials or passwords…
      Thank you for taking the time of reading this.

  6. peter says:

    Nice read but on an interesting topic. Thx for your work.
    I guess you meant execution time in this qoute: “This will definitely increase execution speed, but has some advantages since every dot NET…”

  7. z3dd4 says:

    I’m currently trying to follow your tutorial. Btw: thanks for having it. But I found that “Reflector” is now commercial. I googled it and found:
    Now I’m trying to do this tutorial with open-source software. Maybe it helps others.
    Please do Tutorial 3 asap! I appreciate your work!
    Greetings from Germany,

  8. z3dd4 says:

    One more question: I found the same leaks in my own C#-code. Could you advise how to avoid those leaks? Daniel wrote about hashing and you answered: “I would say NEVER hard code passwords nor serials and at this point even hashing it will be useless since all the code source is reflected and can be easily reversed.”
    Seems that might be a useful tutorial as well, wouldn’t it?
    Greetz, z3dd4

    • When talking about dot NET application and just like traditional ones we can talk about “packing” them, encrypting them or just (and especially for dotnet) obfuscating them which can make the application either “undecompilable” or just unreadable by messing with the names of classes, methods, events, properties… hiding call to methods and by encrypting strings … I may write something regarding obfuscation but meanwhile you can google for “dot net obfuscator” and see what I mean !!

      Thank you and good luck !

    • I started writing the 3d part it takes time to write something that will interest people !! I’ll do my best and try to introduce iLspy in this or in one of the upcoming parts just stay tuned !
      Thank you

  9. JetBrains dotPeek ia a freeware tool replacing Reflector seamlessly.

  10. Edward Maya says:

    Hi Soufiane,
    Nice reading ! Thank you for sharing this.

  11. Tom E. says:

    Very good article just like all articles from you ! Keep it up .

  12. Thank you, keep on visiting here more is comming!

  13. S. G. says:

    Very interesting article. I’m learning software RE with ollydebug and IDA, but this opened my eyes to other tools. Thanks Soufiane.

  14. uzhan says:

    Is this website a child’s blog. Very basic and bad..

  15. Jens says:

    Thanks Mr. Tahiri! Let me show you something:

    “private void Button_Click(object sender, EventArgs e)
    if (this.textEdit1.Text == “”)
    MessageBox.Show(“Input key to activate!”, “Error”, MessageBoxButtons.OK, MessageBoxIcon.Hand);
    MessageBox.Show(“Key not valid! Please try again!”, “Error”, MessageBoxButtons.OK, MessageBoxIcon.Hand);

    With this condition is there a possibility to activate the prog or is this just impossible? Are there other possibilities to override this?


  16. Troy says:

    Hi Soufiane – great article. After reading just parts 1 & 2 I was able to make the desired modifications to a dll (experimental purposes, of course!).

    However, when Reflexfil warned about a strong name, I chose to remove it (and did the same for an associated DLL).

    Now when I try to drag-drop them to the GAC, I get “was expected to contain an assembly manifest”.

    Is this due to the strong name removal? If so, what can I do?

    Thanks again.

    • Troy says:

      Hmm.. I found the only way I can get the builds into the GAC was to not remove the strong name but leave them as delay loading – then manually xcopy the dll into the (/gac_msil/assemblyname/versionnumber/etc). Lo and behold the patch works 🙂 Thank you so much for your article, excellent!

      • Thak you for leaving this comments and sorry for my late answers, actually you can just remove the precompiled version of the dll present ont the Global Assembly folder (if you have enough privilege) then run your application, the execution time will increase once then the GAC will contain a precompiled “modified” version of your desired dll.

  17. Troy says:

    Hi Soufiane,

    Im still having lots of fun with the things you taught me.

    Lots of information and misinformation on the net about reverse engineering, your articles are the first that gave me any usable benefit.

    That being the case, I was hoping you could point me in the right direction to learn more about general (not just .net) reversing?

  18. Hello Tony, thank you I’m glad you had fun withmy series.
    Here is a great place to start from :

    Good luck !

  19. Troy says:

    Thanks Soufiane, very cool.

  20. Rahul says:

    I want to learn technique of reverse engineering.. Are there any online courses which you recommend or do you teach yourselves.

  21. Durexlw says:

    soufiane TAHIRI, thanks man. This was really helpful to me. Very clear explained.

Leave a Reply

Your email address will not be published. Required fields are marked *