设计了一个JavaScript的源代码混淆器
从目前对JavaScript的使用来看,要加密它基本是不太可能的,而最有效的保护办法和对付.NET Assembly的反编译一样——就是混淆。为什么脚本要混淆啊?公司的产品代码和平时我们做些试验呀,做些控件共享啊,是不同的,需要有一定的保护要求。看看Gmail的JS,那个混淆效果,真TMD爽!
前段时间也在网上找了一些JavaScript的混淆器,不过都不太能满足目前项目的需求。于是就看看做一个JavaScript的代码格式化器和混淆器到底有多少障碍,在周末花了一个下午做了对表达式的识别器。下面看看对表达式的识别效果,再来说说是怎么设计的。
处理前的代码:
当然,这都是语法正确的JavaScript代码。
处理后的代码:
蓝色:关键字 绿色:函数名 深灰:变量名 红褐:字符串
本来做这种工具最好的办法就是词法扫描,但是那样编程很繁琐,而且没有生成C#代码的Lex吧?所以设计了一个简化版的扫描模型,因为我只需要判断出变量(包括函数名)和关键字就行了。
于是这样设计了一个ISentence接口,有两个方法:Parse()和Render(),以及两个属性,m_IsMatch和m_NextSentence。当一个Token被识被后,就转到下个识别中去,识别成功赋值给m_NextSentence,然后不断地深度递归,是否成功置于m_IsMatch,用于回退。ISentence定义如下:
不过在处理JavaScript的换行"\r\n"作为语句分割时,比较的郁闷,因为我都直接使用String.TrimStart()作的字符串预处理。
到目前进度的源代码下载,欢迎您的意见和建议。除了能实现外,最好还能编程最便捷。:)
前段时间也在网上找了一些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 () ;
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代码。
处理后的代码:
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吧?所以设计了一个简化版的扫描模型,因为我只需要判断出变量(包括函数名)和关键字就行了。
于是这样设计了一个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;
}
}
}
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的换行"\r\n"作为语句分割时,比较的郁闷,因为我都直接使用String.TrimStart()作的字符串预处理。
到目前进度的源代码下载,欢迎您的意见和建议。除了能实现外,最好还能编程最便捷。:)
posted on 2005-03-16 00:52 birdshome 阅读(7601) 评论(13) 编辑 收藏 举报