你这个问题与 PCap 抓包没什么关系啊,纯粹是解压缩问题。TCP 包头是有规范的,不是随便搞的,一般业务层也不需要处理包头信息。

解决方案 »

  1.   

    @datafansbj  我也知道是解压缩的问题。
    但是这个确实和抓包有一定关联。
    var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);这步我抓到包了,但是怎么解析啊!这是困扰我很久的问题。
    我用尽了方法都不行,请大神给个思路。
      

  2.   

    给一堆字节数组 byte[] 要你解析,没有头绪谁也不会,至少要知道解析的东西大概是什么吧。是压缩数据?文本?视频?音频?
      

  3.   


    文本,抓到的数据就是问题文本。目前就是文本乱码。
    var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
    就在这条语句乱的。tcpPacket.PayloadData 主要是对它解析。没有思路。
      

  4.   

    如果确定是未加密的文本,那么乱码问题就好解决了,使用适当的 Encoding 解码。
    如果确认是 utf8 格式的,应使用下述方式解码:
    UTF8Encoding   encoding   =   new UTF8Encoding();
    string datastr = encoding.GetString(tcpPacket.PayloadData);
      

  5.   

    果然是灵魂写手。你那边怎么写的,怎么发的不知道。你问我们这边怎么写,怎么接,怎么解。好,那我问问,你基于什么啊,udp,tcp,http,基于何种协议mqtt,grpc,json
    你怎么发的,把整包数据压缩,还是只把数据部分压缩。
    如果说整包压缩,udp还有解。tcp就算了,udp一个包就是一个包,我知道头尾,直接解压就好但是tcp,整包压缩。我连头尾都不知道,怎么解???
    话说你看看人家http把头部xxxx:xxxx/gzip ,
    数据包长:xxxx
    数据区:xxxxxxx这才有解,我知道他是gzip,知道一共有多长。你问我们tcpPacket.Header不知道怎么办,我们知道怎么办,你把tHeader都压了,我知道头在那里???
      

  6.   

    在则:tcpPacket.Header ,pcap,那么请问你觉着这个tcpPacket.Header到底表达何意???你觉着pcap到底是个何种软件。那个是个抓封包的,不是一个抓协议的。
    tcpPacket.Header 抓的是tcp/ip底层的原始头,不是你上层的协议头。
    什么那个是一个gzip,底层链路层管你什么gzip么。那个是ip报文头,不是协议报文头
      

  7.   

    来看看随手的例子
    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 5555if (pcap.sendPacket(packet) != Pcap.OK) {
        System.err.println(pcap.getErr());
    }很,明显这是什么?这是ip数据报报文头,而不是应用协议层报文头
      

  8.   


    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
     我把完整代码贴出来,请参看。
      

  9.   

    如果你确定是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         }
      

  10.   

     你的这句117行要改一下,先解压后,如果是UTF-8,再调用var datastr = Encoding.UTF8.GetString(tcpPacket.PayloadData);
                        //主要是这里我已经获取到数据了,只是乱码,只需要解码.不需要分析等等。
                        //重申只需要把乱码解开即可,把乱码解开
      

  11.   


    我用这个方法解压了。用了以下方法读成string。byte[] temp= Compress(tcpPacket.PayloadData);
                        string st = "";
                        foreach (byte b in temp) {
                            st += b.ToString();
                        }
    读出来都是这样的值:
    3113980000040120604925523330201000000064246282512141331613119178202114471201503725517714122124516118819775191482501611379413878841131830133164444025541915628177210207012270197236212142321411079910515567483254112161356183234271421332910212418410901591143612222910539141611018011249285672123520352462533919618013413921418017580247786207146671191391222241012676223862211932032538225125312112321324565815247581171811701960082185729519717916892103112515020411320611156519217543199292122720118562842293125154244186239213236203129333159198033165134206000怎么处理??
      

  12.   

    var datastr = Encoding.UTF8.GetString(temp)
      

  13.   

    怎么解出来倒成乱码了。
    解压后的结果:
    " \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 Ý {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
      

  14.   

    即然能读出来,说明Gzip解码没问题,下一步,就要自已分析网络游戏的发包协议了。
      

  15.   

    而且,你这TcpPacke也没有过滤,会收到很多包,建议过滤一下。
      

  16.   

    这个对同时这个也对。你终于开始深入灵魂了。看看你自己的:是不是上面说的,ok,你理解一下到底何谓http的gzip传输。 就像前面说的,这两句才是我关心的,http不是你认为的把协议包整个压缩,整个压缩你还怎么读,我知道那是头,那是尾。我能把一个zip包从中间开始解压么?这两句就是告诉你
    正文体长415字节,使用gzip压缩。所以请找到正文体区域,往下度415字节,这才是gzip压缩过的数据。当然这个里面其实还有很多问题,你是pcap抓包,那个东西不认识http协议,他只知道ip数据包,所以如果正文体一包收不满,可能有多个包。so,自己慢慢做把。
      

  17.   

    @wanghui0380 这么说有可能是我抓包不全,可能我只抓到了一部分包,得把整个包抓全了在解析。越聊越觉的pcap抓包里面好多东西不懂,迷茫。还得研究一下怎么把包抓全。
      

  18.   

    包抓没抓全,Content-Length: 415,你计算一下,就知道了,关键难点,主要在于分析游戏封包,这个非常费时,是个体力活。
    另外你发的包,前后并不一样。并不是一个包。
      

  19.   

    我们先不考虑多包,就当作一个包来接http实际基于文本。首先当文本,http基本格式,http包头+空行+正文体
    你贴出来的部分实际是http包头
    他和正文体部分用一个空行分割所以一般步骤是先提出包头,分析包头数据,比如上面说的正文体长度,正文体格式然后根据第一个空行定位,正文体开始部分,然后读取包头提示的正文长度,然后在根据格式去做相对应的解析。ps:这块东西理论上应该有成品,微软自己一个有解的东西,应该在system.net.http这块,因为微软自己也需要这块东西,不然他的asp.net,mvc,owin,httpclient都搞不了,他总不可能每一个都是独立解析(这太2了)
      

  20.   

    让二位大神把我说的推翻我的全部思想,得从头学起了。本以为抓到包就处理数据就完了,看来还有很多路要走。按照@wanghui0380  所说我应该是抓到包了,但是抓到的是部分包它的乱码还是和
    之前的包有关系,因为我抓到的是不完整的包,所以无法解析。我总感觉是这样的。