mkaring / ConfuserEx

An open-source, free protector for .NET applications
https://mkaring.github.io/ConfuserEx/
MIT License
2.33k stars 362 forks source link

Suggestion: Expression Cipher for Constants #109

Open ElektroKill opened 4 years ago

ElektroKill commented 4 years ago

Hello, I’ve looked at ConfuserEx and I think I have a possible feature idea.

In DynCipher there is a method for generating expression pairs. It’s already used in ref proxy’s shown here: https://github.com/mkaring/ConfuserEx/blob/4ed6ae1a5cc6a639df3d873c492dc3005ad66603/Confuser.Protections/ReferenceProxy/ExpressionEncoding.cs#L29

I suggest that this can be used to generate cipher code in here instead of the static instructions: https://github.com/mkaring/ConfuserEx/blob/4ed6ae1a5cc6a639df3d873c492dc3005ad66603/Confuser.Protections/Constants/DynamicMode.cs#L49

mkaring commented 4 years ago

I had a look at this and I think I found a good solution.

There are two parts to the constants expression:

  1. The encryption of the binary data block that contains the constants
  2. The decoding of the constants from the decrypted binary data

Currently there are three modes and they use different methods for decrypting and decoding.

  1. Normal Mode: Static CIL code for decrypting and decoding
  2. Dynamic Mode: DynCipher CIL code for decrypting, static code for decoding
  3. x86 Mode: DynCipher CIL code for decrypting, DynCipher x86 code for decoding

The performance impact that needs to be considered, is that the decryption happens once during the runtime of the application, the decoding happens every time a constant value is requested.

To serve all needs I'll split the configuration for the decryption and the decoding. For either I'll allow to set the following options:

  1. Pass-through: No encryption/encoding - use plain values
  2. Normal: Use a simple static encryption/encoding - matches the current "normal mode"
  3. Dynamic: Generate a dynamic CIL expression using the DynCipher
  4. x86: Generate a dynamic x86 method using DynCipher

No matter the option selected for the encryption part, the compression options will take affect.

mkaring commented 4 years ago

After some more thinking about this, I'll drop the "normal" mode. All it adds is more code that needs to be maintained. It's runtime performance matches the dynamic mode with an expression depth of 2, but it's always the same two operations instead of random operations that are provided by the dynamic mode.

ElektroKill commented 4 years ago

The normal mode is too simple, but a lot of cfex tools only support normal mode. Removing it would help improve the obfuscation strength for people that don’t use project and just add protections from GUI. I think ideally the modes should be like this:

Initial data decryption should have dynamic mode and for the Placeholder in the get method either the expression or the x86 generated method should be used.

This would prevent some of the simplest static ConfuserEx tools from working. In order to prevent some of the more complex tools the suggestions from my other issue (#111) could be implemented. These changes would prevent most of the static and basic tools from working. However it would not prevent tools that rely on emulation.