JavaScript - 如何在每次调用后跟随功能并更改其目的?

3
我是一名有用的助手,可以为您翻译文本。
我正在开发一个简单的JavaScript代码混淆器。假设您有一个NxN的二维正方形矩阵,其中包含JavaScript函数。当n=3时:
var m = [
   [function(){return 1}, function(){return 2}, function(){return 3}],
   [function(){return 4}, function(){return 5}, function(){return 6}],
   [function(){return 7}, function(){return 8}, function(){return 9}]
]

现在,在这个例子中,每个函数实际上都包含了需要混淆的代码块,并调用它。一个典型的混淆代码看起来像这样:

(function(){ m[1][2](m[2][0](m[0][1]))(m[1][0])(m[2][2])(m[1][1](m[1][2](m[2][0]))); }());

上面的代码可以翻译成这样:

(function(){ 6( 7(2) )( 4 )( 9 )( 5( 6( 7 ) ) ); }());

当然,假设一个典型的 m[x][y] 返回所需的函数或其他内容,这将非常容易被解读。因此,在每个 m[x][y] 调用之后,m[x][y] 将与 m[x+1][y-1] 交换位置,后者将在其轮到时与 m[0][2] 交换位置,基本上我想把它们混合得那么糟糕,你甚至不敢尝试去解密。可能使用随机生成的数学公式,按照函数执行。
重点是混淆器需要预先知道这个公式,以便它知道要调用哪个 m[x][y],在哪个点上决定调用顺序,并决定函数加入的顺序。一个可行的实现甚至可能会产生:

(function( m[0][0](m[0][0](m[0][0]))(m[0][0]) ))

并仍然工作。所以我的问题是:
  1. How can I split javascript code into smaller functions? I know compilers basically do that, but I also seen some on-line JS beautifiers, and syntax highlighters being able to distinguish code and do their thing properly. I mean can basic regex do the job?

  2. This doesn't work and it should:

    window.a = function(x){ 
        var r = x*2; 
        window.a =alert; // redefines itself after first call
        return r;
    }; 
    a('2 * 2 = ' + a(2)); // doesn't work. it should've alerted "2 * 2 = 4"
    

    This on the other hand does work:

    var i = 0;
    window.a = function(x){ 
        if(i===1){
            i=0;
            return alert(x); 
        }
    
        i=1;
        return x*2; 
    }; 
    a('2 * 2='+a(2));
    

    Why?

  3. Are there any similar on-going projects? Maybe I can get some notes or reference to them.

1个回答

2

首先恭喜你所做的事情。这有点疯狂,但几乎是非常聪明的。

问题1:

我不知道你是如何做到的。我已经花了一些时间思考同样的原理。

问题2:

你的第一个例子不起作用,因为第一个调用它的是 a("2 * 2 = " + x),其中 x 将是第二个调用,所以当第一个 a 被调用时,你会得到一个 NaN,因为你给它一个 String

问题3:

类似的项目?嗯,让我想想... 我想每个人都有自己的项目,因为代码是可见的。实际的来源我不知道。

建议:

您可以将这个平方的2D矩阵视为3D魔方,这样您就可以对其进行洗牌和解决。有趣的部分是,您可以将一系列动作组合起来,实际上成为一个大函数来完成某些操作。无论如何,我认为这种事情的最佳解决方案可能是复制然后删除JS语言的主要对象,并将其存储在匿名函数内的复杂图表中,没有人可以进入其中进行混乱,至于代码是否可读,我认为这是一种艺术。


对于(2),我也尝试了另一种方式,但也不起作用。我会在单独的问题中提出这个问题,因为我觉得它非常有趣。 - Silviu-Marian
1
@GRIGORE-TURBODISEL 三年后我才重新阅读这篇文章。对于问题2,答案很简单:因为行 a('2*2=' + a(2)) 实际上将原始函数 a 放在堆栈中两次。即使在第一次调用之后 a 重新定义自己,您也无法操纵已经在堆栈上的操作。因此,在这种情况下,原始 a 被调用了两次而不是一次。制作多态代码很困难,但是如果考虑到这一点并进行一些类型检查,它可能是某些实现的好主意,但应保持在任何生产环境之外。 - helly0d

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