20 Feb 2015

String decryption with de4dot

Introduction

de4dot is a wonderful tool for deobfuscating known and unknown .NET protections. Dealing with known and supported protections is easy - drag&drop executable on de4dot and it will create deobfuscated assembly. Removing unknown protections is a little bit harder and requires supplying correct command-line parameters to de4dot.

In this article I'll show how de4dot can be used to deobfuscate strings in almost any .NET assembly, some undocumented features of de4dot, and a few bugs in de4dot too. smile

Basics of string encryption/decryption

To show how string encryption works, let's start with a simple C# program.

Hint - you don't have to copy-paste all the code, sample files are available in the archive at the bottom of the post.

As you can see, all the strings are in the clear view and it's obvious that correct password is "secret". No protection whatsoever.

To slow down reversing efforts, obfuscators offer to encrypt user strings. They locate all strings in assembly, encode them somehow, and replace access to string with call to obfuscator code. To keep the code simple, I'll just encode all strings using Base64 - however, the same approach would work for almost any string encryption method (xor, Rijndael, or anything else).

New code looks like this:

No more obvious strings! smile Let's see how we can decrypt them using de4dot..

de4dot and basic string decryption

If you check de4dot help, you'll see that you need to supply 2 command line options for a string decryption to work. First, you need to choose a string decrypter type using --strtyp option: static, delegate, emulate. Then you need to tell de4dot which is string decrypter method using --strtok option.

Let's find which method is responsible for string decryption. Good decompiler can show method tokens, for example, SAE shows it as a tooltip, when you hover over the method:SAE method token

So, for our very basic protection we could run de4dot with commandline:

and the result will look like this:
decompiled cleaned file
So far, so good!

Advanced string decryption

But what happens if obfuscator uses more than one string decryptor? Let's change the code a little bit:

Now there are 3 methods that decrypt strings, and each of them is slightly different. Of course you could run de4dot 3 times, but it's just a pain-in-the-butt.

de4dot help doesn't tell you this, but it is possible to to specify more than one string decryption method:

This is a little bit awkward, but works.

But what to do if there are hundreds of methods - specifying each of them by token is time-consuming and command-line might get too long.

de4dot has solution for that too. Hidden in the middle of help file, is this little gem:

--strtok METHOD String decrypter method token or [type::][name][(args,...)]

It turns out that you can tell de4dot the name of obfuscator class/methods responsible for string decryption and it will resolve tokens automatically. smile

So, the following command-lines will work:

  •  
    This tells de4dot that string decryptor is method with full name Demo.Obfuscator::DecryptString.
  •   This tells de4dot to check all methods in class Demo.Obfuscator and pick the ones which look like string decryptors.
  •   This tells de4dot which class to look at and what kind of parameters string decryption method has.
  •   This tells de4dot to look at all classes for a method called DecryptStringA and use that as string decryptor.

If you want to know more about possible options and the combinations, I suggest that you look at de4dot source code, file de4dot.code\ObfuscatedFile.cs, lines 454-511.

You said something about bugs?

Ok, ok, there are few issues here.. It still works 99% of the time, so no complaining!

First bug is in the checking of string decryptor parameters. When I said that --strtok "Demo.Obfuscator::(System.Int32)" will select only methods that take Int32 as a parameter, I lied. smile

Look at the source:

The continue instruction here does nothing, it just goes on to check next parameter. I guess 0xd4d wanted to stop evaluating this method and go to next one, but got it wrong.

Second bug is in selecting string decryptors - you cannot select a method which takes no parameters. Sample code showing this type of protection is in hello-4.cs (see below).

Look again at the source:

If you don't supply hints about parameters, then methods with 0 parameters will be ignored because of 2nd if. If you do supply hints - then no method with 0 parameters can pass the 3rd if.

Fixing these 2 bugs is left as an exercise to the reader.

Conclusion

In this article explained how to use de4dot to decrypt strings in any .NET assembly, including some lesser known options. Hope this helps you next time you encounter .NET protection that's not directly supported by de4dot. smile

All sample files and their source code: https://www.mediafire.com/?2kwnf7d7vre4uv8

19 thoughts on “String decryption with de4dot

    • It is a very old blog post from year 2015 and de4dot has been improved a lot since then. I think the bugs are already fixed - but I haven't checked..

      • The official repo is inactive now. 0xd4d begins to use undocumented Preprocessor Directive in his code. I think he is getting old.

        • The official repo is still active, last commit was 3 days ago.

          I can see that 0xd4d has moved to Visual Studio 2017, .NET Core other "modern" stuff. I'm not a big fan of that.

  1. --strtok METHOD String decrypter method token or [type::][name][(args,...)]

    This doesn't seem to support other assemblies though. Say for example we have a main EXE and a DLL
    The DLL contains the string decryption method, so throwing it through de4dot works well.
    However the EXE calls the same method, but you cant specify the decryption method in a different method.
    Or am i being stupid here?

    • I think you're right, de4dot only supports calling methods from the same module.

      I have never seen such protection before but I think it would be an easy thing to fix. Can you upload the files to mega.co.nz or mediafire.com and send me the link? I'd like to take a look at it.

      • Hi
        I have a problem to deobfuscate this file.
        {hidden link}
        I get this error:

        de4dot v3.1.41592.3405

        Detected SmartAssembly 7.4.0.3402 (C:\Release\net45\B.dll)
        Cleaning C:\Release\net45\B.dll
        Renaming all obfuscated symbols
        Saving C:\Release\net45\B-cleaned.dll
        ERROR: Method System.Reflection.Assembly .::(System.Object,System.ResolveEvent
        Args) (060001A0) is not defined in this module (Bexel.Licensing.Common.dll). A m
        ethod was removed that is still referenced by this module.

        And program not work.
        {hidden link}

        • SmartAssembly has changed few things and now de4dot is not able to unpack it properly. You will need to update de4dot to make it work.

          But that has nothing to do with this blogpost.

          • thank you for attention
            how i can update it?
            i build from final source with vs2019 but is cant deobfuscate it yet.
            maybe some option must be added?

  2. I'll say it again - someone needs to analyze the new SmartAssembly, find all the changes and then update de4dot code. It's a hard work.

  3. string path = Environment.GetFolderPath(Environment.SpecialFolder.System) + Encoding.UTF8.GetString(Convert.FromBase64String(Encoding.UTF8.GetString(Convert.FromBase64String(Encoding.UTF8.GetString(Convert.FromBase64String(Encoding.UTF8.GetString(Convert.FromBase64String("VjBWa1UyVlhSbGxYYlhocVltczFhbGRzYUZOaGJHaElZVWhhYWsweFNqWT0="))))))));

    I have followed the instructions many times but I can't solve the type I mentioned above, please help

Leave a Reply

  • Be nice to me and everyone else.
  • If you are reporting a problem in my tool, please upload the file which causes the problem.
    I can`t help you without seeing the file.
  • Links in comments are visible only to me. Other visitors cannot see them.

Your email address will not be published.

 −  1  =  0