我寫了個抓包程式,需要抓TcpPacket包的內容。但是我發現這個包發過來是gzip格式,獲取過來是亂碼。
抓狂就在這里我怎么轉換破解這個亂碼。
問題一、tcpPacket.Header; 這個方法是個byte[] 怎么知道里面的content-Encoding是gzip。
問題二、知道是gzip格式了怎么對于tcpPacket.PayloadData進行解壓,試了無數方法均不成功。
#region 接收到包的處理 device_OnPackArrival(object sender, CaptureEventArgs e)
/// <summary>
/// 接收到包的處理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void device_OnPackArrival(object sender, CaptureEventArgs e)
{
try
{
var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
//TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
var tcpPacket = PacketDotNet.TcpPacket.GetEncapsulated(packet);
if (tcpPacket != null)
{
var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
byte[] mybyte = tcpPacket.Header;//到這里不知道怎么處理Header里的資料
string aaa= tcpPacket.PayloadData.ToString();
string datastr5 = Encoding.UTF8.GetString(mybyte);
int srcPort = tcpPacket.SourcePort;
int dstPort = tcpPacket.DestinationPort;
//string datastr = Encoding.GetEncoding("utf-8").GetString(tcpPacket.PayloadData, 0, tcpPacket.PayloadData.Length);
///string datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
//string datastr2 = byteToHexStr(tcpPacket.PayloadData);
//string datastr3 = BinaryToString(datastr2);
////string datastr4 = ZipHelper.GZipDecompressString(datastr);
string datastr6 = Encoding.UTF8.GetString(ZipHelper.Decompress(tcpPacket.PayloadData));
//string datastr1 = Encoding.UTF8.GetString(GzipDecompress(tcpPacket.PayloadData));
}
#endregion
代碼里的ZipHelper類是從以下地址拷貝過來的。
https://www.cnblogs.com/yuwentao/p/9565747.html
uj5u.com熱心網友回復:
在線等,哪位大神幫忙解答一下。uj5u.com熱心網友回復:
你這個問題與 PCap 抓包沒什么關系啊,純粹是解壓縮問題。TCP 包頭是有規范的,不是隨便搞的,一般業務層也不需要處理包頭資訊。uj5u.com熱心網友回復:
@datafansbj 我也知道是解壓縮的問題。但是這個確實和抓包有一定關聯。
var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
這步我抓到包了,但是怎么決議啊!這是困擾我很久的問題。
我用盡了方法都不行,請大神給個思路。
uj5u.com熱心網友回復:
給一堆位元組陣列 byte[] 要你決議,沒有頭緒誰也不會,至少要知道決議的東西大概是什么吧。是壓縮資料?文本?視頻?音頻?uj5u.com熱心網友回復:
文本,抓到的資料就是問題文本。目前就是文本亂碼。
var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
就在這條陳述句亂的。tcpPacket.PayloadData 主要是對它決議。
沒有思路。
uj5u.com熱心網友回復:
如果確定是未加密的文本,那么亂碼問題就好解決了,使用適當的 Encoding 解碼。如果確認是 utf8 格式的,應使用下述方式解碼:
UTF8Encoding encoding = new UTF8Encoding();
string datastr = encoding.GetString(tcpPacket.PayloadData);
uj5u.com熱心網友回復:
果然是靈魂寫手。你那邊怎么寫的,怎么發的不知道。你問我們這邊怎么寫,怎么接,怎么解。
好,那我問問,你基于什么啊,udp,tcp,http,基于何種協議mqtt,grpc,json
你怎么發的,把整包資料壓縮,還是只把資料部分壓縮。
如果說整包壓縮,udp還有解。tcp就算了,udp一個包就是一個包,我知道頭尾,直接解壓就好
但是tcp,整包壓縮。我連頭尾都不知道,怎么解???
話說你看看人家http把
頭部xxxx:xxxx/gzip ,
資料包長:xxxx
資料區:xxxxxxx
這才有解,我知道他是gzip,知道一共有多長。
你問我們tcpPacket.Header不知道怎么辦,我們知道怎么辦,你把tHeader都壓了,我知道頭在那里???
uj5u.com熱心網友回復:
在則:tcpPacket.Header ,pcap,那么請問你覺著這個tcpPacket.Header到底表達何意???你覺著pcap到底是個何種軟體。那個是個抓封包的,不是一個抓協議的。
tcpPacket.Header 抓的是tcp/ip底層的原始頭,不是你上層的協議頭。
什么那個是一個gzip,底層鏈路層管你什么gzip么。
那個是ip報文頭,不是協議報文頭
uj5u.com熱心網友回復:
來看看隨手的例子byte[] pktBytes = FormatUtils.toByteArray("0015c672234c90e6ba92661608004500002d358c4000800600000a000b050a090028c26e270fb8b256e3a2009f785018faf01f550000746573740a");
JMemoryPacket packet = new JMemoryPacket(pktBytes);
packet.scan(Ethernet.ID); //Need to be done before doing any edits
//Editing Ip layer
Ip4 ip = packet.getHeader(new Ip4());
ip.source(new byte[] {2,6,0,0}); //Source Ip 2.6.0.0
ip.destination(new byte[] {1,2,3,4}); //Dest Ip 1.2.3.4
//Editing Tcp layer
Tcp tcp = packet.getHeader(new Tcp());
tcp.destination(5555); //Port destination 5555
if (pcap.sendPacket(packet) != Pcap.OK) {
System.err.println(pcap.getErr());
}很,明顯這是什么?這是ip資料報報文頭,而不是應用協議層報文頭
uj5u.com熱心網友回復:
using SharpPcap;
using SharpPcap.LibPcap;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SharpPcapDemo
{
public partial class Form1 : Form
{
/**
* 例子:從瀏覽器打開 https://money.163.com/stock/
* 這個時候你打開程式撲獲資料
* 看到從這個 https://money.163.com/special/002557S6/newsdata_gp_index.js?callback=data_callback 地址獲取資訊就是亂碼
* 只要能獲取資訊能解碼就行。
*
* **/
string selectedAdp;
public static Thread awaker;//啟動執行緒
public static Thread sleeper;//關閉執行緒
public Form1()
{
InitializeComponent();
}
#region 表單加載 Form1_Load() 事件
private void Form1_Load(object sender, EventArgs e)
{
//初始化加載網卡串列
getAdapter();
}
#endregion
#region 獲取網卡 getAdapter()
/// <summary>
/// 獲取網卡
/// </summary>
private void getAdapter()
{
var devices = LibPcapLiveDeviceList.Instance;
if (devices.Count < 1)
{
MessageBox.Show("此設備沒有網卡");
}
else
{
foreach (var dev in devices)
{
selectAdp.Items.Add(dev.Interface.FriendlyName);
selectAdp.SelectedIndex = 0;
}
}
}
#endregion
#region 啟動監聽按鈕事件
private void btnAutoSpi_Click(object sender, EventArgs e)
{
this.lbsMsg.Text = "監控啟動中.........";
selectedAdp = selectAdp.Text.ToString();
if (awaker != null && awaker.IsAlive)
{
MessageBox.Show("已經在監聽了,不要錯誤操作好嗎 ");
}
awaker = new Thread(new ThreadStart(monitor)); //選擇啟動監聽行程
awaker.Start();
}
#endregion
#region 監聽
/// <summary>
/// 監聽
/// </summary>
private void monitor()
{
var devices = LibPcapLiveDeviceList.Instance;
foreach (PcapDevice dev in devices)
{
if (dev.Interface.FriendlyName.ToString() == selectedAdp)
{
PcapDevice device = dev;
device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPackArrival);
device.Open(DeviceMode.Promiscuous, 1000);//監聽模式
device.StartCapture();//啟動撲獲
}
}
}
#endregion
#region 接收到包的處理 device_OnPackArrival(object sender, CaptureEventArgs e)
/// <summary>
/// 接收到包的處理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void device_OnPackArrival(object sender, CaptureEventArgs e)
{
try
{
var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
//TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
var tcpPacket = PacketDotNet.TcpPacket.GetEncapsulated(packet);
if (tcpPacket != null)
{
var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
//主要是這里我已經獲取到資料了,只是亂碼,只需要解碼.不需要分析等等。
//重申只需要把亂碼解開即可,把亂碼解開
if (datastr != "")
{
//只要這里處理好不是亂碼的資料,能Json決議就好了。
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region 停止監聽按鈕事件
private void btnStop_Click(object sender, EventArgs e)
{
this.lbsMsg.Text = "停止監控.......";
stop();
}
#endregion
#region 停止監聽
/// <summary>
/// 停止監聽
/// </summary>
private void stop()//停止監聽
{
foreach (PcapDevice dev in LibPcapLiveDeviceList.Instance)
{
try
{
if (dev.Interface.FriendlyName.ToString() == selectAdp.Text.ToString())
{
Thread.Sleep(500);
dev.StopCapture();
dev.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
#endregion
}
}
@wanghui0380
我把完整代碼貼出來,請參看。
uj5u.com熱心網友回復:
如果你確定是Gzip的話,可以用這個解壓public static byte[] Compress(byte[] rawData)
60 {
61 MemoryStream ms = new MemoryStream();
62 GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true);
63 compressedzipStream.Write(rawData, 0, rawData.Length);
64 compressedzipStream.Close();
65 return ms.ToArray();
66 }
uj5u.com熱心網友回復:
但是解壓后的正文有可能還是加密的,還得分析解密。uj5u.com熱心網友回復:
你的這句117行要改一下,先解壓后,如果是UTF-8,再呼叫var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
//主要是這里我已經獲取到資料了,只是亂碼,只需要解碼.不需要分析等等。
//重申只需要把亂碼解開即可,把亂碼解開
uj5u.com熱心網友回復:
我用這個方法解壓了。用了以下方法讀成string。
byte[] temp= Compress(tcpPacket.PayloadData);
string st = "";
foreach (byte b in temp) {
st += b.ToString();
}
讀出來都是這樣的值:
3113980000040120604925523330201000000064246282512141331613119178202114471201503725517714122124516118819775191482501611379413878841131830133164444025541915628177210207012270197236212142321411079910515567483254112161356183234271421332910212418410901591143612222910539141611018011249285672123520352462533919618013413921418017580247786207146671191391222241012676223862211932032538225125312112321324565815247581171811701960082185729519717916892103112515020411320611156519217543199292122720118562842293125154244186239213236203129333159198033165134206000
怎么處理??
uj5u.com熱心網友回復:
var datastr = Encoding.UTF8.GetString(temp)uj5u.com熱心網友回復:
怎么解出來倒成亂碼了。解壓后的結果:
" \b\0\0\0\0\0\0e Mo 0 H \a_* R @? R5,]. M& Mp \t ? ? { = yf < \buJSh ] M Q4 [ nz Qu U屆 g i \r30x,O (TG ]. I, f > R +4 \nX D7 [\a]N :\a4 8/ * Б > , \t E i 2^ ? 4V 7 5 D [ 8 ] ? L z(; 5J -T Se ? N vv} ?U * \\?? |z K j \v 2 ] 7\a \f\b 7\a x gM|? rt8 i\b* bU mZvNc4`8 v) \\ \0s\") '?2 pN}) \a \vvwA? 9X χ?C? ? u` S }\\R^ 1^- ,?)\r3 l- rd? u3 q ub!F8 \\ . L r qJ $N -q\r 8 Am 4T !\tT @\f] \f A 7/D(dH t=l m \"uW? F 1N( H1S p J q W , Z Y {N9 ?W gG @ r \n ag ?O ~AU · n [\0 :T V\0\0"
未解壓的結果:
POST /online/setpoint HTTP/1.1
Host: task.browser.360.cn
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE
Content-Length: 415
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/x-www-form-urlencoded
Cookie: __huid=11khu4UOkNItcw0XYdoGuzj9xf9ea7N7ZvDmUPTrujWKs=; __guid=132730903.365150465704162100.1562167421442.6685; Q=u%3D%25P3%25Q7__%25Q7%25Q3%26n%3DGBZ_%25P3%25Q7%26le%3Dqz9fnKEco24lZlH0ZUAinUHhL29g%26m%3DZGZ4WGWOWGWOWGWOWGWOWGWOBGN4%26qid%3D31402461%26im%3D1_t01150640f287e6dcf3%26src%3D360se%26t%3D1; T=s%3Df9a12f917a9dece863ec03ea517de5e0%26t%3D1559569266%26lm%3D%26lf%3D1%26sk%3D738c0d2059b5f03a187443ef2aac6eed%26mt%3D1559569266%26rc%3D2%26v%3D2.0%26a%3D1
Proxy-Connection: keep-alive
X-Lantern-Version: 5.5.0
uj5u.com熱心網友回復:
即然能讀出來,說明Gzip解碼沒問題,下一步,就要自已分析網路游戲的發包協議了。uj5u.com熱心網友回復:
而且,你這TcpPacke也沒有過濾,會收到很多包,建議過濾一下。uj5u.com熱心網友回復:
這個對
同時
這個也對。你終于開始深入靈魂了。
看看你自己的:
是不是上面說的,ok,你理解一下到底何謂http的gzip傳輸。 就像前面說的,
這兩句才是我關心的,http不是你認為的把協議包整個壓縮,整個壓縮你還怎么讀,我知道那是頭,那是尾。我能把一個zip包從中間開始解壓么?
這兩句就是告訴你
正文體長415位元組,使用gzip壓縮。
所以請找到正文體區域,往下度415位元組,這才是gzip壓縮過的資料。當然這個里面其實還有很多問題,你是pcap抓包,那個東西不認識http協議,他只知道ip資料包,所以如果正文體一包收不滿,可能有多個包。
so,自己慢慢做把。
uj5u.com熱心網友回復:
@wanghui0380 這么說有可能是我抓包不全,可能我只抓到了一部分包,得把整個包抓全了在決議。越聊越覺的pcap抓包里面好多東西不懂,迷茫。還得研究一下怎么把包抓全。
uj5u.com熱心網友回復:
包抓沒抓全,Content-Length: 415,你計算一下,就知道了,關鍵難點,主要在于分析游戲封包,這個非常費時,是個體力活。另外你發的包,前后并不一樣。并不是一個包。
uj5u.com熱心網友回復:
我們先不考慮多包,就當作一個包來接http實際基于文本。首先當文本,http基本格式,http包頭+空行+正文體
你貼出來的部分實際是http包頭
他和正文體部分用一個空行分割
所以一般步驟是先提出包頭,分析包頭資料,比如上面說的正文體長度,正文體格式
然后根據第一個空行定位,正文體開始部分,然后讀取包頭提示的正文長度,然后在根據格式去做相對應的決議。
ps:這塊東西理論上應該有成品,微軟自己一個有解的東西,應該在system.net.http這塊,因為微軟自己也需要這塊東西,不然他的asp.net,mvc,owin,httpclient都搞不了,他總不可能每一個都是獨立決議(這太2了)
uj5u.com熱心網友回復:
讓二位大神把我說的推翻我的全部思想,得從頭學起了。本以為抓到包就處理資料就完了,看來還有很多路要走。
按照@wanghui0380 所說我應該是抓到包了,但是抓到的是部分包它的亂碼還是和
之前的包有關系,因為我抓到的是不完整的包,所以無法決議。
我總感覺是這樣的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/128662.html
標籤:C#
下一篇:wpf動態配置問題
