Serialization of proto-buf with obfuscation

I am looking for a few recommendations on what happens when using a proto-buf network with obfuscation (Dotfuscator). One half of the project is a DLL, and the other half is an EXE in a different place and using proto-buf NET they communicate flawlessly. So far I have not confused the DLL.

At this point, the P-BN crashes without throwing an exception, returning in different ways an array of bytes of length 0 or angle depending on what I was looking for. The class is pretty simple (VB):

<ProtoContract(Name:="DMailer")> _ Friend Class DMailer Private _Lic As Cert Private _Sys As Sys Private _LList As List(Of LItem) .. .. End Class 

There are 3 props, each of which is decorated with ProtoMember, to get / set objects of compound classes. Short for brevity.

Again, it works GREAT until I messed up the DLL. Then the Dotfuscator renames each one of them to zero, apparently, since they are all Friends and seem to choke on protobuff. If I free the class from renaming (just the class name, not the props / members), it seems to work again. It makes sense that P-BN can only act on objects with its own name, although when it is asked to serialize a null named object, it looks like it could be an exception.

On the other hand, most of the charm of PB-N should be serialized regardless of the .NET names that work with attributes - at least as I understand it. But in this case, it only works with classes with names. I tried using the qualifier or the Name argument, as shown above, but did not help - obviously, it does not do what I thought it could.

So, I am wondering if:

a) ... I correctly understood the problem correctly

b) ... There is another attribute or flag that can facilitate serialization of an object with a null name

c) ... if there are other ideas that will help.

If I free all 3 or 4 classes from renaming Dotfuscator (LList is not yet implemented, leaving DMailer, Cert and Sys), the DLL seems to work again - at least the output is the right size. I can live with this, although more hidden names will be better: Dotfuscator (CE) either frees them or sets Null names - I cannot find a way to force them to be renamed.

Instead of freeing 3 or 4 classes from renaming, one of the alternatives I’m considering is simply storing the Serializer output for Cert and Sys as arrays of bytes or Base64 strings in DMailer instead of classes. Then get the Deserialize receiver of each object individually. It's nice to be able to unpack only one thing and have the toys right there, as if by magic, though.

(a lot) TIA

+5
source share
2 answers

Since there were a few interesting looks, here is what it will look like:

a) No form of reflection can get a list of properties for obfuscation. I tried to go through all types to find those with ProtoContract, I could find them but the property names are all changed to a, m, b, j, g.

I also tried Me.GetType.GetProperties with the same result.

You could implement a map from the output to indicate that Employee.FirstName is now a0.j, but propagating this leads to a loss of purpose.

b) That works to some extent to free the NAME class from obfuscation. Since PB-N is looking for ProtoMember attributes to retrieve data, you can confuse Property / Members rather than the class / type name. If this name is similar to FederalReserveLogIn, your class / type has an “apple” on it.

I had an initial success:

1) Create a simple class to save the token and property value. Save everything as a string using ConvertFromInvariantString . Taking a hint from PBN, I used an integer for the token:

 <ProtoMember(propIndex.Foo)> Property Foo As String 

Enumeration helps to tie everything together later. Save them to Dictionary(Of T, NameValuePair)

2) add some accessors. they can perform type conversions for you:

  Public Sub Add(ByVal Key As T, ByVal value As Object) If _col.ContainsKey(Key) Then _col.Remove(Key) End If _col.Add(Key, New TValue(value)) End Sub Public Function GetTItem(Of TT)(key As T) As TT If _col.ContainsKey(key) Then Return CType(_col(key).TValue, TT) Else Return Nothing End If End Function 

T is any type of key that you want to use. An integer produces the smallest result and still allows the subscription code to use Enum. But it could be a string.

TT is the original type:

 myFoo = props.GetTItem(Of Long)(propsEnum.Foo) 

3) Open the internal list (dictionary) for PBN and bingo, everything is done.

It is also very easy to add converters for Point, Rectangle, Font, Size, Color and even bitmap.

NTN

+2
source

Interesting. I admit that I have never tried this script, but if you can get me through your process (or better: perhaps provide a basic playback example of “run this, then this, and then this: boom”). I am happy to explore.

Note: The Name in ProtoContract is mainly intended to use GetProto() ; it is not needed by the underlying serializer and can be omitted to reduce your impact. In addition, protobuf-net is not interested in fields unless these fields are decorated with attributes, so this should not be a problem.

But! there is probably a workaround that should work now; You can pre-create static dll serialization; for example, in a separate exe console (as a tool, I really need to wrap this in a standalone utility!)

So, if you create a console exe that references your unobfuscated library and protobuf-net.dll:

 var model = RuntimeTypeModel.Create(); model.Add(typeof(DMailer), true); // true means "use the attributes etc" // and other types needed, etc model.Compile("MailSerializer", "MailSerializer.dll"); 

this should write MailSerializer.dll , which you can then reference your main code (in addition to protobuf-net) and use:

 var ser = new MailSerializer(); // our pre-genereated serializer ser.Serialize(...); // etc 

Then include MailSerializer.dll in your obfuscation payload.

(all this is v2 specific, btw)

If this does not work, I will need to investigate the main problem, but I am not an expert on obfuscation, so you can do this with your playback steps.

+4
source

Source: https://habr.com/ru/post/1383545/


All Articles