如何编程检测JavaScript混淆?

3

我修改了你的问题,因为请求库是被禁止的,这会导致你得到很多关闭/下降的票数。 - Benjamin Gruenbaum
虽然实际上,那篇论文所说的应该已经足够了,但他们只是基于下载的代码进行了分类器的训练,然后与最小化的代码混淆。 - Benjamin Gruenbaum
嗨,本杰明,我正在寻找一种更通用的方法,可以正确地处理新的(或调整过的)混淆器。我不知道该怎么做,希望这里的某个人可以帮助我。 - karpada
但是他们在文章中提到的方法将正确处理新的或调整过的混淆器。 - Benjamin Gruenbaum
也许我没有理解这篇论文,第4节指出他们选择了特征"c&0x1f"和"z >>> 5"。如果使用新的混淆器避免这些特征,它仍然有效吗? - karpada
显示剩余3条评论
1个回答

8

这里没有什么可谈的。

但首先,让我们问一个问题:什么是压缩代码?

好吧,那不太难。维基百科 上有解释!但它没有解释如何实现压缩代码。

基本上,您需要尽可能减少代码量,但保持相同的功能。

让我们分析一些代码!

var times;

times = window.prompt('Insert a number','5');

times = parseInt( times, 10 );

if( !isNaN(times) )
{
  for(var i=0; i<=10; i=i+1 )
  {
    document.write(times + ' &times; ' + i + ' = ' + ( i * times) + '<br/>');
  }
}
else
{
  alert('Invalid number');
}

现在,我们可以大大缩减那些代码!这就是所谓的代码压缩。现在,让我们来看看这段代码:

var i=0,t=window.prompt('Insert a number',5);if(t/1==t/1)for(;i<11;i++)document.write(t+' &times; '+i+' = '+(i*t)+'<br/>');else alert('Invalid number');

它完全一样!但是短得多
我做了什么:
  • 减少变量名长度
  • 同时声明变量
  • 减少将值赋给变量的次数
  • 将字符串'5'替换为数字5
  • 删除不必要的parseInt()
  • t/1==t/1替换!isNaN(times)
    如果不是数字,t/1将是NaN.
    如果运行NaN==NaN,结果为false
  • 删除空格(空格、换行符)
  • 删除大括号
这段代码可以进一步缩小,但是你可以(有点难度)看到其功能。
还有更多减少代码大小的技巧,但我不会详细介绍。

现在又有一个问题:什么是混淆代码?

混淆代码是我们无法理解的代码。

你可以阅读代码,但其功能不容易被理解。

这比缩小尺寸要复杂得多。缩小尺寸并非必需。

但是,大多数情况下,混淆代码是以一种你无法理解的方式进行缩小的。

只有那些知道的人才能理解它。

JSF*ck就是一个例子。

使用2个在线工具,以下是混淆代码的样子:

使用http://www.jsobfuscate.com/ 进行混淆:

eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('4 2;2=d.e(\'c a 3\',\'5\');2=b(2,6);7(!8(2)){9(4 i=0;i<=6;i=i+1){h.j(2+\' &2; \'+i+\' = \'+(i*2)+\'<f/>\')}}k{l(\'g 3\')}',22,22,'||times|number|var||10|if|isNaN|for||parseInt|Insert|window|prompt|br|Invalid|document||write|else|alert'.split('|'),0,{}))

使用http://packer.50x.eu/进行混淆:

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(c/a))+String.fromCharCode(c%a+161)};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\[\xa1-\xff]+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp(e(c),'g'),k[c])}}return p}('£ ¡;¡=©.¨(\'§ a ¢\',\'5\');¡=¥(¡,¤);¦(!ª(¡)){«(£ i=0;i<=¤;i=i+1){®.¬(¡+\' &¡; \'+i+\' = \'+(i*¡)+\'<±/>\')}}­{¯(\'° ¢\')}',17,17,'times|number|var|10|parseInt|if|Insert|prompt|window|isNaN|for|write|else|document|alert|Invalid|br'.split('|'),0,{}))

使用这些工具,有一些相似之处:
  • 两者都有一个eval()
  • 两者都创建一个包含变量p,a,c,k,e,d的函数。
  • 两者都在结尾处拥有一个属性和其他东西的列表。
  • 两者都使用字符串魔法来生成代码。
但是,所有混淆代码都相等吗?不!它们并不相等。
以下是一个例子:

var ________________ = [] + []; var _ = +[]; _++; var _____ = _ + _;
var ___ = _____ + _____; var __ = ___ + ___; var ____ = __ + __; var ______ = ____ + ____;
var _______ = ______ + _; var ___________ = ______ + ______ + __;
var ______________ = ___________ + ____ -  _; var ____________ = _ + _____;
var ________ = _______ * ____________ + _; var _________ = ________ + _;
var _____________ = ______________ + ______ - ___ - _; var __________ = _____________ -
____________; var _______________ = __________ - ____________; document.write(________________ +
String.fromCharCode(___________, _________, _______________, _______________, __________,
______, ______________, __________, _____________, _______________, ________, _______));

这段内容来自另一个网站。你可以在这里查看原始答案: https://codegolf.stackexchange.com/a/22746/14732 如何区分? 你根本无法区分。或者你是一个超级天才,能够看到混淆的代码并知道它的作用。
你需要一个非常聪明的算法才能知道代码的作用。然后反向重建它。 如果两个代码不一样,则可能被混淆。
结论:你无法区分混淆代码和缩小后的代码。

嗨,伊斯梅尔,我也没能成功解决这个问题。感谢你的帮助和分析! - karpada
@karpada 不用谢。只花了一个小时写完它。 - Ismael Miguel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接