ViewState解码分析器

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Web.UI;
using System.Collections;
using System.Xml;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace ViewState解码分析器
{
    public partial class Form1 : Form
    {
        TextBox textbox = null;
        public Form1()
        {
            InitializeComponent();
        }

        private void txtViewState_Leave(object sender, EventArgs e)
        {
            textbox = (TextBox)sender;
        }

        private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
        {
            if (textbox == null)
            {
                textbox = txtViewState;
            }
            textbox.Focus();
        }

        #region 对输入的ViewState字符串进行解码分析 + private void txtDecoder_Click(object sender, EventArgs e)
        private void txtDecoder_Click(object sender, EventArgs e)
        {
            XmlDocument document = null;
            string vs = get__ViewCodeString(txtViewState.Text.Trim());//获取待解码的ViewState字符串
            if (string.IsNullOrEmpty(vs)) return;

            byte[] buff = Encoding.UTF8.GetBytes(vs);
            Stream stream = new MemoryStream(buff);
            try
            {
                LosFormatter lf = new LosFormatter();
                object allViewState = lf.Deserialize(stream);//解码
                XmlDocument dom = ViewStateXmlBuilder.BuildXml(allViewState);
                StringBuilder sb = new StringBuilder();
                using (StringWriter writer = new StringWriter(sb))
                {
                    dom.Save(writer);
                }
                txtResult.Text = sb.ToString();
            }
            catch (Exception er)
            {
                MessageBox.Show(er.Message, "解析错误", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        #endregion

        #region 简化显示ViewState解码后的内容 + private void btnSimple_Click(object sender, EventArgs e)
        private void btnSimple_Click(object sender, EventArgs e)
        {
            string s = Regex.Replace(txtResult.Text, "<[^>]+>", "");
            txtResult.Text = Regex.Replace(s, @"(?m)^\s+{1}quot;, "\r\n");
        } 
        #endregion

        #region 窗体加载时设置Panel2的最小宽度 + private void Form1_Load(object sender, EventArgs e)
        private void Form1_Load(object sender, EventArgs e)
        {
            splitContainer1.Panel2MinSize = 430;//设置Panel2的最小宽度
        } 
        #endregion

        #region 获取正确的待解码的ViewState + private string get__ViewCodeString(string s)
        /// <summary>
        /// 获取正确的待解码的ViewState
        /// </summary>
        /// <param name="s">可能含有“引号外多余内容”的ViewState串</param>
        /// <returns></returns>
        private string get__ViewCodeString(string s)
        {
            int p1 = s.IndexOf('"');
            if (p1 >= 0)//若不含双引号,则取整串内容
            {
                int p2 = s.IndexOf('"', p1 + 1);
                if (p2 > 0)//有一对双引号,则取双引号内部的东东
                {
                    s = s.Substring(p1 + 1, p2 - p1 - 1);
                }
                else//若仅有一个双引号,则取引号两侧较长的字符串
                {
                    string s1 = s.Substring(0, p1).Trim();
                    string s2 = s.Substring(p1 + 1).Trim();
                    s = s1.Length > s2.Length ? s1 : s2;
                }
            }
            return s;
        }
        #endregion
    }


    #region 类ViewStateXmlBuilder,创建ViewState XMLDocument
    public class ViewStateXmlBuilder
    {
        public static XmlDocument BuildXml(object tree)
        {
            XmlDocument dom = new XmlDocument();
            dom.AppendChild(dom.CreateElement("ViewState"));
            BuildElement(dom, dom.DocumentElement, tree);
            return dom;
        }

        private static void BuildElement(XmlDocument dom, XmlElement elem, object treeNode)
        {
            if (treeNode != null)
            {
                XmlElement element;
                Type type = treeNode.GetType();
                if (type == typeof(Pair))
                {
                    element = dom.CreateElement(GetShortTypename(treeNode));
                    elem.AppendChild(element);
                    BuildElement(dom, element, ((Pair)treeNode).First);
                    BuildElement(dom, element, ((Pair)treeNode).Second);
                }
                else if (type == typeof(Triplet))
                {
                    element = dom.CreateElement(GetShortTypename(treeNode));
                    elem.AppendChild(element);
                    BuildElement(dom, element, ((Triplet)treeNode).First);
                    BuildElement(dom, element, ((Triplet)treeNode).Second);
                    BuildElement(dom, element, ((Triplet)treeNode).Third);
                }
                else if (type == typeof(ArrayList))
                {
                    element = dom.CreateElement(GetShortTypename(treeNode));
                    elem.AppendChild(element);
                    foreach (object obj in (ArrayList)treeNode)
                    {
                        BuildElement(dom, element, obj);
                    }
                }
                else if (treeNode is Array)
                {
                    element = dom.CreateElement("Array");
                    elem.AppendChild(element);
                    foreach (object obj in (Array)treeNode)
                    {
                        BuildElement(dom, element, obj);
                    }
                }
                else if (treeNode is HybridDictionary)
                {
                    element = dom.CreateElement(GetShortTypename(treeNode));
                    dom.DocumentElement.AppendChild(element);
                    foreach (object obj in (HybridDictionary)treeNode)
                    {
                        BuildElement(dom, element, obj);
                    }
                }
                else if (treeNode is DictionaryEntry)
                {
                    element = dom.CreateElement(GetShortTypename(treeNode));
                    elem.AppendChild(element);
                    DictionaryEntry entry = (DictionaryEntry)treeNode;
                    BuildElement(dom, element, entry.Key);
                    BuildElement(dom, element, entry.Value);
                }
                else
                {
                    element = dom.CreateElement(GetShortTypename(treeNode));
                    if (type == typeof(IndexedString))
                    {
                        element.InnerText = ((IndexedString)treeNode).Value;
                    }
                    else
                    {
                        element.InnerText = treeNode.ToString();
                    }
                    elem.AppendChild(element);
                }
            }
        }

        private static string GetShortTypename(object obj)
        {
            string str = obj.GetType().ToString();
            return str.Substring(str.LastIndexOf(".") + 1);
        }
    }
    #endregion
}


 

通过对Page类的分析研究,对ViewState的组织结构有了进一步的了解。编写此程序,方便对ViewStste的分析,以便有效控制文件大小。

 

可能还存在其他的一些问题,目前发现的有:

 

原来开发的Web系统,比如VS2003、2005可能存在ViewState无法解码,难道不同VS版本间生成的ViewState稍有不同?

 

有时间,再研究 LosFormatte.Deserialize() 方法得到进一步的解释。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值