This post has been imported from the old blog and has not yet been converted to the new syntax yet.
In my last post I spoke about reverse engineering .NET assemblies upon which Gregory asked how to protect his code against it.

Initially I thought signing an assembly would be the easiest way to prevent this, and my first tests confirmed this. I signed the CrackMe from my previous post and tried modifying it again, unsuccessfully.

Visual Studio - Sign Assembly

After changing the code and saving it, Reflexil gave me several options. Adding it to the verification list, resigning it, or leaving it as is.

Reflexil - Save Tampered Assembly

None of the options proved to be usable for the following reason:

  • Adding it to the verification list.
    This won't work with fully signed assemblies. Shawn Farkas explained long ago why this doesn't work. The solution proposed doesn't work if we don't have the original key used to sign the file.
     

  • Resigning it.
    Logically this doesn't work, since we don't have the original key.
     

  • Leaving it as is.
    When trying to run the modified assembly, an exception will be thrown, preventing it from running.


FileLoadException Tampered Assembly

It seems we managed to protect our code, doesn't it? But we didn't!

I started thinking, since we can easily decompile an assembly, it couldn't be that hard to remove the signature and make it pass all checks again. After playing around with ildasm (Found at: Visual Studio - SDK - v2.0 - Bin) and ilasm (Found at: Microsoft.NET - Framework - v2.0.50727) for a while, my suspicions got confirmed. I managed to run the altered, now unsigned, assembly on my computer, defeating code signing.

This process wasn't error proof however, making round trips through ildasm and ilasm didn't always recreate the original assembly correctly. But why make the round trips in the first place? Why not edit the assembly directly, only removing the signature, instead of having to decompile and recompile the entire code.

A Google search quickly led me to the answer. This code project article describes code signing in great detail and provides a very nice utility to remove the strong name from an assembly, while also keeping into account referencing assemblies.

Using the tool on my CrackMe removed the signature without any problem, after which I could simply modify it as if it was an unsigned assembly using the instructions from my previous post.

Strong Name Remove

In conclusion, I'd say code signing offers no protection against others determined to modify your assemblies. It seems to be like copy protections on games, it will stop a certain percentage of people but not everyone. It's another layer in your protection, making it less attractive to others to even bother trying to break your security.

Should you use code signing? Yes, you should, everything helps and applying a strong name also serves other purposes such as solving versioning issues when using the Global Assembly Cache.

In my next post I'll take a look at another mechanism to protect your code from tampering, obfuscation.

This post is the second in a series on protecting intellectual property.
 
Comments: 4
 
  • Be careful, when removing the strong name of an assembly 'foo.dll', you need to patch all assemblies referencing 'foo.dll' (in order to update the public key token). Your 'CrackMe' sample works fine because you are patching the main executable, but if your protection logic was in a class library DLL you have to update both the DLL (removing the strong name) and the EXE (updating the reference).

     
     
  • The 'Strong Name Remove' tool does this as well :)

     
     
  • "In conclusion, I’d say code signing offers no protection against others determined to modify your assemblies."

    Well, that's because strong signing isn't intended to prevent reverse engineering or stop people from modifying your assemblies. It exists primarily to prevent secret and malicious changes to redistributable libraries that could be blamed on the original library author.

     
     
  • Thanks, works really great.

     
     
  • Leave a reply
    Items marked with * are required. (Name, Email, Comment)
    Comment is missing some required fields.
     
     
     
    To make sure you are not a computer, please type in the characters you see.