#c# #.net #obfuscation
#c# #.net #обфускация
Вопрос:
У меня есть следующий многоуровневый объект JSON, представленный DataContract
, который я могу нормально проанализировать, используя JavascriptSerializer
[DataContract]
public class ClassOuter{
[DataMember(Name = "stringProperty1")]
public string stringProperty1 {get;set;}
[DataMember(Name = "objectProperty")]
public ClassInner objectProperty {get;set;}
}
//NOTE:No DataContract Attribute here!
public class ClassInner{
[DataMember(Name = "stringProperty2")]
public string stringProperty2 {get;set;}
}
Но когда я вызываю
string inputText = "{"stringProperty1":"Hello","objectProperty":{"stringProperty2":"World"}}";
ClassOuter myObject = new JavascriptSerializer().Deserialize<ClassOuter>(inputText);
Console.WriteLine(myObject.stringProperty2);
Все работает нормально.
Однако при запуске приложения через обфускатор после сборки stringProperty2 становится нулевым. * Не могу сказать, какой обфускатор, извините!
Никаких предупреждений от CodeAnalysis. Я не очень знаком с компиляторами, но вот мое предположение: компилятор распознает намерение и создает ссылку внутренне, несмотря на отсутствие DataContract
атрибута. Однако он не создает какой-либо внутренней разметки, поэтому обфускатор может свободно перемешивать его, и ссылка прерывается. Однако, если бы это был просто блок непрерывной памяти, я бы предположил, что все было бы намного сложнее, чем сейчас, а не просто становилось null
Кто-нибудь может проверить или оспорить мою наивную гипотезу?
(Добавление DataContract
атрибута для ClassInner
решает проблему даже при обфускации!)
Ответ №1:
Кто-нибудь может проверить или оспорить мою наивную гипотезу?
Без обфускации он будет работать без [DataContract]
, потому что в результате сериализатор просто вернется к отказу от использования атрибутов и сериализует их только по именам свойств. Они идентичны вашему атрибуту, поэтому вы этого не замечаете. Вы должны быть в состоянии убедиться, что, передавая [DataMember]
текст, который пришел без надлежащего [DataContract]
другого Name
текста, сериализатор по-прежнему будет использовать имя свойства и игнорировать атрибут. Эти атрибуты работают как пара. Установите оба параметра или вернитесь к «none».
public class ClassInner
{
// This is ignored because no [DataContract] was found
[DataMember(Name = "nonexistentProperty")]
// This will still be set unobfuscated because the property name matches
public string stringProperty2 { get; set; }
}
Поэтому, когда вы его запутываете, имена свойств меняются. Без [DataContract]
для начала сериализатор вернется к атрибутам и найдет только случайные комбинации букв, которые он не может сопоставить с входными данными. Следовательно, вы получите null
.
Комментарии:
1. Имеет смысл. Большое вам спасибо!