Search code examples
c#.netjsonobfuscationcrypto-obfuscator

Json.NET and Obfuscation, deserialization not working


I would like to share a solution my team and I discovered to overcome the problem that appears when you try to couple Json.Net and Obfuscation.

My config: VS2013, C#, .NET 4.0, Json.Net 7.0.1, CodeWall/Crypto Obfuscator.

Everything works fine till I obfuscate my code. After that I can't deserialize my json file (that has been serialized correctly!).


Solution

  • Our solution provide a "sort of hacking" of the DefaultSerializationBinder class, that you can simply pick from the source code and modify at will (or provide your custom override of the abstract class SerializationBinder). The problem seems to appear when it tries to discover the correct assembly from the assembly name...here obfuscation won't match the two.

    Here the code of the method you need to rewrite:

    private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey)
    {
        string assemblyName = typeNameKey.AssemblyName;
        string typeName = typeNameKey.TypeName;
    
        if (assemblyName != null)
        {
            // look, I don't like using obsolete methods as much as you do but this is the only way
            // Assembly.Load won't check the GAC for a partial name
            Assembly assembly = Assembly.LoadWithPartialName(assemblyName);
    
            if (assembly == null)
            {
                string partialName = assemblyName;
                var elements = assemblyName.Split(',');
                if (elements.Length > 0)
                {
                    partialName = elements[0];
                }
                // will find assemblies loaded with Assembly.LoadFile outside of the main directory
                Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
                foreach (Assembly a in loadedAssemblies)
                {
                    if (a.GetName().Name == assemblyName || a.FullName == assemblyName || a.GetName().Name == partialName)
                    {
                        assembly = a;
                        break;
                    }
                }
            }
    
            if (assembly == null)
            {
                throw new JsonSerializationException(string.Format("Could not load assembly '{0}'.", assemblyName));
            }
            Type type = assembly.GetType(typeName);
    
            if (type == null)
            {
                throw new JsonSerializationException(string.Format("Could not find type '{0}' in assembly '{1}'.", typeName, assembly.FullName));
            }
    
            return type;
        }
        else if (typeName != null)
        {
            return Type.GetType(typeName);
        }
        else
        {
            return null;
        }
    }
    

    I hope this can help!

    Please fell free to share your ideas and other tests are welcome!