1

BinaryFormatter is now obsolete for security reasons. Unfortunately, there is a ton of old legacy records that were serialized to array using the BinaryFormatter. Is there a way to deserialize those records in a new app WITHOUT using BinaryFormatter or are we stuck doing a massive overhaul to pull records, deserialize and reserialize in a different format?

Edit: I am trying to convert the byte[] into an object. The only other way I know how to do that is with Deseralize from System.Text.Json. But BinaryFormatter doesn't use encode, it uses a BinaryData type. System.Text.Json expects encode, utf8 not to mention it expects json.

Edit: Getting closer. Part of the issue is the format is in MS-NRBF when you use BinaryFormatter. There is a nuget that helps you read the format. (https://github.com/bbowyersmyth/BinaryFormatDataStructure) You still have to manually reflect and manage the object assignment, but at least this lets you read the MS-NRBF format.

I found this resource to be very useful: https://localcoder.org/how-to-analyse-contents-of-binary-serialization-stream

Hope
  • 125
  • 9
  • [.Net Where to find the official specification of the BinaryFormatter serialization format?](https://stackoverflow.com/q/2044111/3744182) may help. – dbc Apr 22 '22 at 18:51

3 Answers3

1

If anyone gets curious about how you can do this, here is a way. Its a rough little experiment I put together. Its not robust, just a breadcrumb. I'm not sharing this to say you should do this, since reflection is a cost. That's up to you and your requirements to decide. I'm just sharing the how. This will successfully map the MS-NRBF back into a class model. Note the recursion.

NOTE: This only works with objects. If it was a string value that was transformed originally, the library will just pull the string value out directly, so you'll need to cast it into (string) instead of (BinaryObject). You can read this to learn more about the MS-NRBF headers if you want to deeper dive into what the lib is doing: https://localcoder.org/how-to-analyse-contents-of-binary-serialization-stream

I used this lib to digest the format: https://github.com/bbowyersmyth/BinaryFormatDataStructure

 private T TransformMSNRBFToObject<T>(byte[] data) where T : new()
    {
        T response = new T();
        using (var stream = new MemoryStream(data))
        {
            var bObj = (BinaryObject)NRBFReader.ReadStream(stream);
            GetObjectFromBinaryObject<T>(bObj, response);
        }

        return response;
    }

    private void GetObjectFromBinaryObject<T>(BinaryObject bObj, T result) where T : new()
    {
        foreach (var prop in result.GetType().GetProperties())
        {
            string key = $"<{prop.Name}>k__BackingField";
            if (!bObj.ContainsKey(key))
            {
                throw new Exception($"Transform could not occur. Expected property {prop.Name} in data, but none was found.");
            }

            //If its a nested class, then the value will be another BinaryObject. Use recursion to get that next obj mapped.
            if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string))
            {
                var type1 = prop.PropertyType;
                var propValue = (BinaryObject)bObj[key];

                try
                {
                    var result2 = Activator.CreateInstance(type1);
                    GetObjectFromBinaryObject(propValue, result2);
                    prop.SetValue(result, result2);
                }
                catch (System.MissingMethodException mme) //This happens usually when you try to map a string or system object
                {
                    throw new Exception($"Model you are trying to convert to is missing an empty contstructor. Class: {type1}");
                }
            }
            else //its a IConvertible field or a string
            {
                prop.SetValue(result, bObj[key]);
            }
        }
    }
Hope
  • 125
  • 9
0

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter?

Can you use System.IO.BinaryReader?

Byrd
  • 325
  • 1
  • 8
  • Sorry I wasn't clear, I am trying to convert the byte[] into an object. The only other way I know how to do that is with Deseralize from System.Text.Json. But BinaryFormatter doesn't use encode, it uses a BinaryData type. System.Text.Json expects encode, utf8. If I could transform it from unencoded to encoded, I could probably get somewhere but I haven't figured that out yet. – Hope Apr 21 '22 at 23:18
  • BinaryReader is only for primitive types. Since I'm trying to convert to an object, this doesn't work for me. – Hope Apr 21 '22 at 23:53
-1

I would back up the data and would do a one-time conversion of all data to a new format. Easy code and fewer chances to screw up things.

Optional Option
  • 1,521
  • 13
  • 33