如何自动获取BinaryFormatter序列化文件的类结构?
自动生成BinaryFormatter序列化文件对应类的方案
方法一:编写反射生成工具
通过BinaryFormatter反序列化文件到object实例,再利用反射遍历类型结构,自动生成C#类代码。示例代码如下:
using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Reflection; using System.Text; using System.Collections.Generic; class ClassGenerator { static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("请传入二进制文件路径"); return; } var formatter = new BinaryFormatter(); using (var stream = File.OpenRead(args[0])) { var obj = formatter.Deserialize(stream); var sb = new StringBuilder(); GenerateCode(obj.GetType(), sb, new HashSet<Type>()); File.WriteAllText($"{obj.GetType().Name}.cs", sb.ToString()); Console.WriteLine("类文件已生成"); } } static void GenerateCode(Type type, StringBuilder sb, HashSet<Type> processed) { if (processed.Contains(type) || type.IsPrimitive || type == typeof(string) || type.IsEnum) return; processed.Add(type); sb.AppendLine("[Serializable]"); sb.AppendLine($"public class {type.Name}"); sb.AppendLine("{"); // 处理属性 foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { sb.AppendLine($" public {GetTypeName(prop.PropertyType)} {prop.Name} {{ get; set; }}"); GenerateCode(prop.PropertyType, sb, processed); } // 处理字段 foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) { sb.AppendLine($" public {GetTypeName(field.FieldType)} {field.Name};"); GenerateCode(field.FieldType, sb, processed); } sb.AppendLine("}"); sb.AppendLine(); } static string GetTypeName(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) { var elementType = type.GetGenericArguments()[0]; return $"List<{GetTypeName(elementType)}>"; } // 可扩展处理其他泛型类型 return type.Name; } }
使用时将编译后的程序与目标二进制文件放在同一目录,执行ClassGenerator.exe yourfile.bin即可生成对应的类文件。
方法二:借助第三方逆向工具
- dotPeek:将反序列化后的对象加载到内存后,使用dotPeek的导出功能,将类型结构导出为C#代码,支持识别嵌套类型、私有成员等复杂结构。
- BinaryFormatter专用解析工具:部分逆向工具可直接解析BinaryFormatter格式的文件,无需完整反序列化即可生成类定义,适合处理超大文件或存在反序列化障碍的场景。
注意事项
- .NET Core/.NET 5+环境下需手动引用
System.Runtime.Serialization.Formatters.BinaryNuGet包。 - 若原类型实现了
ISerializable接口,自动生成的类需补充GetObjectData方法和对应的构造函数,才能正常序列化。
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

