李恒道 发表于 2022-10-7 19:36:29

JS混淆分析初步理论研究篇一

# 前文
因为目前市面上资料是较少的...
最近突然对js逆向有了一定兴趣
碰到涛也在油中
于是经过一段不可告人的事情后
打入了内部学习了一些奇奇怪怪的大人的知识
写下了这篇入门文章
可能存在事实性错误
可以在评论区支出
# 开始
因为https://www.jsjiami.com/生成的代码不好使
所以我换了一个
https://www.sojson.com/jsobfuscator.html
加密的代码也比较简单
let a=1;
alert(a);
最基础的配置我们研究一些东西
生成的代码为
```javascript
/*
* 加密工具已经升级了一个版本,目前为 jsjiami.com.v5 ,主要加强了算法,以及防破解【绝对不可逆】配置,耶稣也无法100%还原,我说的。;
* 已经打算把这个工具基础功能一直免费下去。还希望支持我。
* 另外 jsjiami.com.v5 已经强制加入校验,注释可以去掉,但是 jsjiami.com.v5 不能去掉(如果你开通了VIP,可以手动去掉),其他都没有任何绑定。
* 誓死不会加入任何后门,jsjiami.com JS 加密的使命就是为了保护你们的Javascript 。
* 警告:如果您恶意去掉 jsjiami.com.v5 那么我们将不会保护您的JavaScript代码。请遵守规则
* 新版本: https://www.jsjiami.com/ 支持批量加密,支持大文件加密,拥有更多加密。 */

;var encode_version = 'jsjiami.com.v5', uumto = '__0xecbce',__0xecbce=['w7Q+w6jDqcKnMMOewpgF','TsOTIcKVw4IjwpsGc2NVQR/CtQ==','5YiH6ZmZ54uo5pyg5YyF772HfcOr5L+Z5a6R5p+y5byO56ms','w4I7Ohwo','dXkZw4kL','wrnClsKNIsKX','54if5p6c5Y6v772NCGDkv7rlr6zmnYXlvqPnq4nvvaPov4Hor6Xmla3mjIXmi6jkuaTnm7Dlt4zkv4o=','wpk8WMOuQA==','wqojw6I='];(function(_0x4a174f,_0x2b3ed7){var _0x51adc6=function(_0x4c4f72){while(--_0x4c4f72){_0x4a174f['push'](_0x4a174f['shift']());}};_0x51adc6(++_0x2b3ed7);}(__0xecbce,0x155));var _0x43f9=function(_0x15b28a,_0x370d4f){_0x15b28a=_0x15b28a-0x0;var _0x958f5c=__0xecbce;if(_0x43f9['initialized']===undefined){(function(){var _0x375bef=typeof window!=='undefined'?window:typeof process==='object'&&typeof require==='function'&&typeof global==='object'?global:this;var _0x36add6='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x375bef['atob']||(_0x375bef['atob']=function(_0x2b8d70){var _0x786ab7=String(_0x2b8d70)['replace'](/=+$/,'');for(var _0x2efd19=0x0,_0x5032a4,_0x1a3fe4,_0x5cb9a4=0x0,_0x3d9d3c='';_0x1a3fe4=_0x786ab7['charAt'](_0x5cb9a4++);~_0x1a3fe4&&(_0x5032a4=_0x2efd19%0x4?_0x5032a4*0x40+_0x1a3fe4:_0x1a3fe4,_0x2efd19++%0x4)?_0x3d9d3c+=String['fromCharCode'](0xff&_0x5032a4>>(-0x2*_0x2efd19&0x6)):0x0){_0x1a3fe4=_0x36add6['indexOf'](_0x1a3fe4);}return _0x3d9d3c;});}());var _0x4d9f1d=function(_0x11262d,_0x148d0f){var _0x31b35b=[],_0x2d6c29=0x0,_0x24b4f5,_0x196a93='',_0x56258a='';_0x11262d=atob(_0x11262d);for(var _0x3d7663=0x0,_0x34f9e9=_0x11262d['length'];_0x3d7663<_0x34f9e9;_0x3d7663++){_0x56258a+='%'+('00'+_0x11262d['charCodeAt'](_0x3d7663)['toString'](0x10))['slice'](-0x2);}_0x11262d=decodeURIComponent(_0x56258a);for(var _0x48101c=0x0;_0x48101c<0x100;_0x48101c++){_0x31b35b=_0x48101c;}for(_0x48101c=0x0;_0x48101c<0x100;_0x48101c++){_0x2d6c29=(_0x2d6c29+_0x31b35b+_0x148d0f['charCodeAt'](_0x48101c%_0x148d0f['length']))%0x100;_0x24b4f5=_0x31b35b;_0x31b35b=_0x31b35b;_0x31b35b=_0x24b4f5;}_0x48101c=0x0;_0x2d6c29=0x0;for(var _0x206f10=0x0;_0x206f10<_0x11262d['length'];_0x206f10++){_0x48101c=(_0x48101c+0x1)%0x100;_0x2d6c29=(_0x2d6c29+_0x31b35b)%0x100;_0x24b4f5=_0x31b35b;_0x31b35b=_0x31b35b;_0x31b35b=_0x24b4f5;_0x196a93+=String['fromCharCode'](_0x11262d['charCodeAt'](_0x206f10)^_0x31b35b[(_0x31b35b+_0x31b35b)%0x100]);}return _0x196a93;};_0x43f9['rc4']=_0x4d9f1d;_0x43f9['data']={};_0x43f9['initialized']=!![];}var _0x106a87=_0x43f9['data'];if(_0x106a87===undefined){if(_0x43f9['once']===undefined){_0x43f9['once']=!![];}_0x958f5c=_0x43f9['rc4'](_0x958f5c,_0x370d4f);_0x43f9['data']=_0x958f5c;}else{_0x958f5c=_0x106a87;}return _0x958f5c;};let a=0x1;alert(a);;(function(_0xc2361a,_0x49f6b2,_0x4c5d49){var _0x4bbdd6={'PTyWI':_0x43f9('0x0','SRfb'),'CFOau':function _0x2e9886(_0x27d2c4,_0x233ed3){return _0x27d2c4!==_0x233ed3;},'yGZoO':_0x43f9('0x1','(WPz'),'UQhqT':function _0xe650a3(_0x4590a1,_0x160226){return _0x4590a1===_0x160226;},'TtTMq':_0x43f9('0x2','yz7r'),'FQggo':function _0x47c22c(_0x2fe61e,_0x50381a){return _0x2fe61e+_0x50381a;},'FTCAn':_0x43f9('0x3','D!uM')};_0x4c5d49='al';try{_0x4c5d49+=_0x4bbdd6['PTyWI'];_0x49f6b2=encode_version;if(!(_0x4bbdd6['CFOau'](typeof _0x49f6b2,_0x4bbdd6)&&_0x4bbdd6(_0x49f6b2,_0x4bbdd6))){_0xc2361a(_0x4bbdd6['FQggo']('删除',_0x43f9('0x7','27(^')));}}catch(_0x2d647c){_0xc2361a(_0x4bbdd6);}}(window));;encode_version = 'jsjiami.com.v5';
```
我们格式化一下,跑一下发现可以正常运行
证明没有进行格式化攻击
先看第一段
```javascript
var encode_version = "jsjiami.com.v5",
uumto = "__0xecbce",
__0xecbce = [
    "w7Q+w6jDqcKnMMOewpgF",
    "TsOTIcKVw4IjwpsGc2NVQR/CtQ==",
    "5YiH6ZmZ54uo5pyg5YyF772HfcOr5L+Z5a6R5p+y5byO56ms",
    "w4I7Ohwo",
    "dXkZw4kL",
    "wrnClsKNIsKX",
    "54if5p6c5Y6v772NCGDkv7rlr6zmnYXlvqPnq4nvvaPov4Hor6Xmla3mjIXmi6jkuaTnm7Dlt4zkv4o=",
    "wpk8WMOuQA==",
    "wqojw6I=",
];
```
var encode_version = "jsjiami.com.v5",
声明了网站加密标识,禁止删除
uumto暂时不知道
__0xecbce 是对字符串加密形成的数组,把代码里的字符串全部提到数组里了
我们称之为【数组混淆】
```javascript
(function (_0x4a174f, _0x2b3ed7) {
var _0x51adc6 = function (_0x4c4f72) {
    while (--_0x4c4f72) {
      _0x4a174f["push"](_0x4a174f["shift"]());
    }
};
_0x51adc6(++_0x2b3ed7);
})(__0xecbce, 0x155);
```
这里是一个数组乱序混淆,因为数组混淆很容易被抓到规律
所以在 创建后,进行一个乱序,我们称之为【乱序混淆】
我们可以调试看一下
这是没执行的时候
![图片.png](data/attachment/forum/202210/07/192259cz9c2gp8sy9rp5ip.png)
这是执行一次的时候
可以看到就是将第一项放到最后一位,重复++0x155次,也就是342次
![图片.png](data/attachment/forum/202210/07/192319pqwq2lwg45w44www.png)
当执行到342次后
打乱成了这样
![图片.png](data/attachment/forum/202210/07/192412x0jx0xj484xax8r9.png)
然后声明了一个_0x43f9的函数
![图片.png](data/attachment/forum/202210/07/192512l62u5affxa2l62kf.png)
执行到了a=1,alert...加密个鬼啦!
![图片.png](data/attachment/forum/202210/07/192539ynklkxg7fplvlrzx.png)
接下来走到了自执行代码
我大概贴一下,我们继续往后分析
```javascript
(function (_0xc2361a, _0x49f6b2, _0x4c5d49) {
var _0x4bbdd6 = {
    PTyWI: _0x43f9("0x0", "SRfb"),
    CFOau: function _0x2e9886(_0x27d2c4, _0x233ed3) {
      return _0x27d2c4 !== _0x233ed3;
    },
    yGZoO: _0x43f9("0x1", "(WPz"),
    UQhqT: function _0xe650a3(_0x4590a1, _0x160226) {
      return _0x4590a1 === _0x160226;
    },
    TtTMq: _0x43f9("0x2", "yz7r"),
    FQggo: function _0x47c22c(_0x2fe61e, _0x50381a) {
      return _0x2fe61e + _0x50381a;
    },
    FTCAn: _0x43f9("0x3", "D!uM"),
};
_0x4c5d49 = "al";
try {
    _0x4c5d49 += _0x4bbdd6["PTyWI"];
    _0x49f6b2 = encode_version;
    if (
      !(
      _0x4bbdd6["CFOau"](
          typeof _0x49f6b2,
          _0x4bbdd6
      ) &&
      _0x4bbdd6(
          _0x49f6b2,
          _0x4bbdd6
      )
      )
    ) {
      _0xc2361a(_0x4bbdd6["FQggo"]("删除", _0x43f9("0x7", "27(^")));
    }
} catch (_0x2d647c) {
    _0xc2361a(_0x4bbdd6);
}
})(window);
```
有三个变量,但是实际只传入了一个变量
另外两个很有可能是在源代码叫var a=1之类的
在混淆之后变量提升到顶部的入参,来混淆视线,我们称之为【变量提升混淆】
![图片.png](data/attachment/forum/202210/07/192653c0vzw33cqc0n06tq.png)
然后这里声明了一个对象,并且调用了_0x43f9,证明了0x43f9是一个解密函数
我们跟进去看看
![图片.png](data/attachment/forum/202210/07/192815m562ci6ktokhthki.png)
传入了两个参数
![图片.png](data/attachment/forum/202210/07/192854i6vxwcbbece2xqnb.png)
首先将字符串-0,形成数字
var _0x958f5c = __0xecbce;
然后找到对应的字符串
![图片.png](data/attachment/forum/202210/07/192947igg2w6uwvgndcvet.png)
判断这个函数有没有初始化过,我们第一次运行很显然没有
_0x43f9["initialized"] === undefined
所以直接执行一段自执行函数,代码我们上面贴了,我就不重复了
获取对应的window值(浏览器情况下)
```
      var _0x375bef =
      typeof window !== "undefined"
          ? window
          : typeof process === "object" &&
            typeof require === "function" &&
            typeof global === "object"
          ? global
          : this;
```
然后对window的atob进行了劫持
```
_0x375bef["atob"] ||
      (_0x375bef["atob"] = function (_0x2b8d70)
```
又声明了一个_0x4d9f1d 函数,干啥不知道
_0x43f9["rc4"] = _0x4d9f1d;将上面那个函数赋值给解密函数,叫rc4,应该也是个什么解密
_0x43f9["data"] = {};应该是一个数字缓存
_0x43f9["initialized"] = !![];表示初始化成功
```
var _0x4d9f1d = function (_0x11262d, _0x148d0f)
    _0x43f9["rc4"] = _0x4d9f1d;
    _0x43f9["data"] = {};
    _0x43f9["initialized"] = !![];
```
判断是否命中缓存,我们这里肯定没有命中
没有命中就判断once是否执行过一次了,没执行过就设置once为真

```javascript
if (_0x106a87 === undefined) {
    if (_0x43f9["once"] === undefined) {
      _0x43f9["once"] = !![];
    }
    _0x958f5c = _0x43f9["rc4"](_0x958f5c, _0x370d4f);
    _0x43f9["data"] = _0x958f5c;
} else {
    _0x958f5c = _0x106a87;
}
```
设置后传入
_0x958f5c = _0x43f9["rc4"](_0x958f5c, _0x370d4f);
传入我们数组混淆里的内容,以及一个最初传入的内容
![图片.png](data/attachment/forum/202210/07/193615wuwmrt68m122wu3x.png)
# 结语
下篇继续...太长了



Vikrant 发表于 2022-10-7 21:27:44

本帖最后由 Vikrant 于 2022-10-7 21:31 编辑

终于有教程了,不用硬着头皮、漫无方向地硬读代码了(*/ω\*)

李恒道 发表于 2022-10-7 21:29:21

Vikrant 发表于 2022-10-7 21:27
终于有教程了,不用硬着头皮,漫无方向地硬读代码了(*/ω\*)
其实浏览器大部分跑的加密都不是特别难...
基本就是常见的那几种
数组混淆,乱序混淆,整个平坦流,内存爆破,格式化爆破啥的
看了好多文章就那几种来回换

= =
后期等我学的差不多了出ast分析...
大部分网站基本就是分析解密函数,然后ast抬手scope,bingding,replace三板斧

Vikrant 发表于 2022-10-7 22:12:01

李恒道 发表于 2022-10-7 21:29
其实浏览器大部分跑的加密都不是特别难...
基本就是常见的那几种
数组混淆,乱序混淆,整个平坦流,内存爆 ...
话说哥哥有推荐的vscode格式化插件吗,哥哥的示例代码我用我的vscode格式化没有反应
ε(┬┬﹏┬┬)3

李恒道 发表于 2022-10-8 10:26:45

Vikrant 发表于 2022-10-7 22:12
话说哥哥有推荐的vscode格式化插件吗,哥哥的示例代码我用我的vscode格式化没有反应
ε(┬┬﹏┬┬)3 ...

宝子去掉第一个;

Vikrant 发表于 2022-10-8 23:30:40

李恒道 发表于 2022-10-8 10:26
宝子去掉第一个;

我去掉了的……(*꒦ິ⌓꒦ີ)

李恒道 发表于 2022-10-8 23:55:03

Vikrant 发表于 2022-10-8 23:30
我去掉了的……(*꒦ິ⌓꒦ີ)

{:4_105:}我用的vscode
去掉第一个;就可以格式化了
哥哥用的啥

Vikrant 发表于 2022-10-9 10:07:42

李恒道 发表于 2022-10-8 23:55
我用的vscode
去掉第一个;就可以格式化了
哥哥用的啥

我用的也是vscode 😭,格式化程序是vscode默认的“JavaScript和Typescript的语言功能”,没有用插件,就很怪 ╯︿╰

李恒道 发表于 2022-10-9 12:22:58

Vikrant 发表于 2022-10-9 10:07
我用的也是vscode 😭,格式化程序是vscode默认的“JavaScript和Typescript的语言功能”,没有用插件,就 ...

我好像有Pretter
哥哥试试?

Vikrant 发表于 2022-10-9 17:37:38

李恒道 发表于 2022-10-9 12:22
我好像有Pretter
哥哥试试?

好哒🍭
页: [1] 2
查看完整版本: JS混淆分析初步理论研究篇一