使用 .NET Reactor 混淆 C#程序,出现Newtonsoft.Json.JsonSerializationException
具体问题如下:
Newtonsoft.Json.JsonSerializationException: A member with the name ' ' already exists on 'Test.AuthCode'. Use the JsonPropertyAttribute to specify another name.
在 Newtonsoft.Json.Serialization.JsonPropertyCollection.AddProperty(JsonProperty property)
在 Newtonsoft.Json.Serialization.DefaultContractResolver.CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
在 Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType)
在 Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)
在 System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
在 Newtonsoft.Json.Utilities.ThreadSafeStore`2.Get(TKey key)
背景:
1.代码中Config类同AuthCode类相似,他们的实例都有调用ToJson()方法,但Config的实例调用ToJson()方法无误。
解决该问题我使用了“dnSpy”逆向工具
起初我一直在“修改混淆模式 -> 运行程序 -> 报错”这个循环往复,以为是 .NET Reactor 工具的问题。我在这种方式下调试了一天,一直到下午下班,还是没有调试出来。然后,我想反正解决不了,要不先去吃饭,放松下,在放松的工程中总会有拓开的想法,感觉思维进胡同了。后面我就吃饭去了。就在吃饭的时候我想到了一个办法:
将出错位置的代码拷贝到程序起始位置去运行,看看是否报错,如果仍然报错,就拷贝AuthCode类为AuthCode2。然后来逐渐删减里面的代码,直到出现运行正常时候,就定位到具体错误代码行。
最后我按照该方法,果然定位到问题行。原来是AuthCode2的构造函数的访问权限应该为public。
原代码为:
private AuthCode2() { }
改为:
public AuthCode2() { }
那为什么Config类中构造函数为:
private Config() { }
却能正常运行呢? ***目前该问题还不得而知。***但可以知道的是 .NET Reactor 混淆等功能跟原程序中类、方法、属性、字段的访问权限有关系,并且影响其保护输出的exe的结果。
以上虽仍有问题未解决,但“适当放松->拓展思维”的这个Debug的方法确实很好的,这也印证了我在以前的一片随想“解决技术难题思路” 中提到的 排除法, 控制变量法
补充:
在下午调试的时候最终定位的位置如图:

如图,程序时运行到此处由于 变量parameters 中存储的属性名有两个 " "(string类型) 和一个0(int类型)。这个现象让我想起了AuthCode的另有一个三参数的构造函数,如下:
public AuthCode(string account, string computerUniqueID, int usableMonthNumber){}
而Config却只有一个 private权限的无参构造函数。我在想问题是否就出在了构造函数。
本文介绍了在使用.NETReactor混淆C#程序时遇到的Newtonsoft.Json.JsonSerializationException问题,以及如何通过调整类的构造函数访问权限解决。作者分享了在调试过程中采用的“适当放松-拓展思维”策略,成功定位到错误代码行,发现AuthCode类构造函数权限需为public。尽管Config类私有构造函数能正常运行的原因尚未明确,但该案例揭示了混淆工具与代码访问权限之间的关系,对类似问题的解决提供了思路。
5422

被折叠的 条评论
为什么被折叠?



