AST实战|手把手教你还原ob混淆:ob混淆代码特征

ob混淆过的代码有那些特征?

特征一: 大数组 + 移位自执行函数 + 解密字符串函数

下面的代码是一个之前我在官网上混淆的一个例子:

可以看到,大数组为变量 _0x33fc,移位自执行函数体比较大,其实化简后有效的就这么点:

(function(_0x40b128, _0x10e158) {
    var _0x1c0044 = function(_0x1cab6b) {
        while (--_0x1cab6b) {
            _0x40b128['push'](_0x40b128['shift']());
        }
    }
    _0x21186e = function(_0x44fcdc, _0x2309cd) {
        _0x44fcdc(++_0x2309cd);
    }
    ;
    _0x21186e(_0x1c0044, _0x10e158);
}(_0x33fc, -0xa25 + 0x1436 * -0x1 + 0x1f96));

具体的化简过程可以参考我的这篇文章: JS逆向时碰到了恶心的死代码怎么办?手把手教你解决!

而解密函数是 _0x14b7,因为后面有很多地方会调用这个函数。

特征二: 定义的Object,其key和value很有规律

var _0x22e4cc = {};
_0x22e4cc["_0x2e7dd3"] = function(_0x16ad58, _0x5d4167) {
    return _0x16ad58 === _0x5d4167;
};
_0x22e4cc['_0x1b1554'] = "string";
_0x22e4cc["_0x2ab7a2"] = function(_0x120b76, _0x5482f3) {
    return _0x120b76 !== _0x5482f3;
};
_0x22e4cc["_0x16d15a"] = function(_0x35fd52, _0xb88db7) {
    return _0x35fd52 + _0xb88db7;
};
_0x22e4cc["_0x267303"] = function(_0x516608, _0x46e9cb) {
    return _0x516608 / _0x46e9cb;
};
_0x22e4cc["_0x179f12"] = 'length';
_0x22e4cc["_0x4f8e92"] = function(_0xafceb, _0x3c43b9) {
    return _0xafceb % _0x3c43b9;
}
;
_0x22e4cc["_0x3fba04"] = function(_0x3c0262, _0x3c50b7) {
    return _0x3c0262 + _0x3c50b7;
}
;
_0x22e4cc["_0x158e00"] = "debu";
_0x22e4cc["_0x1203cd"] = "action";
_0x22e4cc["_0x50462a"] = "gger";
_0x22e4cc["_0x3e6826"] = "stateObject";
_0x22e4cc["_0x3fcd8d"] = function(_0x2c50a6, _0x24e706) {
    return _0x2c50a6(_0x24e706);
};

上面代码所示的Object变量为 _0x22e4cc,其key值长度是一样的,而它对应的value要么是字符串,要么是函数,其返回结构也是非常简单。

特征三: while + switch 组合

var _0x5ee804 = '4|5|3|0|2|1'['split']('|')
  , _0x572cee = 0;
while (!![]) {
    switch (_0x5ee804[_0x572cee++]) {
    case '0':
        _0xdedd5["__proto__"] = _0x2f44f0['bind'](_0x2f44f0);
        continue;


    case '1':
        _0x39a3d5[_0x359747] = _0xdedd5;
        continue;


    case '2':
        _0xdedd5['toString'] = _0x1941e5["toString"]["bind"](_0x1941e5);
        continue;


    case '3':
        var _0x1941e5 = _0x39a3d5[_0x359747] || _0xdedd5;


        continue;


    case '4':
        var _0xdedd5 = _0x2f44f0["constructor"]['prototype']["bind"](_0x2f44f0);


        continue;


    case '5':
        var _0x359747 = _0x195f0c[_0x301b17];
        continue;
    }
    break;
}


看到这个特征,相信大部分人都看到过,一个很简单的控制流平坦化,而且,ob混淆的控制流平坦化基本都是这样,还没见过不一样的。哪天要是在case语句中修改case值,就不好弄咯。

特征四: 一些干扰调试的垃圾代码

如:

setInterval(function () {
  _0x5dcd51();
}, 4000);
function _0x5dcd51(_0x712948) {
  function _0x441fc1(_0x2aae3c) {
    if (typeof _0x2aae3c === "string") return function (_0x1430b6) {}["constructor"]("while (true) {}")["apply"]('counter');else ('' + _0x2aae3c / _0x2aae3c)["length"] !== 1 || _0x2aae3c % 20 === 0 ? function () {
      return true;
    }['constructor']("debugger")["call"]("action") : function () {
      return false;
    }["constructor"]("debugger")['apply']("stateObject");


    _0x441fc1(++_0x2aae3c);
  }


  try {
    if (_0x712948) return _0x441fc1;else _0x441fc1(0);
  } catch (_0x219393) {}
}

也有类似这样的:

var _0x4bea14 = _0x46c669(this, function() {
    function _0x139538() {
        var _0x1664a7;


        try {
            _0x1664a7 = Function("return (function() {}.constructor(\"return this\")( ));")();
        } catch (_0x1d7d81) {
            _0x1664a7 = window;
        }


        return _0x1664a7;
    }


    var _0x1f8e02 = _0x139538();


    var _0x4fd052 = _0x1f8e02["console"] = _0x1f8e02["console"] || {};


    var _0x1d2e26 = ["log", "warn", "info", "error", "exception", "table", "trace"];


    for (var _0x3f35ef = 0; _0x3f35ef < _0x1d2e26["length"]; _0x3f35ef++) {
        var _0x4cca25 = _0x46c669["constructor"]["prototype"]["bind"](_0x46c669);


        var _0x11486c = _0x1d2e26[_0x3f35ef];


        var _0x29f6cb = _0x4fd052[_0x11486c] || _0x4cca25;


        _0x4cca25["__proto__"] = _0x46c669["bind"](_0x46c669);
        _0x4cca25["toString"] = _0x29f6cb["toString"]["bind"](_0x29f6cb);
        _0x4fd052[_0x11486c] = _0x4cca25;
    }
});


_0x4bea14();

这些代码是干扰或者阻扰你进行调试的,对加密参数来说,没有什么用,我一般都是直接删除。

ob混淆的代码特征基本上就是这些,而最新版的ob混淆,也只是第一个略有修改,大数组变成了一个函数,其他的基本没变。

欢迎关注本人微信公众号,学习更多AST相关知识。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ob混淆 ast工具是一种用于混淆代码的工具,主要针对Python语言编写的代码AST是Abstract Syntax Tree的缩写,即抽象语法树,它是Python解释器在分析源代码时生成的一种表示方式。ob混淆 ast工具通过操作抽象语法树来混淆代码,使其难以被逆向工程分析和理解。 ob混淆 ast工具的原理是通过修改和替换抽象语法树中的节点和结构,使得源代码的结构、语义和逻辑变得混乱和困惑。它可以对变量名、函数名、类名等进行重命名,使得原本可读性强的代码变得难以阅读和理解。同时,还可以对源代码中的函数调用关系、控制流等进行修改和隐藏,增加解析和分析的复杂度。 ob混淆 ast工具的优点是能够在不改变源代码的功能和逻辑的前提下,提高源代码的保护性。通过混淆代码,可以有效地防止源代码被反编译、逆向工程和非法盗用。对于需要加密和保护源代码的应用场景,ob混淆 ast工具是一种非常有效的安全保护措施。 然而,ob混淆 ast工具也存在一些缺点。首先,混淆后的源代码可读性较差,给后续的维护和调试带来不便。其次,由于混淆是通过修改和替换抽象语法树实现的,因此在一些复杂和庞大的项目中,可能会导致混淆过程失败或引入新的错误。 总之,ob混淆 ast工具是一种在保护源代码安全性方面非常有用的工具。通过操作和修改抽象语法树,可以有效地混淆和加密源代码,使得其难以被逆向工程分析,增加了源代码的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值