mkaring / ConfuserEx

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

Serializing with Newtonsoft breaks application #421

Closed hitgubmitt closed 2 years ago

hitgubmitt commented 2 years ago

Steps to Reproduce:

I obfustacted the code below with this crproj:

<project outputDir="outputDir" baseDir="baseDir" seed="seednumber" xmlns="http://confuser.codeplex.com">
  <rule pattern="true" inherit="false">
    <protection id="ctrl flow" />
    <protection id="rename" />
  </rule>
  <module path="ConfuserTests.exe" />
</project>

Obf.cs

using System.Reflection;
using Newtonsoft.Json;

namespace ConfuserTests
{
  [Obfuscation(Exclude = true)]
  public class Obf
  {
    [JsonProperty("a")] public string a;

    [JsonProperty("b")] public string b;

    [JsonProperty("c")] public string c;

    public Obf(string a, string b, string c){
      this.a = a;
      this.b = b;
      this.c = c;
    }

    public override string ToString(){
      return JsonConvert.SerializeObject(this);
    }
  }
}

Program.cs

    public static void Main(string[] args){

      try{
        Obf a = new Obf("a","b","c");
        string obfstring = a.ToString();
        Console.WriteLine(obfstring);
      }
      catch (Exception e){
        Console.WriteLine(e);
      }

      Console.ReadLine();
    }

This code triggers an error:

Newtonsoft.Json.JsonSerializationException: A member with the name '' already exists on 'ConfuserTests.Obf'. Use the JsonPropertyAttribute to specify another name.
   at Newtonsoft.Json.Serialization.JsonPropertyCollection.AddProperty(JsonProperty property)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   at Newtonsoft.Json.JsonConvert.SerializeObject(Object value)
   at ConfuserTests.Obf.?????????????????????????????????????????() in C:\path\ConfuserTests\Obf.cs:line 25
   at ?????????????????????????????????????????.?????????????????????????????????????????(String[] ) in C:\path\ConfuserTests\Program.cs:line 11

As you can see, serialization breaks application. Even with [Obfuscation(Exclude = true)] attribute on the Obf class. What is the recommended way to achieve obfuscation when using json serialization via newtonsoft?

Thanks

vincenthawke commented 2 years ago

I replicated the problem and wish to learn how to fix it as well. It seems that the biggest issue here is not only that ConfuserEx can't handle serialization yet, but that it won't obey the flags that are supposed to tell it what not to obfuscate, but it goes ahead and still does it.

I tried at assembly level [assembly:ObfuscateAssemblyAttribute(true)] at individual methods [ObfuscationAttribute(Exclude=true)] and classes [ObfuscationAttribute(Exclude=true, ApplyToMembers=true)] None worked and the code example still got obfuscated. Am I using them wrong? I followed the official MS guide: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.obfuscationattribute?view=netframework-4.6.1

BarehSolok commented 2 years ago

[Obfuscation(Exclude = true)] wouldn't work you should use [Obfuscation(Exclude = false, Feature="-typescramble;-rename;-anti debug")] the string inside Feature is the feature you want to exclude for the type in ConfuserEx

@vincenthawke the only supported annotation is [Obfuscation(Exclude = false, Feature="-feature")]

mkaring commented 2 years ago

Okay, so there is a problem here for sure. Excluding the class from protection is done correctly in your example @hitgubmitt. So that should work.

Fixing it on your end can be done by marking your Obf class with the Newtonsoft.Json.JsonObjectAttribute. ConfuserEx will detect this any this will resolve the issue.

I'm investigating why ConfuserEx isn't handling the [Obfuscation(Exclude = true)] attribute correctly.

mkaring commented 2 years ago

The issue why the [Obfuscation(Exclude = true)] does not take it identified and will be fixed with the referenced pull-request.

mkaring commented 2 years ago

@hitgubmitt: You'll find a build that resolves the bug with the exclude attribute here on the buildserver.

github-actions[bot] commented 2 years ago

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.