2010-07-14 16 views
12

Bir Microsoft .Net ikili desantizasyon başarısızlığı kaynak türünü açığa çıkarmak için bir çalışma zamanı platformunun nasıl çalınacağı hakkında bilgi arıyorum..Net İkili Deserialization Başarısızlık tespiti/forensics

BinaryFormatter.Deserialize(StreamingContextStates.CrossMachine) kullanırken ve türlerden biri geçerli ikili dosyalarda mevcut değil; Bir hata atmak yerine, .NET [TypeLoadExceptionHolder] nesnesini ekler. Özellikle koleksiyonlar için bu derhal sorun yaratmaz. Ardından, uygulama katmanları arasında iletim için toplama serileştirildiğinde; platform bir "serileştirme hatası" alır, çünkü [TypeLoadExceptionHolder] serileştirilemez. Dolayısıyla ortaya çıkan hata, soruna neden olan kaynak türüne ilişkin ipuçları sağlamak için işe yaramaz. Şimdi avlanma (zaman emmek) hangi geliştiricinin (yüzlerce) milyonlarca platformda yeni bir tür eklediğini görmeye devam ediyor.

Bu sorun, platform oturum önbelleğini desteklemek için kullanılan seri hale getirme akışı nedeniyle bazı sıklıkta gerçekleşir. Kod oldukça sık ve artan bir şekilde dağıtılmaktadır. Müşteri sayfası istekleri, dağıtım penceresi sırasında kod tabanının eski ve yeni sürümleri arasında geri dönebilir. Yeni bir türün dikkatsiz bir şekilde tanıtılması, eski versiyondaki sayfa isteklerinin patlamasına neden olacaktır. Çalışma zamanı açısından zengin hata/tuzak sağlama hakkında herhangi bir fikir takdir edilecektir.


(SerializationException) 
Type 'System.Runtime.Serialization.TypeLoadExceptionHolder' in Assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 
- at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) 
- at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) 
- at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() 
- at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) 
- at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) 
- at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) 
- at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) 
- at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) 

cevap

4

Eh, sürebilir bir yaklaşım özel bir BindToType geçersiz kılar ve seri kaldırma sırasında tür adı denetler SerializationBinder kullanmaktır.

size de yapamaz bilinmeyen bir türü tanımlamak zaman, başarmak istediğiniz ne bağlı olarak:

  • (Kötümser) bir özel durum yükseltin: meseleyi erkenden yakala ve kolayca kimlik türünü ile özel bir mesaj veya istisna.

  • Tür Adını Günlüğe Kaydet (İyimser): Bilinmeyen türlerin iyi olduğu senaryolar varsa, günlüğe kaydetme sırasında daha sonra gerçekleşirse, günlüğe kaydetme, ayrıcalıkları tanılamak için gerekli ayrıntıları sağlar.

Ayrıca tip adının özelliklerine bağlı olarak farklı bir yaklaşım seçebilirsiniz (yani tip uygulamanızda veya 3. taraf kütüphanesinin bölümü bir parçası olmak görünüyorsa).

Seri hale getirme sırasında oluşturulan TypeLoadExceptionHolder örneğinde, çözümlenemeyen türün adını içeren TypeName kamuya açık olmayan bir üye bulunur. Ancak, örnek daha sonra karşılaştığınız SerializationException'dan edinilemez, hatta bu değer, yalnızca güvenilen bağlamlarda yansıma aracılığıyla kullanılabilir.

public class CustomSerializationBinder : SerializationBinder 
{ 
    public override Type BindToType(string assemblyName, string typeName) 
    { 
     Type t = Type.GetType(string.Concat(typeName, ", ", assemblyName)); 

     if (t == null) 
     { 
      throw new SerializationException(string.Format("Type {0} from assembly {1} could not be bound.", typeName, assemblyName)); 
     } 

     return t; 
    } 

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName) 
    { 
     base.BindToName(serializedType, out assemblyName, out typeName); 
    } 
} 

... 

BinaryFormatter.Binder = new CustomSerializationBinder(); 
İlgili konular