Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the strongest protection settings without triggering anti-virus false positives? #64

Closed
glasgowrob opened this issue Jul 24, 2019 · 6 comments

Comments

@glasgowrob
Copy link

Hello mkaring, Hello fellow ConfuserEx fans,

I am trying to obfuscate my WPF/C# desktop application as much as possible using mkaring's ConfuserEx, but without triggering anti-virus false positives when I release my beta version in a couple of months.

1. What advice can you give someone like me, who is trying to find a "good balance" between the strongest possible obfuscation and not triggering anti-virus false positives?

2. What protections should I turn off in my .crproj file to accomplish this?

So far I have turned off the following:

Protection 1 I turned off: "anti tamper". Reason: because lots of people (including mkaring) in lots of issues across all 3 ConfuserEx branches have mentioned that "anti tamper" is the worst for anti-virus triggering.

Protections 2 and 3 I turned off: "anti dump" and "invalid metadata". Reason: Because without turning off these 2 protections as well, my exe is unverifiable via PEVerify, which I run using the following command at the Visual Studio 2019 command prompt:

peverify "<File Path to My Obfuscated Exe>"

I've seen some ConfuserEx issues where people suggest making sure that one's obfuscated executable is verifiable, so to accomplish this I had to turn off all 3 protections mentioned above, and avoid any "<argument>" name-value pairs that the ConfuserEx documentation mentions "produce unverifiable modules".

3. Do you think that my choices of turning off the three protections mentioned above ("anti tamper", "anti dump", "invalid metadata") were good ones, or would you recommend turning off a different set of protections?

I hate to turn off "anti tamper" because I love how it removes the code from my methods (!!!) (sorry nosy competitors!) without breaking my application and maybe would stop hackers from being able to remove the licensing code (which I am sure is easy to find somehow), and I hate to turn off "anti dump" and "invalid metadata", because I want the most protection possible.

4. Should I turn off ConfuserEx features that make each build a little different than the last, so that anti-virus companies don't think that each new version is a completely different piece of software with potential for new threats?

Some examples of this include:

  1. renaming changes the names every time

  2. I use "resources" protection, which I think I read in another issue somwhere might produce different results each time, but I am not sure.

Thank you so much!

glasgowrob

@mkaring
Copy link
Owner

mkaring commented Jul 25, 2019

Hello,

in general I'd recommend to enable the protections you want, with the options you want to use.

There are lot of protections with different levels of impact on your application. Real world projects always require some tweaking to get working properly, because usually you need to enable and disable the configurations for different parts of your assemblies.

As for the protections:

  1. AntiTamper: This protection is actually just what is says it is. It's a protection that ensures that the assembly is not altered. The side effect of this protection is that all the method bodies become invisible. How ever when debugging into the protected code with for example dnspy, you'll get the method bodies pretty easily. There are two modes to this protection. The mode "normal" and the mode "JIT". The latter is a broken mess and I strongly suggest to not use it.
    The protection is (in "normal" mode) sometimes detected as a false positive malicious application. It provides a weak protection from people wanting to look at your code.
  2. Constants: This protection hides away constant values. It can protect strings (default), numbers, primitives and initializers (default). It basically encodes the value that is used for the initialization. Be aware that it can't protect const values, as those can't be populated by a function. All others are populated. The protected values can be uncovered by debugging, how ever analyzing the assembly get's much harder, because you can't search for specific strings for example.
    This protection has the modes "normal" (default), "dynamic" and "x86". I recommend setting it to "x86", because this implements the actual decoder with native code. If you can't use native code, use the "dynamic" mode. The "normal" mode is very easily reversed by some applications that are out there. I'm not aware of any case where this protection was detected by a anti-virus application.
  3. Control Flow: The control flow obfuscation basically splits the code in pieces, rearranges it in the function and implements a very large switch block or a lot of jump statements to restore the actual flow of the application. This works best on large functions that can be split many times. The part of the obfuscation that takes care of "selecting the next block" in a obfuscated function, can be implemented in different ways. There is the "normal", the "expression" and the "x86" method. Again I suggest using "x86" if possible. If not either of the others is fine.
    This protection can be undone if the attacker follows the control flow the application with the debugger or in case the predicate method is decoded and the attacker is able to calculate the next block. I'm not aware of any case where this protection was detected by a anti-virus application.
    That is unless you got yourself a method that calls a lot of native functions (using Marshalling). Such methods are at times detected. I recommend disabling this protection for functions contains a lot of native calls.
  4. Reference Proxy: This protection basically hides all calls to functions inside another function. The "normal" mode doesn't help much, but makes it much more strenuous to read the code. This mode is never detected by a anti virus application. The "strong" mode is much more interesting. It hides the method code and some additional memory block and uses a decoder function to read it and create a dynamic method that contains the original code. This is very hard to follow, because you will not see the code in the debugger (at least I don't know how). This mode how ever is sometimes detected as malicious.
  5. Resources: This protection encodes the embedded resource files (mostly the ones created by *.resx files. This only works fine in case the resource is accessed using the generated code that accompanies the *.resx file. In case you got a assembly where you directly work with the resource file or in case you need to use the resource file across assemblies, I suggest disabling this protection.
  6. AntiIDasm: Can be enabled without and worry. It simply sets a flag that says "please don't deobfuscated me". I think ILSpy honored this flag (once).
  7. AntiDebug: Depending on the mode this protection adds some codes to the assembly that makes it impossible to attach the debugger. This should only be added to the main executables. The code does nothing in normal operation, but it turns any attached debugger either inoperable or very glitchy. It works well together with other protections that can be reversed with the debugger, to make things harder. But it's fairly easy using a msil editor to get rid of the code that break the Debuggers.
  8. AntiDump: Works similar to AntiDebug, it tries to block memory dumping of the application memory. I usually don't use this, because it prevents minidumps to be created on the customer system.
  9. Invalid Metadata: Adds some buggy metadata to the classes and methods that cause some decompilers to break. This also causes massive issues in case you are trying to compile an application referencing an assembly protected with this.
  10. TypeScambler: Some versions of ConfuserEx contain this. Don't use it. It's broken.
  11. Rename: The renamer is the big bad among the protections. This protection is the only truly irreversible one and also the one that requires the most fine tuning. ConfuserEx tries to set it up right for you, but in some cases it needs to be disabled for parts of an application. Mostly in case the application accesses specific classes a lot with reflections by name.
  12. Compress packer: The compress packer is the part that combines multiple assemblies into one. This is detected as malicious code very often.

To create the same result every time you can set the seed to a fixed value, but this will not help you with the anti virus application. These applications will always scan your application. You should upload your application to virus total to check if it's detected as virus.

In general I recommend to use:

  1. AntiTamper
  2. Constants
  3. Control Flow
  4. Reference Proxy
  5. Resources
  6. AntiIDasm
  7. Rename

You have to setup the pattern and options so especially the WPF bindings (in case they are written using WPF) are not broken. So you may have to disable it for some classes. Just enabling these protections for everything usually does not result in a working output. So try to disable protections for part of your application where they cause error. That can be done in the *.crproj file or in the code using the ObfuscationAttribute

So the answer "what is the strongest protection" is very difficult to answer, because it very much depends on your application.

Have fun hiding your stuff,
Martin

@glasgowrob
Copy link
Author

Hi Martin,

I just read your excellent answer on the way out the door for a long weekend and I am very much looking forward to trying your suggestions Tuesday or Wednesday of next week when I am back in the office. I will report back with a post to this thread at that time.

Your answer will help a lot of newbies like me who are looking for good advice on this extremely important topic.

Thank you!

glasgowrob

@glasgowrob
Copy link
Author

Hi Martin,

Thank you again for your invaluable advice. I went through all of it today and tried everything, and used a lot of the specific things you suggested with excellent results.

Here are a handful of specific comments on your advice and how I used it, in case you have any additional comments on my potentially faulty rationale:

  1. I am going to turn on Anti-Tamper (in "normal" mode), even though some people have mentioned that it can cause anti-virus false positives, and I will submit my application to virustotal before I make my beta publicly available. I am going to inquire on the pricing of their private service, called Virus Monitor, at [https://www.virustotal.com/gui/monitor-overview], since it sounds even better than their free public service, although since no prices are listed, it might be "priced for large company budgets", in which case I will just use their public service.

  2. I will make sure that my renaming is particularly good, since it is not reversible.

  3. I won't use a compressor to avoid getting flagged by anti-virus software.

4. I deviated from your list of 7 protections that in general you recommend in 3 ways:

4A. I turned on "AntiDebug", because even though "it's fairly easy using a msil editor to get rid of the code that break the Debuggers", I figure I would keep it turned on if it is better than nothing. Maybe it would stop a couple of my laziest competitors from debugging my application.

4B. I turned on "AntiDump", because I decided that I won't need mini-dumps from my customers' computers.

4C. I turned on "Invalid Metadata" because I am only protecting the main executable of a desktop app, not an assembly that will ever be referenced by another assembly.

Is my rationale for my choices faulty in any way?

Thank you again for all of the help!

glasgowrob

@glasgowrob
Copy link
Author

I am closing this issue because after working with mkaring's ConfuserEx a lot in the last few weeks, I have learned a lot about it and have become more comfortable with my decisions in my previous post and have decided that they do in fact make sense.

@GazziFX
Copy link

GazziFX commented Dec 21, 2020

I think use https://github.com/dotnet/runtimelab/tree/feature/NativeAOT will be better for you and should not be triggered by AVs. If you can make at least string encryption work with this, it will be really strong protection. But you'll have to use .NET Core

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants