XenocodeRCE / neo-ConfuserEx

Updated ConfuserEX, an open-source, free obfuscator for .NET applications
http://yck1509.github.io/ConfuserEx/
Other
746 stars 89 forks source link

When to support .net5 #66

Open ni-xue opened 3 years ago

ni-xue commented 3 years ago

Is your feature request related to a problem? Please describe. Nothing to do with the problem.

Describe the solution you'd like I hope to provide support for .net5, I need to confuse the function very urgently.

Describe alternatives you've considered .NET Reactor Not in the expected results.

Additional context nothing.

nathan-chappell commented 2 years ago

For anyone who cares, I've been able to get neo-ConfuserEx to work with a .net5 project by applying the following changes:

  1. Set the EnableFrameworkRedirect to false when the AssemblyResolver is constructed (in Confuser.Core/ConfuserEngine.cs: line 88)
  2. Catch some exceptions in the ReferenceProxy MildMode protections (in Confuser.Protections/ReferenceProxy/MildMode.cs: line 17)

(See git diff below)

(2) is only necessary because the resolver failed to find:

It seems that these are located in the assembly Microsoft.Extensions.DependencyInjection.Abstractions.dll and not Microsoft.Extensions.DependencyInjection.dll, which I believe is what is confusing the resolver. I didn't care enough about this protection to determine a way to fix it.

I also needed to put a probepath where I have the dotnet SDK references installed (in the .crproj file):

Here is the diff of changes I made for this workaround (don't forget to do your own probePath stuff)

diff --git a/Confuser.Core/ConfuserEngine.cs b/Confuser.Core/ConfuserEngine.csindex fcf6309..a26cec1 100644
--- a/Confuser.Core/ConfuserEngine.cs
+++ b/Confuser.Core/ConfuserEngine.cs
@@ -88,6 +88,7 @@ public static class ConfuserEngine {
                var asmResolver = new AssemblyResolver();
                asmResolver.EnableTypeDefCache = true;
                asmResolver.DefaultModuleContext = new ModuleContext(asmResolver);
+               asmResolver.EnableFrameworkRedirect = false;
                context.Resolver = asmResolver;
                context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, parameters.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + "." + Path.DirectorySeparatorChar);
                context.OutputDirectory = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
diff --git a/Confuser.Protections/ReferenceProxy/MildMode.cs b/Confuser.Protections/ReferenceProxy/MildMode.cs
index fcc50f4..e272c35 100644
--- a/Confuser.Protections/ReferenceProxy/MildMode.cs
+++ b/Confuser.Protections/ReferenceProxy/MildMode.cs
@@ -17,8 +17,16 @@ internal class MildMode : RPMode {
            if (target.DeclaringType.ResolveTypeDefThrow().IsValueType)
                return;
            // Skipping visibility is not supported in mild mode.
-           if (!target.ResolveThrow().IsPublic && !target.ResolveThrow().IsAssembly)
+           try
+           {
+               if (!target.ResolveThrow().IsPublic && !target.ResolveThrow().IsAssembly)
+                   return;
+           }
+           catch
+           {
+               Console.WriteLine($"ReferenceProxy.MildMode.ProcessCall exception resolving: {target.FullName}");
                return;
+           }

            Tuple<Code, TypeDef, IMethod> key = Tuple.Create(invoke.OpCode.Code, ctx.Method.DeclaringType, target);
            MethodDef proxy;
RobsonRojas commented 1 year ago

For anyone who cares, I've been able to get neo-ConfuserEx to work with a .net5 project by applying the following changes:

  1. Set the EnableFrameworkRedirect to false when the AssemblyResolver is constructed (in Confuser.Core/ConfuserEngine.cs: line 88)
  2. Catch some exceptions in the ReferenceProxy MildMode protections (in Confuser.Protections/ReferenceProxy/MildMode.cs: line 17)

(See git diff below)

(2) is only necessary because the resolver failed to find:

  • Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions::CreateScope(System.IServiceProvider)
  • Extensions.DependencyInjection.IServiceScope::get_ServiceProvider()

It seems that these are located in the assembly Microsoft.Extensions.DependencyInjection.Abstractions.dll and not Microsoft.Extensions.DependencyInjection.dll, which I believe is what is confusing the resolver. I didn't care enough about this protection to determine a way to fix it.

I also needed to put a probepath where I have the dotnet SDK references installed (in the .crproj file):

  • C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0

Here is the diff of changes I made for this workaround (don't forget to do your own probePath stuff)

diff --git a/Confuser.Core/ConfuserEngine.cs b/Confuser.Core/ConfuserEngine.csindex fcf6309..a26cec1 100644
--- a/Confuser.Core/ConfuserEngine.cs
+++ b/Confuser.Core/ConfuserEngine.cs
@@ -88,6 +88,7 @@ public static class ConfuserEngine {
              var asmResolver = new AssemblyResolver();
              asmResolver.EnableTypeDefCache = true;
              asmResolver.DefaultModuleContext = new ModuleContext(asmResolver);
+             asmResolver.EnableFrameworkRedirect = false;
              context.Resolver = asmResolver;
              context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, parameters.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + "." + Path.DirectorySeparatorChar);
              context.OutputDirectory = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
diff --git a/Confuser.Protections/ReferenceProxy/MildMode.cs b/Confuser.Protections/ReferenceProxy/MildMode.cs
index fcc50f4..e272c35 100644
--- a/Confuser.Protections/ReferenceProxy/MildMode.cs
+++ b/Confuser.Protections/ReferenceProxy/MildMode.cs
@@ -17,8 +17,16 @@ internal class MildMode : RPMode {
          if (target.DeclaringType.ResolveTypeDefThrow().IsValueType)
              return;
          // Skipping visibility is not supported in mild mode.
-         if (!target.ResolveThrow().IsPublic && !target.ResolveThrow().IsAssembly)
+         try
+         {
+             if (!target.ResolveThrow().IsPublic && !target.ResolveThrow().IsAssembly)
+                 return;
+         }
+         catch
+         {
+             Console.WriteLine($"ReferenceProxy.MildMode.ProcessCall exception resolving: {target.FullName}");
              return;
+         }

          Tuple<Code, TypeDef, IMethod> key = Tuple.Create(invoke.OpCode.Code, ctx.Method.DeclaringType, target);
          MethodDef proxy;

These changes would work on .net6?

nathan-chappell commented 1 year ago

@RobsonRojas I've used the obfuscator on .net6 and .net7 assemblies as well. You just have to be willing to go into dnlib and tear out all the hardcoded bullshit, then, in whatever way you please, ensure that it can find the "correct" assemblies. You don't have to point it at the ref assemblies either, I've discovered. A rather straightforward way to have all the correct assemblies in one place is to put a runtime-identifier in your .csproj file (e.g. <RuntimeIdentifier>win-x64</RuntimeIdentifier>). Then all assemblies required for you program will be in the output folder (something like .\bin\Debug\net7.0\win-x64\), and you can tell dnlib to probe in that directory for assemblies, and not everywhere else.

In general, there are some other issues that you might run into using this thing, but I can't give away anymore right now.