• JS混淆助手类


    先看效果:

    string js = @"var a=1
                  alert(a);//注释1
                  alert(a);/*注释2*/";
    string result = PackBus.PackJavascript(js).Replace("
    ", "
    ");
    
    result:
    eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fr.............
    

    助手类:

    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Text;
    using System.Text.RegularExpressions;
    
    /*
        packer, version 2.0 (beta) (2005/02/01)
        Copyright 2004-2005, Dean Edwards
        Web: http://dean.edwards.name/
    
        This software is licensed under the CC-GNU LGPL
        Web: http://creativecommons.org/licenses/LGPL/2.1/
        
        Ported to C# by Jesse Hansen, twindagger2k@msn.com
    
        http://dean.edwards.name/packer/
    */
    
    namespace MeShop.Web.Pack
    {
        /// <summary>
        /// Packs a javascript file into a smaller area, removing unnecessary characters from the output.
        /// </summary>
        public class ECMAScriptPacker
        {
            /// <summary>
            /// The encoding level to use. See http://dean.edwards.name/packer/usage/ for more info.
            /// </summary>
            public enum PackerEncoding { None = 0, Numeric = 10, Mid = 36, Normal = 62, HighAscii = 95 };
    
            private PackerEncoding encoding = PackerEncoding.Normal;
            private bool fastDecode = true;
            private bool specialChars = false;
            private bool enabled = true;
    
            string IGNORE = "$1";
    
            /// <summary>
            /// The encoding level for this instance
            /// </summary>
            public PackerEncoding Encoding
            {
                get { return encoding; }
                set { encoding = value; }
            }
    
            /// <summary>
            /// Adds a subroutine to the output to speed up decoding
            /// </summary>
            public bool FastDecode
            {
                get { return fastDecode; }
                set { fastDecode = value; }
            }
    
            /// <summary>
            /// Replaces special characters
            /// </summary>
            public bool SpecialChars
            {
                get { return specialChars; }
                set { specialChars = value; }
            }
    
            /// <summary>
            /// Packer enabled
            /// </summary>
            public bool Enabled
            {
                get { return enabled; }
                set { enabled = value; }
            }
    
            public ECMAScriptPacker()
            {
                Encoding = PackerEncoding.Normal;
                FastDecode = true;
                SpecialChars = false;
            }
    
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="encoding">The encoding level for this instance</param>
            /// <param name="fastDecode">Adds a subroutine to the output to speed up decoding</param>
            /// <param name="specialChars">Replaces special characters</param>
            public ECMAScriptPacker(PackerEncoding encoding, bool fastDecode, bool specialChars)
            {
                Encoding = encoding;
                FastDecode = fastDecode;
                SpecialChars = specialChars;
            }
    
            /// <summary>
            /// Packs the script
            /// </summary>
            /// <param name="script">the script to pack</param>
            /// <returns>the packed script</returns>
            public string Pack(string script)
            {
                if (enabled)
                {
                    script += "
    ";
                    script = basicCompression(script);
                    if (SpecialChars)
                        script = encodeSpecialChars(script);
                    if (Encoding != PackerEncoding.None)
                        script = encodeKeywords(script);
                }
                return script;
            }
    
            //zero encoding - just removal of whitespace and comments
            private string basicCompression(string script)
            {
                ParseMaster parser = new ParseMaster();
                // make safe
                parser.EscapeChar = '\';
                // protect strings
                parser.Add("'[^'\n\r]*'", IGNORE);
                parser.Add(""[^"\n\r]*"", IGNORE);
                // remove comments
                parser.Add("\/\/[^\n\r]*[\n\r]");
                parser.Add("\/\*[^*]*\*+([^\/][^*]*\*+)*\/");
                // protect regular expressions
                parser.Add("\s+(\/[^\/\n\r\*][^\/\n\r]*\/g?i?)", "$2");
                parser.Add("[^\w\$\/'"*)\?:]\/[^\/\n\r\*][^\/\n\r]*\/g?i?", IGNORE);
                // remove: ;;; doSomething();
                if (specialChars)
                    parser.Add(";;[^\n\r]+[\n\r]");
                // remove redundant semi-colons
                parser.Add(";+\s*([};])", "$2");
                // remove white-space
                parser.Add("(\b|\$)\s+(\b|\$)", "$2 $3");
                parser.Add("([+\-])\s+([+\-])", "$2 $3");
                parser.Add("\s+");
                // done
                return parser.Exec(script);
            }
    
            WordList encodingLookup;
            private string encodeSpecialChars(string script)
            {
                ParseMaster parser = new ParseMaster();
                // replace: $name -> n, $$name -> na
                parser.Add("((\$+)([a-zA-Z\$_]+))(\d*)",
                    new ParseMaster.MatchGroupEvaluator(encodeLocalVars));
    
                // replace: _name -> _0, double-underscore (__name) is ignored
                Regex regex = new Regex("\b_[A-Za-z\d]\w*", RegexOptions.None, TimeSpan.FromSeconds(2));
    
                // build the word list
                encodingLookup = analyze(script, regex, new EncodeMethod(encodePrivate));
    
                parser.Add("\b_[A-Za-z\d]\w*", new ParseMaster.MatchGroupEvaluator(encodeWithLookup));
    
                script = parser.Exec(script);
                return script;
            }
    
            private string encodeKeywords(string script)
            {
                // escape high-ascii values already in the script (i.e. in strings)
                if (Encoding == PackerEncoding.HighAscii) script = escape95(script);
                // create the parser
                ParseMaster parser = new ParseMaster();
                EncodeMethod encode = getEncoder(Encoding);
    
                // for high-ascii, don't encode single character low-ascii
                Regex regex = new Regex(
                        (Encoding == PackerEncoding.HighAscii) ? "\w\w+" : "\w+", RegexOptions.None, TimeSpan.FromSeconds(2)
                    );
                // build the word list
                encodingLookup = analyze(script, regex, encode);
    
                // encode
                parser.Add((Encoding == PackerEncoding.HighAscii) ? "\w\w+" : "\w+",
                    new ParseMaster.MatchGroupEvaluator(encodeWithLookup));
    
                // if encoded, wrap the script in a decoding function
                return (script == string.Empty) ? "" : bootStrap(parser.Exec(script), encodingLookup);
            }
    
            private string bootStrap(string packed, WordList keywords)
            {
                // packed: the packed script
                packed = "'" + escape(packed) + "'";
    
                // ascii: base for encoding
                int ascii = Math.Min(keywords.Sorted.Count, (int)Encoding);
                if (ascii == 0)
                    ascii = 1;
    
                // count: number of words contained in the script
                int count = keywords.Sorted.Count;
    
                // keywords: list of words contained in the script
                foreach (object key in keywords.Protected.Keys)
                {
                    keywords.Sorted[(int)key] = "";
                }
                // convert from a string to an array
                StringBuilder sbKeywords = new StringBuilder("'");
                foreach (string word in keywords.Sorted)
                    sbKeywords.Append(word + "|");
                sbKeywords.Remove(sbKeywords.Length - 1, 1);
                string keywordsout = sbKeywords.ToString() + "'.split('|')";
    
                string encode;
                string inline = "c";
    
                switch (Encoding)
                {
                    case PackerEncoding.Mid:
                        encode = "function(c){return c.toString(36)}";
                        inline += ".toString(a)";
                        break;
                    case PackerEncoding.Normal:
                        encode = "function(c){return(c<a?"":e(parseInt(c/a)))+" +
                            "((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))}";
                        inline += ".toString(a)";
                        break;
                    case PackerEncoding.HighAscii:
                        encode = "function(c){return(c<a?"":e(c/a))+" +
                            "String.fromCharCode(c%a+161)}";
                        inline += ".toString(a)";
                        break;
                    default:
                        encode = "function(c){return c}";
                        break;
                }
    
                // decode: code snippet to speed up decoding
                string decode = "";
                if (fastDecode)
                {
                    decode = "if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;}";
                    if (Encoding == PackerEncoding.HighAscii)
                        decode = decode.Replace("\\w", "[\xa1-\xff]");
                    else if (Encoding == PackerEncoding.Numeric)
                        decode = decode.Replace("e(c)", inline);
                    if (count == 0)
                        decode = decode.Replace("c=1", "c=0");
                }
    
                // boot function
                string unpack = "function(p,a,c,k,e,d){while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}";
                Regex r;
                if (fastDecode)
                {
                    //insert the decoder
                    r = new Regex("\{", RegexOptions.None, TimeSpan.FromSeconds(2));
                    unpack = r.Replace(unpack, "{" + decode + ";", 1);
                }
    
                if (Encoding == PackerEncoding.HighAscii)
                {
                    // get rid of the word-boundries for regexp matches
                    r = new Regex("'\\\\b'\s*\+|\+\s*'\\\\b'", RegexOptions.None, TimeSpan.FromSeconds(2));
                    unpack = r.Replace(unpack, "");
                }
                if (Encoding == PackerEncoding.HighAscii || ascii > (int)PackerEncoding.Normal || fastDecode)
                {
                    // insert the encode function
                    r = new Regex("\{", RegexOptions.None, TimeSpan.FromSeconds(2));
                    unpack = r.Replace(unpack, "{e=" + encode + ";", 1);
                }
                else
                {
                    r = new Regex("e\(c\)", RegexOptions.None, TimeSpan.FromSeconds(2));
                    unpack = r.Replace(unpack, inline);
                }
                // no need to pack the boot function since i've already done it
                string _params = "" + packed + "," + ascii + "," + count + "," + keywordsout;
                if (fastDecode)
                {
                    //insert placeholders for the decoder
                    _params += ",0,{}";
                }
                // the whole thing
                return "eval(" + unpack + "(" + _params + "))
    ";
            }
    
            private string escape(string input)
            {
                Regex r = new Regex("([\\'])", RegexOptions.None, TimeSpan.FromSeconds(2));
                return r.Replace(input, "\$1");
            }
    
            private EncodeMethod getEncoder(PackerEncoding encoding)
            {
                switch (encoding)
                {
                    case PackerEncoding.Mid:
                        return new EncodeMethod(encode36);
                    case PackerEncoding.Normal:
                        return new EncodeMethod(encode62);
                    case PackerEncoding.HighAscii:
                        return new EncodeMethod(encode95);
                    default:
                        return new EncodeMethod(encode10);
                }
            }
    
            private string encode10(int code)
            {
                return code.ToString();
            }
    
            //lookups seemed like the easiest way to do this since 
            // I don't know of an equivalent to .toString(36)
            private static string lookup36 = "0123456789abcdefghijklmnopqrstuvwxyz";
    
            private string encode36(int code)
            {
                string encoded = "";
                int i = 0;
                do
                {
                    int digit = (code / (int)Math.Pow(36, i)) % 36;
                    encoded = lookup36[digit] + encoded;
                    code -= digit * (int)Math.Pow(36, i++);
                } while (code > 0);
                return encoded;
            }
    
            private static string lookup62 = lookup36 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
            private string encode62(int code)
            {
                string encoded = "";
                int i = 0;
                do
                {
                    int digit = (code / (int)Math.Pow(62, i)) % 62;
                    encoded = lookup62[digit] + encoded;
                    code -= digit * (int)Math.Pow(62, i++);
                } while (code > 0);
                return encoded;
            }
    
            private static string lookup95 = "、¥ウЖ┆���辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬���";
    
            private string encode95(int code)
            {
                string encoded = "";
                int i = 0;
                do
                {
                    int digit = (code / (int)Math.Pow(95, i)) % 95;
                    encoded = lookup95[digit] + encoded;
                    code -= digit * (int)Math.Pow(95, i++);
                } while (code > 0);
                return encoded;
            }
    
            private string escape95(string input)
            {
                Regex r = new Regex("[xa1-xff]", RegexOptions.None, TimeSpan.FromSeconds(2));
                return r.Replace(input, new MatchEvaluator(escape95Eval));
            }
    
            private string escape95Eval(Match match)
            {
                return "\x" + ((int)match.Value[0]).ToString("x"); //return hexadecimal value
            }
    
            private string encodeLocalVars(Match match, int offset)
            {
                int length = match.Groups[offset + 2].Length;
                int start = length - Math.Max(length - match.Groups[offset + 3].Length, 0);
                return match.Groups[offset + 1].Value.Substring(start, length) +
                    match.Groups[offset + 4].Value;
            }
    
            private string encodeWithLookup(Match match, int offset)
            {
                return (string)encodingLookup.Encoded[match.Groups[offset].Value];
            }
    
            private delegate string EncodeMethod(int code);
    
            private string encodePrivate(int code)
            {
                return "_" + code;
            }
    
            private WordList analyze(string input, Regex regex, EncodeMethod encodeMethod)
            {
                // analyse
                // retreive all words in the script
                MatchCollection all = regex.Matches(input);
                WordList rtrn;
                rtrn.Sorted = new StringCollection(); // list of words sorted by frequency
                rtrn.Protected = new HybridDictionary(); // dictionary of word->encoding
                rtrn.Encoded = new HybridDictionary(); // instances of "protected" words
                if (all.Count > 0)
                {
                    StringCollection unsorted = new StringCollection(); // same list, not sorted
                    HybridDictionary Protected = new HybridDictionary(); // "protected" words (dictionary of word->"word")
                    HybridDictionary values = new HybridDictionary(); // dictionary of charCode->encoding (eg. 256->ff)
                    HybridDictionary count = new HybridDictionary(); // word->count
                    int i = all.Count, j = 0;
                    string word;
                    // count the occurrences - used for sorting later
                    do
                    {
                        word = "$" + all[--i].Value;
                        if (count[word] == null)
                        {
                            count[word] = 0;
                            unsorted.Add(word);
                            // make a dictionary of all of the protected words in this script
                            //  these are words that might be mistaken for encoding
                            Protected["$" + (values[j] = encodeMethod(j))] = j++;
                        }
                        // increment the word counter
                        count[word] = (int)count[word] + 1;
                    } while (i > 0);
                    /* prepare to sort the word list, first we must protect
                        words that are also used as codes. we assign them a code
                        equivalent to the word itself.
                       e.g. if "do" falls within our encoding range
                            then we store keywords["do"] = "do";
                       this avoids problems when decoding */
                    i = unsorted.Count;
                    string[] sortedarr = new string[unsorted.Count];
                    do
                    {
                        word = unsorted[--i];
                        if (Protected[word] != null)
                        {
                            sortedarr[(int)Protected[word]] = word.Substring(1);
                            rtrn.Protected[(int)Protected[word]] = true;
                            count[word] = 0;
                        }
                    } while (i > 0);
                    string[] unsortedarr = new string[unsorted.Count];
                    unsorted.CopyTo(unsortedarr, 0);
                    // sort the words by frequency
                    Array.Sort(unsortedarr, (IComparer)new CountComparer(count));
                    j = 0;
                    /*because there are "protected" words in the list
                      we must add the sorted words around them */
                    do
                    {
                        if (sortedarr[i] == null)
                            sortedarr[i] = unsortedarr[j++].Substring(1);
                        rtrn.Encoded[sortedarr[i]] = values[i];
                    } while (++i < unsortedarr.Length);
                    rtrn.Sorted.AddRange(sortedarr);
                }
                return rtrn;
            }
    
            private struct WordList
            {
                public StringCollection Sorted;
                public HybridDictionary Encoded;
                public HybridDictionary Protected;
            }
    
            private class CountComparer : IComparer
            {
                HybridDictionary count;
    
                public CountComparer(HybridDictionary count)
                {
                    this.count = count;
                }
    
                #region IComparer Members
    
                public int Compare(object x, object y)
                {
                    return (int)count[y] - (int)count[x];
                }
    
                #endregion
            }
        }
    }
    
    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Text;
    using System.Text.RegularExpressions;
    
    /*
        ParseMaster, version 1.0 (pre-release) (2005/02/01) x4
        Copyright 2005, Dean Edwards
        Web: http://dean.edwards.name/
    
        This software is licensed under the CC-GNU LGPL
        Web: http://creativecommons.org/licenses/LGPL/2.1/
    
        Ported to C# by Jesse Hansen, twindagger2k@msn.com
    */
    
    namespace MeShop.Web.Pack
    {
        /// <summary>
        /// a multi-pattern parser
        /// </summary>
        public class ParseMaster
        {
            // used to determine nesting levels
            Regex GROUPS = new Regex("\(", RegexOptions.None, TimeSpan.FromSeconds(2)),
                SUB_REPLACE = new Regex("\$", RegexOptions.None, TimeSpan.FromSeconds(2)),
                INDEXED = new Regex("^\$\d+$", RegexOptions.None, TimeSpan.FromSeconds(2)),
                ESCAPE = new Regex("\\.", RegexOptions.None, TimeSpan.FromSeconds(2)),
                QUOTE = new Regex("'", RegexOptions.None, TimeSpan.FromSeconds(2)),
                DELETED = new Regex("\x01[^\x01]*\x01", RegexOptions.None, TimeSpan.FromSeconds(2));
    
            /// <summary>
            /// Delegate to call when a regular expression is found.
            /// Use match.Groups[offset + &lt;group number&gt;].Value to get
            /// the correct subexpression
            /// </summary>
            public delegate string MatchGroupEvaluator(Match match, int offset);
    
            private string DELETE(Match match, int offset)
            {
                return "x01" + match.Groups[offset].Value + "x01";
            }
    
            private bool ignoreCase = false;
            private char escapeChar = '';
    
            /// <summary>
            /// Ignore Case?
            /// </summary>
            public bool IgnoreCase
            {
                get { return ignoreCase; }
                set { ignoreCase = value; }
            }
    
            /// <summary>
            /// Escape Character to use
            /// </summary>
            public char EscapeChar
            {
                get { return escapeChar; }
                set { escapeChar = value; }
            }
    
            /// <summary>
            /// Add an expression to be deleted
            /// </summary>
            /// <param name="expression">Regular Expression String</param>
            public void Add(string expression)
            {
                Add(expression, string.Empty);
            }
    
            /// <summary>
            /// Add an expression to be replaced with the replacement string
            /// </summary>
            /// <param name="expression">Regular Expression String</param>
            /// <param name="replacement">Replacement String. Use $1, $2, etc. for groups</param>
            public void Add(string expression, string replacement)
            {
                if (replacement == string.Empty)
                    add(expression, new MatchGroupEvaluator(DELETE));
    
                add(expression, replacement);
            }
    
            /// <summary>
            /// Add an expression to be replaced using a callback function
            /// </summary>
            /// <param name="expression">Regular expression string</param>
            /// <param name="replacement">Callback function</param>
            public void Add(string expression, MatchGroupEvaluator replacement)
            {
                add(expression, replacement);
            }
    
            /// <summary>
            /// Executes the parser
            /// </summary>
            /// <param name="input">input string</param>
            /// <returns>parsed string</returns>
            public string Exec(string input)
            {
                return DELETED.Replace(unescape(getPatterns().Replace(escape(input), new MatchEvaluator(replacement))), string.Empty);
                //long way for debugging
                /*input = escape(input);
                Regex patterns = getPatterns();
                input = patterns.Replace(input, new MatchEvaluator(replacement));
                input = DELETED.Replace(input, string.Empty);
                return input;*/
            }
    
            ArrayList patterns = new ArrayList();
            private void add(string expression, object replacement)
            {
                Pattern pattern = new Pattern();
                pattern.expression = expression;
                pattern.replacement = replacement;
                //count the number of sub-expressions
                // - add 1 because each group is itself a sub-expression
                pattern.length = GROUPS.Matches(internalEscape(expression)).Count + 1;
    
                //does the pattern deal with sup-expressions?
                if (replacement is string && SUB_REPLACE.IsMatch((string)replacement))
                {
                    string sreplacement = (string)replacement;
                    // a simple lookup (e.g. $2)
                    if (INDEXED.IsMatch(sreplacement))
                    {
                        pattern.replacement = int.Parse(sreplacement.Substring(1)) - 1;
                    }
                }
    
                patterns.Add(pattern);
            }
    
            /// <summary>
            /// builds the patterns into a single regular expression
            /// </summary>
            /// <returns></returns>
            private Regex getPatterns()
            {
                StringBuilder rtrn = new StringBuilder(string.Empty);
                foreach (object pattern in patterns)
                {
                    rtrn.Append(((Pattern)pattern).ToString() + "|");
                }
                rtrn.Remove(rtrn.Length - 1, 1);
                return new Regex(rtrn.ToString(), ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None, TimeSpan.FromSeconds(2));
            }
    
            /// <summary>
            /// Global replacement function. Called once for each match found
            /// </summary>
            /// <param name="match">Match found</param>
            private string replacement(Match match)
            {
                int i = 1, j = 0;
                Pattern pattern;
                //loop through the patterns
                while (!((pattern = (Pattern)patterns[j++]) == null))
                {
                    //do we have a result?
                    if (match.Groups[i].Value != string.Empty)
                    {
                        object replacement = pattern.replacement;
                        if (replacement is MatchGroupEvaluator)
                        {
                            return ((MatchGroupEvaluator)replacement)(match, i);
                        }
                        else if (replacement is int)
                        {
                            return match.Groups[(int)replacement + i].Value;
                        }
                        else
                        {
                            //string, send to interpreter
                            return replacementString(match, i, (string)replacement, pattern.length);
                        }
                    }
                    else //skip over references to sub-expressions
                        i += pattern.length;
                }
                return match.Value; //should never be hit, but you never know
            }
    
            /// <summary>
            /// Replacement function for complicated lookups (e.g. Hello $3 $2)
            /// </summary>
            private string replacementString(Match match, int offset, string replacement, int length)
            {
                while (length > 0)
                {
                    replacement = replacement.Replace("$" + length--, match.Groups[offset + length].Value);
                }
                return replacement;
            }
    
            private StringCollection escaped = new StringCollection();
    
            //encode escaped characters
            private string escape(string str)
            {
                if (escapeChar == '')
                    return str;
                Regex escaping = new Regex("\\(.)", RegexOptions.None, TimeSpan.FromSeconds(2));
                return escaping.Replace(str, new MatchEvaluator(escapeMatch));
            }
    
            private string escapeMatch(Match match)
            {
                escaped.Add(match.Groups[1].Value);
                return "\";
            }
    
            //decode escaped characters
            private int unescapeIndex = 0;
            private string unescape(string str)
            {
                if (escapeChar == '')
                    return str;
                Regex unescaping = new Regex("\" + escapeChar, RegexOptions.None, TimeSpan.FromSeconds(2));
                return unescaping.Replace(str, new MatchEvaluator(unescapeMatch));
            }
    
            private string unescapeMatch(Match match)
            {
                return "\" + escaped[unescapeIndex++];
            }
    
            private string internalEscape(string str)
            {
                return ESCAPE.Replace(str, "");
            }
    
            //subclass for each pattern
            private class Pattern
            {
                public string expression;
                public object replacement;
                public int length;
    
                public override string ToString()
                {
                    return "(" + expression + ")";
                }
            }
        }
    }
    
  • 相关阅读:
    java 变量的初始化顺序
    Asp.net MVC3.0 入门指南 1.简介
    使用EnterpriseLibrary5实现数据的缓存(附完整代码下载)
    js showModalDialog 取得(访问)父窗体的语法
    Asp.net MVC3.0 入门指南 2.控制器Controller
    linq 之入门(一) O/R设计器的使用
    sql2000 示例数据库Northwind的 ER图、字段说明及使用Powerdesigner反向工程方法
    局域网共享文件win7系统
    远程桌面 不能粘贴文本 的解决办法
    解决vs2005控件事件为空白
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/13914294.html
Copyright © 2020-2023  润新知