Code Signing as Reverse Engineering Protection

In my last post I spoke about 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. a very nice utility">This code project article describes code signing in great detail and provides <a href=" "Strong Name Remove") 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.