[英]Reading Protobuf TCP Packets with existing C# classes
這個問題看似簡單且可行,但是我一生無法使它正常工作。
我有:
程序集中所有可能的C#類都裝飾有:
[DebuggerNonUserCode, CompilerGenerated, GeneratedCode("ProtoGen", "2.4.1.473")] public sealed class thing : GeneratedMessageLite<thing, thing.Builder>
我要做的就是使用我從匯編文件中了解的信息來解析那些數據包。 簡單? 可能,但是無論我做什么,實際上都沒有得到解析。
這是許多可能的類之一的示例:
[DebuggerNonUserCode, CompilerGenerated, GeneratedCode("ProtoGen", "2.4.1.473")]
public sealed class Thing: GeneratedMessageLite<Thing, Thing.Builder>
{
// Fields
private static readonly string[] _thingFieldNames = new string[] { "list" };
private static readonly uint[] _thingFieldTags = new uint[] { 10 };
...
public static Builder CreateBuilder()
{
return new Builder();
}
...
public static thing ParseFrom(ByteString data)
{
return CreateBuilder().MergeFrom(data).BuildParsed();
}
...
public override void WriteTo(ICodedOutputStream output)
{
int serializedSize = this.SerializedSize;
string[] strArray = _thingFieldNames;
if (this.list_.Count > 0)
{
output.WriteMessageArray<thingData>(1, strArray[0], this.list_);
}
}
...
[DebuggerNonUserCode, GeneratedCode("ProtoGen", "2.4.1.473"), CompilerGenerated]
public static class Types
{
// Nested Types
[CompilerGenerated, GeneratedCode("ProtoGen", "2.4.1.473")]
public enum PacketID
{
ID = 19
}
}
}
有很多其他類似的東西。 我嘗試對每個數據包執行以下操作(使用protobuf-csharp-port):
Console.WriteLine(Thing.ParseFrom(packet.Buffer).ToString());
我希望看到實際的文本數據。 但是我什么也沒得到,關於無效數據包標簽的錯誤,或者關於它為“ 0”的錯誤。
我也嘗試過使用protobuf-net,但這只是給我有關不兼容,意外類型等的隨機錯誤:
Console.WriteLine(ProtoBuf.Serializer.Deserialize<Thing>(ms));
我到底在這做錯了什么? 有沒有更好的方法,可以在程序集中使用所有已知的類型,簡單地解碼Protobuf消息並查看其中的內容? 理想情況下,無需事先知道消息類型是什么?
非常感謝,如果您能解決這個問題!
從問題中概述的失敗嘗試中猜測,我相信您對pcap文件的內容有一些誤解。 特別是這條線
Console.WriteLine(Thing.ParseFrom(packet.Buffer).ToString());
讓我認為您在錯誤的假設下工作,即單個pcap數據包包含一個對象的序列化字節。 不幸的是,這種情況並非如此。
如您所知,TCP / IP網絡使用分層協議棧,其中每個層都添加了功能,並將上層協議與下層協議的細節隔離開了(反之亦然)。 這是通過封裝從高層發送到網絡的數據,並在數據沿接收方的堆棧向上傳輸時進行解封裝來完成的。 現在,您的pcap文件包含網絡接口看到的原始數據,即,序列化的有效負載以及應用程序,傳輸,Internet和鏈接層添加的所有數據。
現在,如果您要反序列化轉儲中包含的對象,則需要編寫一些代碼來刪除鏈接層和Internet協議的所有標頭,(取消)傳輸協議的工作並重新組合通過網絡發送的字節流。*
接下來,您將需要分析產生的字節轉儲,並對應用程序級別協議的設計做出一些復雜的猜測。 開始通信時是否實現握手? 它會與實際有效載荷一起發送校驗和嗎? 數據在通過網絡發送之前是否已被壓縮? 應用程序在發送數據之前會對其進行加密嗎? 如果將TCP用作傳輸協議,那么如何實現消息框架等。當然,如果您可以訪問生成數據的應用程序的源代碼(或至少是應用程序二進制文件),則只需閱讀代碼即可(或對二進制文件進行反向工程)以弄清楚這部分。
至此,您就可以解釋原始數據了。 剩下的就是編寫一些代碼來提取相關的字節,並將其提供給協議緩沖區解串器和voilà,讓您的對象回來!
(*當然還有其他一些小問題,例如碎片化的IP數據包,無序到達的TCP段和TCP重傳。)
總結一下:
請注意,僅上述第1點導致要求至少部分實現TCP / IP堆棧的功能。 實現此目的的最簡單方法可能是重用開放源代碼TCP / IP實現的代碼,例如在Linux或* BSD內核中發現的代碼。 許多執行類似操作的工具(例如從捕獲文件中重建HTTP流量)正是這樣做的。 (例如參見Justsniffer 。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.