从目前对JavaScript的使用来看,要加密它基本是不太可能的,而最有效的保护办法和对付.NET Assembly的反编译一样——就是混淆。为什么脚本要混淆啊?公司的产品代码和平时我们做些试验呀,做些控件共享啊,是不同的,需要有一定的保护要求。看看Gmail的JS,那个混淆效果,真TMD爽!
前段时间也在网上找了一些JavaScript的混淆器,不过都不太能满足目前项目的需求。于是就看看做一个JavaScript的代码格式化器和混淆器到底有多少障碍,在周末花了一个下午做了对表达式的识别器。下面看看对表达式的识别效果,再来说说是怎么设计的。
处理前的代码:
a > b; alert(); alert(
typeof (alert ) ); alert( ! strue);
a += f99( a$$, asdf)/3;
new[Object](0);
new Object();
var abc = [{a : 100 } . a, 1, [ ], abc]; alert({} + {a:
789.132-e1 ,c . b , b : c,d: e} +[';',100]. length+([
0].length+[5 ].length)); foo ( asf) ;foo2(foo(
), asf, foo(3)); foo3(foo2(foo(asf*34/ 34)*foo2(34+foo()
)-10)/foo());
var a ,c = 1 , b = 'a\'""' + 1 , asdf =
""a's'\'df"";
var c = b - 1 ; abc = 100 *100 /2+(a+1)+(
(a+ 1)+( a +1)+1); a -1;asdf () ;
当然,这都是语法正确的JavaScript代码。
处理后的代码:
蓝色:关键字 绿色:函数名 深灰:变量名 红褐:字符串
本来做这种工具最好的办法就是词法扫描,但是那样编程很繁琐,而且没有生成C#代码的 Lex吧
?所以设计了一个简化版的扫描模型,因为我只需要判断出
变量
(包括函数名)和
关键字就行了。
于是这样设计了一个ISentence接口,有两个方法:Parse()和Render(),以及两个属性,m_IsMatch和m_NextSentence。当一个Token被识被后,就转到下个识别中去,识别成功赋值给m_NextSentence,然后不断地深度递归,是否成功置于m_IsMatch,用于回退。ISentence定义如下:
Using directives
namespace JScriptConfusion.JScriptSyntax.Sentence
{
public
class ISentence
{
protected
bool m_IsMatch =
false;
protected ISentence m_NextSentence =
null;
public
virtual
bool IsMatch {
get {
return
this.m_IsMatch; } }
public ISentence() {}
public
virtual
string Parse(
string jscript)
{
jscript = jscript.TrimStart();
return jscript;
}
public
virtual
string Render()
{
return
string.Empty;
}
}
}
前段时间也在网上找了一些JavaScript的混淆器,不过都不太能满足目前项目的需求。于是就看看做一个JavaScript的代码格式化器和混淆器到底有多少障碍,在周末花了一个下午做了对表达式的识别器。下面看看对表达式的识别效果,再来说说是怎么设计的。
处理前的代码:
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
当然,这都是语法正确的JavaScript代码。
处理后的代码:
a>
b;
alert();
alert( typeof( alert));
alert(! strue);
a+= f99( a$$, asdf)/3;
new [ Object]; (0);
new Object();
var abc=[{ a:100}. a,1,[], abc];
alert({}+{ a:789.132- e1, c. b, b: c, d: e}+[ ';',100]. length+([0]. length+[5]. length));
foo( asf);
foo2( foo(), asf, foo(3));
foo3( foo2( foo( asf*34/34)* foo2(34+ foo())-10)/ foo());
var a, c=1, b= 'a\'"'+1, asdf= "a's'\'df";
var c= b-1;
abc=100*100/2+( a+1)+(( a+1)+( a+1)+1);
a-1;
asdf();
alert();
alert( typeof( alert));
alert(! strue);
a+= f99( a$$, asdf)/3;
new [ Object]; (0);
new Object();
var abc=[{ a:100}. a,1,[], abc];
alert({}+{ a:789.132- e1, c. b, b: c, d: e}+[ ';',100]. length+([0]. length+[5]. length));
foo( asf);
foo2( foo(), asf, foo(3));
foo3( foo2( foo( asf*34/34)* foo2(34+ foo())-10)/ foo());
var a, c=1, b= 'a\'"'+1, asdf= "a's'\'df";
var c= b-1;
abc=100*100/2+( a+1)+(( a+1)+( a+1)+1);
a-1;
asdf();
蓝色:关键字 绿色:函数名 深灰:变量名 红褐:字符串
本来做这种工具最好的办法就是词法扫描,但是那样编程很繁琐,而且没有生成C#代码的 Lex吧
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334105/20241017/061d7284dc484a4f9a79811f7f59cc69.gif)
于是这样设计了一个ISentence接口,有两个方法:Parse()和Render(),以及两个属性,m_IsMatch和m_NextSentence。当一个Token被识被后,就转到下个识别中去,识别成功赋值给m_NextSentence,然后不断地深度递归,是否成功置于m_IsMatch,用于回退。ISentence定义如下:
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334110/20241017/7bff2bc0788c45e6bd9afd135d4971cd.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/829f67b1a25747deb42f19d353c5843b.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334113/20241017/074cbf3a271d41db8e0be9f913dc4d15.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334113/20241017/074cbf3a271d41db8e0be9f913dc4d15.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334113/20241017/d107f85a13814ae48eb210d262e25675.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334113/20241017/074cbf3a271d41db8e0be9f913dc4d15.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334113/20241017/d107f85a13814ae48eb210d262e25675.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334113/20241017/d107f85a13814ae48eb210d262e25675.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/1704810d4b354992a5ec34f4e687ceda.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
不过在处理JavaScript的换行"\r\n"作为语句分割时,比较的郁闷,因为我都直接使用String.TrimStart()作的字符串预处理。
本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。