Auto Obfuscation on Build

This should actually be two blog posts. The first on obfuscation (and whether or not it works) and another on command line arguments for build.  But, I am being lazy. 😉


I got into a discussion in the Microsoft groups the other day about obfuscation. The OP (Original Poster) stated:

I’ve got some code contained in a component in a dll that I want to protect
against reverse engineering – but I’ve never done anything like that before,
so I’m wondering a few things:
1) What brand of obfuscation software provides best protection at a
reasonable cost? Have you got any recommendations?
2) If I obfuscate the dll containing the component, will it still be
possible to add the component to the VS toolbox and use it in projects that
are not obfuscated or perhaps obfuscated using a different tool?
3) Does addind the "DebuggerHidden" attribute to the critical code sections
protect anything at all?`

One of the posters responded:

The only way to stop people reverse engineering your assemblies is not to
let them have them.  Put the critical stuff on a webservice or something.
If this is not possible then just accept that it is entirely possible to
read your source code using something like Reflector.

For the record, there are good and bad obfuscators out there. True, you cannot completely protect your code from a serious hacker, but you can make it very hard. True, the built in obfuscator will not stop anyone from using Reflector and getting your code, as it is just a symbol renaming tool. There are, however, some good obfuscators.

One I particularly like is CodeVeil, although what I describe here can be done with any of the obfuscators on the market that has a command line version of the tool. I think that pretty much describes them all, although I could be wrong.


In Visual Studio, go to the properties for your project. One easy way is via the right click menu in Solution Explorer.


Click on the Build Events tab


and add the following to your post-build event command line box:

"C:Program FilesXHEOCodeVeilv1.0cve.exe" /ox+ /er+ /es+ /er+ $(TargetPath)

When you run this you should see the following on your output for your build (I have obfuscated out the licensing information for CodeVeil (the ####s):

Compile complete — 0 errors, 0 warnings
MyCompany.ClassLibrary -> C:projectstestMyCompany.ClassLibrarybinDebugMyCompany.ClassLibrary.dll
"C:Program FilesXHEOCodeVeilv1.0cve.exe" /ox+ /er+ /es+ /er+ C:projectstestMyCompany.ClassLibrarybinDebugMyCompany.ClassLibrary.dll
copy C:projectstestMyCompany.ClassLibrarybinDebug\VeiledMyCompany.ClassLibrary.dll C:projectstestMyCompany.ClassLibrarybinDebugMyCompany.ClassLibrary.dll
rmdir /s /q C:projectstestMyCompany.ClassLibrarybinDebug\Veiled

XHEO|CodeVeil Assembly Encoder v1.0
Copyright (C) 2002-2006 XHEO INC. All rights reserved.

Licensed to:

Processing C:projectstestMyCompany.ClassLibrarybinDebugMyCompany.ClassLibrary.dll.
Resolving Rules..
Saving modified assembly.
        1 file(s) copied.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

I am currently in the process of trying to get rid of the Veiled directory:

"C:Program FilesXHEOCodeVeilv1.0cve.exe" /ox+ /er+ /es+ /er+ $(TargetPath)
copy $(TargetDir)Veiled$(TargetFileName) $(TargetPath)
rmdir /s /q $(TargetDir)Veiled

But I am having a hit or miss time. Perhaps adding a little time for the compiler to let lose of the target file is in order?

Does the obfuscator actually prevent decompilation?

This is a question on most people’s minds at this point in time. So, I am going to take a project from work and open in Lutz Roeder’s Reflector and explore the file. In this case, I am looking at a Response object. The GIF quality is not great, but much smaller:


Notice that there is heavy symbol renaming, and when I attempt to reverse engineer the code, I end up with the following:


What about ILDASM:


Double clicking on this method ends up with the following IL:

.method private hidebysig static valuetype Microtrak.Kore.Enumerations.SmsRatePlan
        a(string b) cil managed
  // Code size       59 (0x3b)
  .maxstack  8
  IL_0000:  ldarga.s   148 // ERROR: invalid arg index (>=2)
  IL_0002:  br.s       IL_0063
  IL_0004:  unused
  IL_0005:  sub
  IL_0006:  unused
  IL_0007:  isinst      [ERROR: INVALID TOKEN 0x1F3A95CA]
  IL_000c:  stelem.ref
  IL_000d:  unused
  IL_000e:  unused
  IL_000f:  shr
// Error: no section header for RVA 0x18f1f, defaulting to empty string
  IL_0010:  ldstr     
  IL_0015:  nop
  IL_0016:  nop
  IL_0017:  unused
  IL_0018:  ldarga.s   148 // ERROR: invalid arg index (>=2)
  IL_001a:  br.s       IL_007b
  IL_001c:  unused
  IL_001d:  sub
  IL_001e:  unused
  IL_001f:  castclass   [ERROR: INVALID TOKEN 0x1F3A95CA]
  IL_0024:  stelem.ref
  IL_0025:  unused
  IL_0026:  ldelem.r8
  IL_0027:  stloc.s    V_18
  IL_0029:  ldind.i
  IL_002a:  ldc.i4.5
  IL_002b:  ldelem      [ERROR: INVALID TOKEN 0x05EA1D87]
  IL_0030:  ldc.i4.7
  IL_0031:  unused
  IL_0032:  conv.ovf.u8.un
  IL_0033:  break
  IL_0034:  ldc.i4.7
  IL_0035:  ldind.u2
  IL_0036:  calli      0x0A1D8723 // ERROR: invalid token type
} // end of method Response::a

Notice the errors in the IL. These do not prevent the code from running. All of my tests are fine:


What about the RemoteSoft Salamander decompiler. It is, by their own press, the best on the market. How does the obfuscated assembly fare?


Once again, we won.

Realize that a very committed individual will eventually get your code. It will take quite a bit of work, however. Two things to make this even harder:

  1. Make your public members stubs (see point 2)
  2. Move the code that contains your algorithms into private methods. Make sure to refactor the code from public members here.
  3. Encrypt strings, resources and blobs whenever possible before obfuscating

Hope you had fun with this one.

Peace and Grace,


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: