From 681714731d9bb71a7d37d5b9b44b39f19b735c1b Mon Sep 17 00:00:00 2001 From: tfarley Date: Sun, 22 Jan 2017 00:00:28 -0800 Subject: [PATCH] Add highlighting option --- aclogview/Form1.Designer.cs | 23 +++- aclogview/Form1.cs | 243 +++++++++++++++++++++++++++++------- 2 files changed, 220 insertions(+), 46 deletions(-) diff --git a/aclogview/Form1.Designer.cs b/aclogview/Form1.Designer.cs index 76438d8..dc20aef 100644 --- a/aclogview/Form1.Designer.cs +++ b/aclogview/Form1.Designer.cs @@ -34,7 +34,7 @@ private void InitializeComponent() { this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.splitContainer_Bottom = new System.Windows.Forms.SplitContainer(); - this.textBox_PacketData = new System.Windows.Forms.TextBox(); + this.textBox_PacketData = new System.Windows.Forms.RichTextBox(); this.treeView_ParsedData = new System.Windows.Forms.TreeView(); this.mainMenu = new System.Windows.Forms.MainMenu(this.components); this.menuItem_File = new System.Windows.Forms.MenuItem(); @@ -47,6 +47,7 @@ private void InitializeComponent() { this.pictureBox_Search = new System.Windows.Forms.PictureBox(); this.statusStrip = new System.Windows.Forms.StatusStrip(); this.checkBox_HideHeaderOnly = new System.Windows.Forms.CheckBox(); + this.checkBox_useHighlighting = new System.Windows.Forms.CheckBox(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer_Main)).BeginInit(); this.splitContainer_Main.Panel1.SuspendLayout(); this.splitContainer_Main.Panel2.SuspendLayout(); @@ -160,10 +161,10 @@ private void InitializeComponent() { this.textBox_PacketData.Dock = System.Windows.Forms.DockStyle.Fill; this.textBox_PacketData.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.textBox_PacketData.Location = new System.Drawing.Point(0, 0); - this.textBox_PacketData.Multiline = true; this.textBox_PacketData.Name = "textBox_PacketData"; this.textBox_PacketData.Size = new System.Drawing.Size(1126, 487); this.textBox_PacketData.TabIndex = 0; + this.textBox_PacketData.Text = ""; // // treeView_ParsedData // @@ -172,6 +173,7 @@ private void InitializeComponent() { this.treeView_ParsedData.Name = "treeView_ParsedData"; this.treeView_ParsedData.Size = new System.Drawing.Size(382, 487); this.treeView_ParsedData.TabIndex = 0; + this.treeView_ParsedData.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_ParsedData_AfterSelect); // // mainMenu // @@ -255,11 +257,24 @@ private void InitializeComponent() { this.checkBox_HideHeaderOnly.Visible = false; this.checkBox_HideHeaderOnly.CheckedChanged += new System.EventHandler(this.checkBox_HideHeaderOnly_CheckedChanged); // + // checkBox_useHighlighting + // + this.checkBox_useHighlighting.Checked = true; + this.checkBox_useHighlighting.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_useHighlighting.Location = new System.Drawing.Point(949, 2); + this.checkBox_useHighlighting.Name = "checkBox_useHighlighting"; + this.checkBox_useHighlighting.Size = new System.Drawing.Size(156, 17); + this.checkBox_useHighlighting.TabIndex = 4; + this.checkBox_useHighlighting.Text = "Use Highlighting (Slower!)"; + this.checkBox_useHighlighting.UseVisualStyleBackColor = true; + this.checkBox_useHighlighting.CheckedChanged += new System.EventHandler(this.checkBox_useHighlighting_CheckedChanged); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1520, 964); + this.Controls.Add(this.checkBox_useHighlighting); this.Controls.Add(this.checkBox_HideHeaderOnly); this.Controls.Add(this.splitContainer_Main); this.Controls.Add(this.textBox_Search); @@ -276,7 +291,6 @@ private void InitializeComponent() { ((System.ComponentModel.ISupportInitialize)(this.splitContainer_Main)).EndInit(); this.splitContainer_Main.ResumeLayout(false); this.splitContainer_Bottom.Panel1.ResumeLayout(false); - this.splitContainer_Bottom.Panel1.PerformLayout(); this.splitContainer_Bottom.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer_Bottom)).EndInit(); this.splitContainer_Bottom.ResumeLayout(false); @@ -301,7 +315,7 @@ private void InitializeComponent() { private System.Windows.Forms.TextBox textBox_Search; private System.Windows.Forms.PictureBox pictureBox_Search; private System.Windows.Forms.StatusStrip statusStrip; - private System.Windows.Forms.TextBox textBox_PacketData; + private System.Windows.Forms.RichTextBox textBox_PacketData; private System.Windows.Forms.ColumnHeader columnHeader1; private System.Windows.Forms.ColumnHeader columnHeader2; private System.Windows.Forms.ColumnHeader columnHeader3; @@ -311,6 +325,7 @@ private void InitializeComponent() { private System.Windows.Forms.ColumnHeader columnHeader7; private System.Windows.Forms.TreeView treeView_ParsedData; private System.Windows.Forms.CheckBox checkBox_HideHeaderOnly; + private System.Windows.Forms.CheckBox checkBox_useHighlighting; } } diff --git a/aclogview/Form1.cs b/aclogview/Form1.cs index 7c2411f..34283c6 100644 --- a/aclogview/Form1.cs +++ b/aclogview/Form1.cs @@ -65,6 +65,7 @@ class PacketRecord { public string packetHeadersStr; public string packetTypeStr; public byte[] data; + public int optionalHeadersLen; public NetPacket netPacket; public PacketOpcode opcode; public string extraInfo; @@ -88,7 +89,9 @@ private void readPacket(PacketRecord packet, StringBuilder packetTypeStr, Binary } } - private void readOptionalHeaders(uint header_, StringBuilder packetHeadersStr, BinaryReader packetReader) { + private void readOptionalHeaders(PacketRecord packet, uint header_, StringBuilder packetHeadersStr, BinaryReader packetReader) { + long readStartPos = packetReader.BaseStream.Position; + if ((header_ & CServerSwitchStructHeader.mask) != 0) { CServerSwitchStruct serverSwitchStruct = CServerSwitchStruct.read(packetReader); if (packetHeadersStr.Length != 0) { @@ -239,6 +242,8 @@ private void readOptionalHeaders(uint header_, StringBuilder packetHeadersStr, B } packetHeadersStr.Append("Flow"); } + + packet.optionalHeadersLen = (int)(packetReader.BaseStream.Position - readStartPos); } List records = new List(); @@ -276,7 +281,7 @@ private void loadPcap(string fileName) { try { ProtoHeader pHeader = ProtoHeader.read(packetReader); - readOptionalHeaders(pHeader.header_, packetHeadersStr, packetReader); + readOptionalHeaders(packet, pHeader.header_, packetHeadersStr, packetReader); if (packetReader.BaseStream.Position == packetReader.BaseStream.Length) { packetTypeStr.Append("
"); @@ -363,64 +368,213 @@ public int CompareString(string x, string y) { } private void updateData() { + updateText(); + updateTree(); + } + + private void updateText() { + textBox_PacketData.Clear(); + if (listView_Packets.SelectedIndices.Count > 0) { PacketRecord record = records[Int32.Parse(listItems[listView_Packets.SelectedIndices[0]].SubItems[0].Text)]; byte[] data = record.data; - StringBuilder strBuilder = new StringBuilder(); - StringBuilder hexBuilder = new StringBuilder(); - StringBuilder asciiBuilder = new StringBuilder(); - int wrapCounter = 0; - for (int i = 0; i < data.Length; ++i) { - if (wrapCounter == 0) { - strBuilder.Append(string.Format("{0:X4} ", i)); - } + if (checkBox_useHighlighting.Checked) { + int fragStartPos = 20 + record.optionalHeadersLen; + int curFrag = 0; + int curLine = 0; + int dataConsumed = 0; + while (dataConsumed < data.Length) { + textBox_PacketData.SelectionColor = Color.Black; + textBox_PacketData.AppendText(string.Format("{0:X4} ", curLine)); + + int lineFragStartPos = fragStartPos; + int linecurFrag = curFrag; + + int hexIndex = 0; + for (; hexIndex < Math.Min(16, data.Length - dataConsumed); ++hexIndex) { + if (hexIndex == 8) { + textBox_PacketData.AppendText(" "); + } - hexBuilder.Append(string.Format("{0:X2} ", data[i])); + int dataIndex = dataConsumed + hexIndex; - char asChar = Convert.ToChar(data[i]); - if (asChar >= ' ' && asChar <= '~') { - asciiBuilder.Append(asChar); - } else { - asciiBuilder.Append('.'); - } + int selectedIndex = -1; + TreeNode selectedNode = treeView_ParsedData.SelectedNode; + if (selectedNode != null) { + while (selectedNode.Parent != null) { + selectedNode = selectedNode.Parent; + } + selectedIndex = selectedNode.Index; + } - wrapCounter++; - if (wrapCounter == 8) { - hexBuilder.Append(' '); - asciiBuilder.Append(' '); - } else if (wrapCounter == 16) { - strBuilder.Append(hexBuilder.ToString()); - hexBuilder.Clear(); + // Default color + textBox_PacketData.SelectionColor = Color.Red; + textBox_PacketData.SelectionBackColor = Color.White; + + if (dataIndex < 20) { + // Protocol header + textBox_PacketData.SelectionColor = Color.Blue; + } else if (dataIndex < 20 + record.optionalHeadersLen) { + // Optional headers + textBox_PacketData.SelectionColor = Color.Green; + } else if (record.netPacket.fragList_.Count > 0) { + if (curFrag < record.netPacket.fragList_.Count) { + int fragCurPos = dataIndex - fragStartPos; + if (fragCurPos < 16) { + // Fragment header + textBox_PacketData.SelectionColor = Color.Magenta; + } else if (fragCurPos == (16 + record.netPacket.fragList_[curFrag].dat_.Length)) { + // Next fragment + fragStartPos = dataIndex; + curFrag++; + textBox_PacketData.SelectionColor = Color.Magenta; + } else { + // Fragment data + textBox_PacketData.SelectionColor = Color.Black; + } - strBuilder.Append(' '); + if (selectedIndex == curFrag) { + textBox_PacketData.SelectionBackColor = Color.LightGray; + } + } + } - strBuilder.Append(asciiBuilder.ToString()); - asciiBuilder.Clear(); + textBox_PacketData.AppendText(string.Format("{0:X2} ", data[dataIndex])); + } + + textBox_PacketData.SelectionBackColor = Color.White; + StringBuilder spaceAligner = new StringBuilder(); + spaceAligner.Append(' ', 1 + (16 - hexIndex) * 3 + (hexIndex <= 8 ? 1 : 0)); + textBox_PacketData.AppendText(spaceAligner.ToString()); + + fragStartPos = lineFragStartPos; + curFrag = linecurFrag; + + for (int i = 0; i < Math.Min(16, data.Length - dataConsumed); ++i) { + if (i == 8) { + textBox_PacketData.AppendText(" "); + } + + int dataIndex = dataConsumed + i; + + int selectedIndex = -1; + TreeNode selectedNode = treeView_ParsedData.SelectedNode; + if (selectedNode != null) { + while (selectedNode.Parent != null) { + selectedNode = selectedNode.Parent; + } + selectedIndex = selectedNode.Index; + } + + // Default color + textBox_PacketData.SelectionColor = Color.Red; + textBox_PacketData.SelectionBackColor = Color.White; + + if (dataIndex < 20) { + // Protocol header + textBox_PacketData.SelectionColor = Color.Blue; + } else if (dataIndex < 20 + record.optionalHeadersLen) { + // Optional headers + textBox_PacketData.SelectionColor = Color.Green; + } else if (record.netPacket.fragList_.Count > 0) { + if (curFrag < record.netPacket.fragList_.Count) { + int fragCurPos = dataIndex - fragStartPos; + if (fragCurPos < 16) { + // Fragment header + textBox_PacketData.SelectionColor = Color.Magenta; + } else if (fragCurPos == (16 + record.netPacket.fragList_[curFrag].dat_.Length)) { + // Next fragment + fragStartPos = dataIndex; + curFrag++; + textBox_PacketData.SelectionColor = Color.Magenta; + } else { + // Fragment data + textBox_PacketData.SelectionColor = Color.Black; + } + + if (selectedIndex == curFrag) { + textBox_PacketData.SelectionBackColor = Color.LightGray; + } + } + } + + char asChar = Convert.ToChar(data[dataIndex]); + if (asChar >= ' ' && asChar <= '~') { + textBox_PacketData.AppendText(Char.ToString(asChar)); + } else { + textBox_PacketData.AppendText("."); + } + } - strBuilder.Append(Environment.NewLine); + textBox_PacketData.AppendText("\n"); - wrapCounter = 0; + dataConsumed += 16; + curLine++; } - } + } else { + StringBuilder strBuilder = new StringBuilder(); + StringBuilder hexBuilder = new StringBuilder(); + StringBuilder asciiBuilder = new StringBuilder(); + int wrapCounter = 0; + for (int i = 0; i < data.Length; ++i) { + if (wrapCounter == 0) { + strBuilder.Append(string.Format("{0:X4} ", i)); + } + + hexBuilder.Append(string.Format("{0:X2} ", data[i])); - if (wrapCounter != 0) { - int spacesToAppend = (16 - wrapCounter) * 3; - if (wrapCounter < 8) { - spacesToAppend++; + char asChar = Convert.ToChar(data[i]); + if (asChar >= ' ' && asChar <= '~') { + asciiBuilder.Append(asChar); + } else { + asciiBuilder.Append('.'); + } + + wrapCounter++; + if (wrapCounter == 8) { + hexBuilder.Append(' '); + asciiBuilder.Append(' '); + } else if (wrapCounter == 16) { + strBuilder.Append(hexBuilder.ToString()); + hexBuilder.Clear(); + + strBuilder.Append(' '); + + strBuilder.Append(asciiBuilder.ToString()); + asciiBuilder.Clear(); + + strBuilder.Append(Environment.NewLine); + + wrapCounter = 0; + } } - hexBuilder.Append(' ', spacesToAppend); + if (wrapCounter != 0) { + int spacesToAppend = (16 - wrapCounter) * 3; + if (wrapCounter < 8) { + spacesToAppend++; + } - strBuilder.Append(hexBuilder.ToString()); + hexBuilder.Append(' ', spacesToAppend); - strBuilder.Append(' '); + strBuilder.Append(hexBuilder.ToString()); + + strBuilder.Append(' '); + + strBuilder.Append(asciiBuilder.ToString()); + } - strBuilder.Append(asciiBuilder.ToString()); + textBox_PacketData.Text = strBuilder.ToString(); } + } + } - textBox_PacketData.Text = strBuilder.ToString(); + private void updateTree() { + treeView_ParsedData.Nodes.Clear(); + if (listView_Packets.SelectedIndices.Count > 0) { + PacketRecord record = records[Int32.Parse(listItems[listView_Packets.SelectedIndices[0]].SubItems[0].Text)]; foreach (BlobFrag frag in record.netPacket.fragList_) { BinaryReader fragDataReader = new BinaryReader(new MemoryStream(frag.dat_)); @@ -453,9 +607,6 @@ private void updateData() { treeView_ParsedData.Nodes.Add(new TreeNode("EXCEPTION: " + e.Message)); } } - } else { - textBox_PacketData.Text = ""; - treeView_ParsedData.Nodes.Clear(); } } @@ -475,5 +626,13 @@ private void listView_Packets_RetrieveVirtualItem(object sender, RetrieveVirtual private void menuItem_About_Click(object sender, EventArgs e) { MessageBox.Show("aclogview\n\nA program to view and parse Asheron's Call 1 packet capture files (.pcap) generated by aclog.\n\nFor more info and source code, see https://github.com/tfarley/aclogview", "About"); } + + private void treeView_ParsedData_AfterSelect(object sender, TreeViewEventArgs e) { + updateText(); + } + + private void checkBox_useHighlighting_CheckedChanged(object sender, EventArgs e) { + updateText(); + } } }