《Flappy Pig》被高手破解,代码分析

2014-03-30 · 477 chars · 3 min read

2014-11-14 更新:

其实那段“乱七八糟”的代码不是手写的,可以使用jjencode这个工具生成。

正文:

今天早晨刚起来,看到一个朋友(@Laix)的留言,他留了一段“奇怪的代码”,说在控制台执行会发生神奇的事情:

_=~[];_={___:++_,$$$$:(![]+"")[_],__$:++_,$_$_:(![]+"")[_],_$_:++_,$_$$:({}+"")[_],$$_$:(_[_]+"")[_],_$$:++_,$$$_:(!""+"")[_],$__:++_,$_$:++_,$$__:({}+"")[_],$$_:++_,$$$:++_,$___:++_,$__$:++_};_.$_=(_.$_=_+"")[_.$_$]+(_._$=_.$_[_.__$])+(_.$$=(_.$+"")[_.__$])+((!_)+"")[_._$$]+(_.__=_.$_[_.$$_])+(_.$=(!""+"")[_.__$])+(_._=(!""+"")[_._$_])+_.$_[_.$_$]+_.__+_._$+_.$;_.$$=_.$+(!""+"")[_._$$]+_.__+_._+_.$+_.$$;_.$=(_.___)[_.$_][_.$_];_.$(_.$(_.$$+"\""+_.$$$$+(![]+"")[_._$_]+_.$_$_+"\\"+_.__$+_.$$_+_.___+"\\"+_.__$+_.$$_+_.___+"\\"+_.__$+_.$$$+_.__$+".\\"+_.__$+_.$_$+_.__$+"\\"+_.__$+_.$_$+_.$$_+"\\"+_.__$+_.$_$+_.__$+_.__+"();"+"\"")())();

这一坨乱七八糟的代码,甚至连个字母都没有。我还是打开Flappy Pig试了一下(chrome 或者 firefox 打开,F12 呼出开发者工具,输入上面的代码,回车):

之后按空格键开始游戏~~~~~神奇的事情果然发生了,小猪无敌了,撞在柱子上不会死~~~~~~

下面分析下这位高手是怎么做到的

首先把那段奇怪的 javascript“美化”一下:

_ = ~ [];
_ = {
    ___: ++_,
    $$$$: (![] + "")[_],
    __$: ++_,
    $_$_: (![] + "")[_],
    _$_: ++_,
    $_$$: ({} + "")[_],
    $$_$: (_[_] + "")[_],
    _$$: ++_,
    $$$_: (!"" + "")[_],
    $__: ++_,
    $_$: ++_,
    $$__: ({} + "")[_],
    $$_: ++_,
    $$$: ++_,
    $___: ++_,
    $__$: ++_
};
_.$_ = (_.$_ = _ + "")[_.$_$] + (_._$ = _.$_[_.__$]) + (_.$$ = (_.$ + "")[_.__$]) + ((!_) + "")[_._$$] + (_.__ = _.$_[_.$$_]) + (_.$ = (!"" + "")[_.__$]) + (_._ = (!"" + "")[_._$_]) + _.$_[_.$_$] + _.__ + _._$ + _.$;
_.$$ = _.$ + (!"" + "")[_._$$] + _.__ + _._ + _.$ + _.$$;
_.$ = (_.___)[_.$_][_.$_];
_.$(_.$(_.$$ + "\"" + _.$$$$ + (![] + "")[_._$_] + _.$_$_ + "\\" + _.__$ + _.$$_ + _.___ + "\\" + _.__$ + _.$$_ + _.___ + "\\" + _.__$ + _.$$$ + _.__$ + ".\\" + _.__$ + _.$_$ + _.__$ + "\\" + _.__$ + _.$_$ + _.$$_ + "\\" + _.__$ + _.$_$ + _.__$ + _.__ + "();" + "\"")())();

可以看出,其实_是个变量(我们平时不会这么命名变量),~ []就是-1(大家可以执行下,不要问我为什么),以此类推,代码可以进一步“美化”(虽然这一步跨的有点大):

_ = ~ [];
_ = {
    $$$: 7
    $$$$: "f"
    $$$_: "e"
    $$_: 6
    $$_$: "d"
    $$__: "c"
    $_$: 5
    $_$$: "b"
    $_$_: "a"
    $__: 4
    $__$: 9
    $___: 8
    _$$: 3
    _$_: 2
    __$: 1
    ___: 0
};
_.$_ = "constructor";
_.$$ = "return"
_.$ = (0)[constructor][constructor];
0["constructor"]["constructor"](
    0["constructor"]["constructor"](
        "flappy.init()"
    )()
)();

最关键的代码就是后面的(0)[constructor][constructor],他实质上是执行了flappy.init(),关于(0)[constructor][constructor]的分析看这里,那么我们再次打开flappy pig,打开开发者工具,执行flappy.init()

没错,“小猪”无敌了。

总结:#

1、其实核心的就是执行一句话flappy.init(),这是我的疏忽,再一次初始化游戏,会产生 bug,小猪就无敌了。

2、这位高手用很复杂代码,各种拼凑,让我这种菜鸟各种看不懂的执行了flappy.init()

3、我的 javascript 还是没学懂

4、@Laix 你还真是顽皮啊。

赞赏

微信