使用混淆的 Proto-buf 序列化
我正在寻找一些有关使用带有混淆功能的 proto-buf 网络(Dotfuscator)时发生的情况的指导。该项目的一半是 DLL,另一半是其他地方的 EXE,它们使用 proto-buf NET 完美地交换数据。直到我混淆了 DLL。
此时,P-BN 会失败,不会引发异常,根据我所处理的内容,返回不同的 0 长度字节数组或缩短的字节数组。该类相当简单 (VB):
<ProtoContract(Name:="DMailer")> _
Friend Class DMailer
Private _Lic As Cert
Private _Sys As Sys
Private _LList As List(Of LItem)
..
..
End Class
有 3 个 props 均用 ProtoMember 装饰,用于获取/设置组成类对象。为了简洁起见,剪掉了。
再说一遍,在我混淆 DLL 之前它工作得很好。然后,Dotfuscator 将它们中的每一个重命名为 null,显然因为它们都是 Friend,这似乎让原始爱好者感到窒息。如果我免除类的重命名(只是类名,而不是 props/members),它似乎又可以工作了。 P-BN 只能对具有正确名称的对象进行操作,这是有道理的,但当被要求序列化一个空命名对象时,似乎可能会出现异常。
另一方面,PB-N 的大部分魅力应该是独立于使用属性的 .NET 名称的序列化 - 至少在我看来是这样。然而在这种情况下,它似乎只适用于有名称的类。我尝试使用名称限定符或参数,如上所示,但无济于事 - 它显然没有达到我的预期。
所以,我很好奇是否:
a)...我基本上正确地推测了问题
b)...还有一些其他属性或标志可能有助于序列化 一个空的命名对象
c) ...如果有任何其他见解可以提供帮助。
如果我从 Dotfuscator 重命名中免除所有 3 或 4 个类(LList 尚未实际实现,只剩下 DMailer、Cert 和 Sys),DLL 似乎会再次工作 - 至少输出是正确的大小。我可以忍受这一点,尽管模糊的名称会更好:Dotfuscator (CE) 要么豁免它们,要么将名称设置为 Null - 我似乎找不到一种方法来强制它们重命名。
我正在考虑的一种替代方案是将 Cert 和 Sys 的序列化器输出简单地存储为 DMailer 中的字节数组或 Base64 字符串,而不是类,而不是免除 3 或 4 个类的重命名。然后让接收者单独反序列化每个对象。不过,能够像变魔术一样打开一件东西并把你的玩具放在那里,真是太好了。
(许多)TIA
I am looking for some guidance as to what is going on when using proto-buf net with obfuscation (Dotfuscator). One half of the project is a DLL and the other is an EXE elsewhere and using proto-buf NET they exchange data flawlessly. Until I obfuscate the DLL.
At that point P-BN fails without raising an exception, returning variously a 0 length byte array or a foreshortened one depending on what I have fiddled with. The class is fairly 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 all decorated with ProtoMember to get/set the constituent class objects. Snipped for brevity.
Again, it works GREAT until I obfuscate the DLL. Then, Dotfuscator renames each of these to null, apparently since they are all Friend, and that seems to choke proto-buff. If I exempt the class from renaming (just the class name, not props/members), it seems to work again. It makes sense that P-BN would only be able to act on objects with a proper name, though when asked to serialize a null named object, it seems like an exception might be in order.
On the other hand, much of the charm of PB-N is supposed to be serialization independent of .NET names working from attributes - at least as I understand it. Yet in this case it only seems to work with classes with names. I tried using the Name qualifier or argument as shown above, to no avail - it apparently doesnt do what I thought it might.
So, I am curious if:
a) ...I have basically surmised the problem correctly
b) ...There is some other attribute or flag that might facilitate serializing
a null named object
c) ...if there are any other insights that would help.
If I exempt all 3 or 4 classes from Dotfuscator renaming (LList is not actually implemented yet, leaving DMailer, Cert and Sys), the DLL seems to work again - at least the output is the correct size. I can live with that, though obscured names would be better: Dotfuscator (CE) either exempts them or sets the names to Null - I cant seem to find a way to force them to be renamed.
Rather than exempt 3 or 4 classes from renaming, one alternative I am considering is to simply store the Serializer output for Cert and Sys as byte arrays or Base64 strings in DMailer instead of classes. Then have the receiver Deserialize each object individually. It is kind of nice to be able to unpack just one thing and have your toys right there as if by magic though.
(many)TIA
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有趣的。我承认我从未尝试过这种情况,但如果您可以引导我完成您的过程(或者更好:也许提供一个基本的重现示例“运行这个,然后这个,然后这个:繁荣”)我会很乐意进行调查。
注意:ProtoContract 上的
Name
主要供GetProto()
使用;核心串行器不需要它,可以省略它以减少暴露。此外,protobuf-net 对字段不感兴趣,除非这些字段用属性修饰,所以这不应该成为问题。然而!这里可能有一个解决方法,现在应该可以工作;您可以预先生成静态序列化dll;例如在一个单独的控制台 exe 中(就像一个工具;我真的需要将其包装在一个独立的实用程序中!)
因此,如果您创建一个引用您的unobfuscated库和 protobuf-net.dll 的控制台 exe :
这应该编写
MailSerializer.dll
,然后您可以从您的 main 代码(除了 protobuf-net 之外)引用它,并使用:然后包含混淆负载中的
MailSerializer.dll
。(顺便说一句,这都是 v2 特定的)
如果这不起作用,我需要调查主要问题,但我不是混淆专家,因此可以按照您的重现步骤进行操作。
Interesting. I confess I have never tried this scenario, but if you can walk me through your process (or better: maybe provide a basic repro example with "run this, then this, then this: boom") I'll happily investigate.
Note: the
Name
on ProtoContract is mainly intended forGetProto()
usage; it is not needed by the core serializer, and can be omitted to reduce your exposure. Also, protobuf-net isn't interested in fields unless those fields are decorated with the attributes, so that shouldn't be an issue.However! there's probably a workaround here that should work now; you can pre-generate a static serialization dll; for example in a separate console exe (just 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:
this should write
MailSerializer.dll
, which you can then reference from your main code (in addition to protobuf-net), and use:Then include
MailSerializer.dll
in your obfuscation payload.(this is all v2 specific, btw)
If this doesn't work, I'll need to investigate the main issue, but I'm not an obfuscation expert so could do with your repro steps.
由于存在一些兴趣上升,因此看起来会起作用:
a)任何形式的反射都无法获取混淆类型的属性列表。
我尝试遍历所有类型来找到带有 ProtoContract 的类型,我可以找到它们
但属性名称全部改为a,m,b,j,g。
我也尝试了 Me.GetType.GetProperties ,结果相同。
您可以从输出中实现一个映射来指示 Employee.FirstName 现在是 a0.j,但是分发它会破坏混淆的目的。
b) 在一定程度上有效的是使类 NAME 免受混淆。由于 PB-N 查找 ProtoMember 属性来获取数据,因此您可以混淆属性/成员名称,但不能混淆类/类型名称。如果名称类似于 FederalReserveLogIn,则您的类/类型上有一个靶心。
我在执行以下操作时取得了初步成功:
1)构建一个简单的类来存储属性令牌和值。使用ConvertFromInvariantString 将所有内容存储为字符串。借鉴 PBN 的提示,我使用了一个整数作为标记:
枚举有助于稍后将所有内容联系在一起。将它们存储在
Dictionary(Of T, NameValuePair)
2) 添加一些访问器。这些可以为您执行类型转换:
T
是您希望使用的任何键类型。整数会产生最小的输出,并且仍然允许订阅代码使用枚举。但它可能是字符串。TT
是原始类型:3)将内部列表(字典)暴露给 PBN 和 bingo,全部完成。
添加点、矩形、字体、大小、颜色甚至位图转换器也非常容易。
华泰
Since there were a few upticks of interest, here is what looks like will work:
a) No form of reflection will be able to get the list of properties for an obfuscated type.
I tried walking thru all the types to find the ones with ProtoContract on it, 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 distributing this defeats the purpose of obfuscation.
b) What does work to a degree is to exempt the class NAME from obfuscation. Since PB-N looks for the ProtoMember attributes to get the data, you CAN obfuscate the Property/Member names, just not the CLASS/type name. If the name is something like FederalReserveLogIn, your class/type has a bullseye on it.
I have had initial success doing the following:
1) Build a simple class to store a Property Token and value. Store everything as string using
ConvertFromInvariantString
. Taking a tip from PBN, I used an integer for the token:An enum helps tie everything together later. Store these in a
Dictionary(Of T, NameValuePair)
2) add some accessors. these can perform the type conversions for you:
T
is whatever key type you wish to use. Integer results in the smallest output and still allows the subscribing code to use an Enum. But it could be String.TT
is the original type:3) Expose the innerlist (dictionary) to PBN and bingo, all done.
Its also very easy to add converters for Point, Rectangle, Font, Size, Color and even bitmap.
HTH