Как мне поддерживать совместимость с десериализацией в обфускированных и отладочных сборках?

StackOverflow https://stackoverflow.com/questions/514332

Вопрос

Я пытаюсь заставить {smartassembly} .СЕТЕВОЙ обфускатор работать с моей системой.В настоящее время я храню пользовательские данные в серии сериализованных классов словаря, а затем десериализую эти классы, чтобы получить данные обратно.Я уже игнорирую информацию о версии сборки, просто потому, что таким образом усложняю жизнь.Этот код является адаптировано из MSDN:

//to avoid cross-versioning problems
public sealed class CrossVersionDeserializationBinder : SerializationBinder {
    public override Type BindToType(string assemblyName, string typeName) {
        Type typeToDeserialize = null;

        typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
            typeName, assemblyName));

        return typeToDeserialize;
    }
}

Проблема в том, что теперь мое запутанное приложение будет игнорировать информацию о версии, но не сможет прочитать данные, сохраненные не запутанным приложением, и наоборот.Нам понадобится версия без обфускации, чтобы отлаживать приложение, так что для нас это довольно большая проблема.Есть какой-нибудь способ обойти эту проблему?Должен ли я просто не запутывать классы данных?Это похоже на довольно большую брешь в системе безопасности.

Это было полезно?

Решение

Возможно, рассмотрите сериализатор, который не привязан к типу и именам полей?Например, protobuf-сеть является двоичным сериализатором, но использует числовые теги, установленные (через атрибут) для каждого элемента.Это означает:

  • сериализация вообще не привязана к версии сборки
  • информация об имени поля отсутствует в сериализованном файле
  • (исходя из вышесказанного) не будет иметь значения, является ли код запутанным
  • (и) файл не может быть использован для тривиального нарушения обфускации (хотя данные все еще могут указывать на намерение, если они не зашифрованы)

Например:

[ProtoContract]
public class Foo {
    [ProtoMember(1)]
    public string Bar {get;set;}
}

Здесь, в 1 это все, что идентифицировало участника в файле.Ключевым моментом здесь является то, что он основан на контракте, поэтому позже может быть десериализован с использованием несвязанного типа:

[ProtoContract]
public class a12 {
    [ProtoMember(1)]
    public string a {get;set;}
}

(что нормально, поскольку запутывание сохраняет метаданные, IIRC).

Сравните это с другими сериализаторами на основе контрактов (такими как XmlSerializer или DataContractSerializer) - где вы были бы вынуждены указать имя участника в атрибутах, что в значительной степени сделало бы запутывание бессмысленным:

[DataContract]
public class a12 {
    [DataMember(Name="Bar")]
    public string a {get;set;}
}

Другие советы

Обфускация, в первую очередь, не обеспечивает безопасность.Так что, возможно, вы захотите отказаться от этого, и точка.

Два варианта, которые я вижу, таковы:

  1. Не запутывайте эти типы.Это заставит все просто работать.
  2. Напишите свой собственный код сериализатора.

Поскольку вы ничего не добьетесь, запутывая, я бы выбрал # 1.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top