AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn

图片[1]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

图片[2]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

paituo
|我的
|设置
|消息
|提醒
|退出

图片[3]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网 |积分: 2
|用户组: 锋芒初露

.

.

帖子

.

吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn»网站 【 软件安全 】 『脱壳破解区』 AST – 并没有想象中那么神秘

.

返回列表
图片[4]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网图片[5]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
.

查看: 333|回复: 5
图片[6]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
图片[7]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网


图片[8]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

[原创]
AST – 并没有想象中那么神秘


 图片[9]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
[复制链接]

电梯直达

图片[10]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网



楼主

图片[11]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
发表于 2021-7-9 13:46
|
只看该作者
图片[12]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

本帖最后由 null119 于 2021-7-9 13:46 编辑

0x0、前言部分

PS:本来准备发到编程区,不过编程区没有JavaScript 版块,另外本文最主的内容是如何通过AST处理还原加密混淆JS代码,应该也属于逆向破解的范畴,所以就发在这个版块,如有不妥,麻烦管理安排一下。

前几天在论坛看到一篇由 beattortoise 写的关于AST还原混淆JS的文章,回想起曾经折腾AST走过的那么多弯路,真是一把鼻涕一把泪,所以趁这个机会,给那些想学习AST却苦于无处入门的朋友们做个入门引导,其实AST并不神秘,也并没有想象中的那么的高大上!

文章就两个部分,AST基础+混淆JS还原的逐步演示。师傅领进门、修行还得靠个人! 共勉!!!



0x1、基础部分

AST:Abstract Syntax Tree(抽象语法树),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

我知道,看完定义的你八成是一脸懵逼,什么叫做源代码语法结构的抽象表示?不用害怕,我在这里简单使用一句话为例来帮助大家理解:

今天你喝水了吗?

大家都知道这句话的意思就是问今天你喝水了吗,但你知道这句话是由哪些成分组成的吗?

图片[13]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

以前上学的时候语文课肯定都学过,句子里有主语,谓语,宾语,定语等等,句子中的词又分为名词、动词、介词….各种词,当这些词按照某种规律形式组合以后,就形成了上面的那句话,

而现在正在看文章的你肯定知道并理解上面那句话的意思,但是,你不一定知道这句话中每个词的词性,不知道哪个是主语,哪个是谓语,这就跟你知道 JavaScript,却不了解AST是一回事。

所以:

不会AST这件事本身不会对你学习使用JavaScript有任何影响,但如果你理解并掌握了AST,那么JavaScript 可能在你眼里就有些不太一样了,从某种程度上来说,了解掌握AST可以帮助你真正吃透 JavaScript 的语言精髓。

既然如此,那怎样才能快速的了解AST?

答案很简单,随写写句JS拿去AST分析一下,然后对着看看,相信聪明的你很快就能有所了解。

在线 AST语法结构解析网站:https://astexplorer.net/

下面来看看最最简单的JS

[JavaScript] 纯文本查看 复制代码
1
var a=1;

代码对应的AST语法树结构:

图片[14]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

从上往下看,有Program、declarations、VariableDeclarator、Identifier、Literal,这些都AST的结构类型,除了这些还有很多,列表如下:

图片[15]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

知道了这些有什么用呢?除了上面说的可以加深对JS的深层理解外,最大的用处就是对 JavaScript 代码进行混淆以及还原了。

了解JavaScript 的小伙伴应该都知道,JS有非常非常多的语法糖,而对JS的加密混淆,其实就是在对这些语法糖的充分利用,当你既熟练掌握JavaScript ,又理解并掌握了AST以后,你就可以从AST语法树结构的视角,去对混淆后的JS代码进行某种程度的还原,有点类似于降维打击,因为JS加密混淆都是在JS代码的外在表现形式上做的手脚,而AST的视角则更偏向底层。

0x2、混淆JS还原演示

PS:环境问题请自行百度解决。

测试代码:

[JavaScript] 纯文本查看 复制代码

?

1
2
3
4
5
6
function MyFun(a,b){
        var c=a+b;
        var d=a*b+c;
        return c+d;
}
console.log(MyFun(10,20))

加密混淆后的代码:

[JavaScript] 纯文本查看 复制代码

?

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
var _0x305a = ['B8OBMcKcUQ==', 'w4Y2wrrCl8OT', 'wpHCpMKLRsOu', 'wpgfwo7DgMO4', 'wpVywozCqwHCucKV', 'HMK1VsOS', 'wrfCiSgfw7c0NGHCoAXCuH7CnyzDlMOdfXxHLDorfsOCwrzCnFNPw6I+cwQ=', 'SsO0PUdW', 'PcKRVQ==', 'UHbDj3xcw7ZY', 'UsO6OA==', 'wrjChmcfw70=', 'W8OnLURB', 'w6/CrATDncKcw6lF', 'IcOxw4DDiMOx', 'wr3Dp07DtUUfwrI=', 'N8KOesOsw58=', 'FR7DgS0p', 'AgPDjj0jcUI=', 'AsOYGMKFdg==', 'bcK0wrHCiMOt', 'w7HClAPDo8KVSsKe', 'wrbDhGR1', 'ABzDkCI1', 'Fg1fRsOE', 'w4XCocOJBGg=', 'w60AwpHCv8OJ', 'NcKLwpBPHW01', 'w4QGIWLDiw==', 'wqXCmmAT', 'FT9dMg==', 'LF7Du2sqwrrCqsKDRw==', 'wr/DsknDs3s=', 'wrXDhHR3BQ==', 'P8KKwphT', 'RHjDk2E=', 'w7FCY21yw7BV', 'w7tDa3E=', 'w77ClAo=', 'AcOWJMKKRsOCwpbDsRLDlHkTw5g/wqfCgDzCusOC', 'w6fDpAHDiRlpWQ==', 'wpgGwo3Dtg==', 'w4c+wqHDh2E=', 'fXjDpUspw5kAH1jDvcOGAMKhfiHCiFvCkcOLGMOqw5HDtsKTw5jDom7DmMOaYMKdwrs=', 'QhFqYQg=', 'wqHCsm3Ds0DCpsKB', 'w4cdwo4=', 'w75Cag==', 'w4YiEcO9wq1aIw==', 'w48XwovCvcOY', 'e1vDnHbCg8Kkdkp5', 'cEHDtUhR', 'asKwwonCjMOw', 'TsOaw4QMGsKswp4=', 'wqrDqULDqk8=', 'w7DCjHcsw4A=', 'w4N6worDksOo', 'WMKywpDDonI=', 'wo0GwqkKwrA=', 'DjRPKMKlwpROa8OCV8KxY8KYWGEuwobDgcO2', 'CcOZw5jDlcOO', 'bsK4wpLClsOT', 'w6YJw5APwoo=', 'w4EoHcO7wqU=', 'w4lHTTnCpcKkw6jCgUc=', 'wpNlwoHCvR7CocKZwoMe', 'w6XCt8O1I1A=', 'w7dff3Fv', 'FMKrQMORw6M=', 'w7fCgw7DtcKKUsKSLyA=', 'DMOyw6vDucO6', 'L1/Dt1nDuMOlwpQ=', 'w5MbLnLDgcKlwps=', 'wrXCvHHDrg==', 'w5EsHcOiwqc=', 'N8KUwo5QCw==', 'w6sdwo3Co8OUw7xB', 'VABoYw==', 'wrF7LhFwwo5O', 'Rj9O']; (function(_0x1f4b85, _0x305a4c) {
    var _0x796962 = function(_0x4b72d1) {
        while (--_0x4b72d1) {
            _0x1f4b85['push'](_0x1f4b85['shift']());
        }
    };
    _0x796962(++_0x305a4c);
} (_0x305a, 0xe7));
var _0x7969 = function(_0x1f4b85, _0x305a4c) {
    _0x1f4b85 = _0x1f4b85 - 0x0;
    var _0x796962 = _0x305a[_0x1f4b85];
    if (_0x7969['UkyMFX'] === undefined) { (function() {
            var _0x344906;
            try {
                var _0x1d345f = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
                _0x344906 = _0x1d345f();
            } catch(_0x1d3b2a) {
                _0x344906 = window;
            }
            var _0x14f0f1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
            _0x344906['atob'] || (_0x344906['atob'] = function(_0x3128ab) {
                var _0x23f475 = String(_0x3128ab)['replace'](/=+$/, '');
                var _0x32bdd4 = '';
                for (var _0x3da026 = 0x0,
                _0x372bba, _0x104d49, _0x5eb7a8 = 0x0; _0x104d49 = _0x23f475['charAt'](_0x5eb7a8++);~_0x104d49 && (_0x372bba = _0x3da026 % 0x4 ? _0x372bba * 0x40 + _0x104d49: _0x104d49, _0x3da026++%0x4) ? _0x32bdd4 += String['fromCharCode'](0xff & _0x372bba >> ( - 0x2 * _0x3da026 & 0x6)) : 0x0) {
                    _0x104d49 = _0x14f0f1['indexOf'](_0x104d49);
                }
                return _0x32bdd4;
            });
        } ());
        var _0x570ba5 = function(_0x257551, _0x1f613d) {
            var _0x3e9282 = [],
            _0x434903 = 0x0,
            _0x33fc11,
            _0x249601 = '',
            _0x2f07c3 = '';
            _0x257551 = atob(_0x257551);
            for (var _0x464f7e = 0x0,
            _0x4b3e63 = _0x257551['length']; _0x464f7e < _0x4b3e63; _0x464f7e++) {
                _0x2f07c3 += '%' + ('00' + _0x257551['charCodeAt'](_0x464f7e)['toString'](0x10))['slice']( - 0x2);
            }
            _0x257551 = decodeURIComponent(_0x2f07c3);
            var _0x94001b;
            for (_0x94001b = 0x0; _0x94001b < 0x100; _0x94001b++) {
                _0x3e9282[_0x94001b] = _0x94001b;
            }
            for (_0x94001b = 0x0; _0x94001b < 0x100; _0x94001b++) {
                _0x434903 = (_0x434903 + _0x3e9282[_0x94001b] + _0x1f613d['charCodeAt'](_0x94001b % _0x1f613d['length'])) % 0x100;
                _0x33fc11 = _0x3e9282[_0x94001b];
                _0x3e9282[_0x94001b] = _0x3e9282[_0x434903];
                _0x3e9282[_0x434903] = _0x33fc11;
            }
            _0x94001b = 0x0;
            _0x434903 = 0x0;
            for (var _0x27a73e = 0x0; _0x27a73e < _0x257551['length']; _0x27a73e++) {
                _0x94001b = (_0x94001b + 0x1) % 0x100;
                _0x434903 = (_0x434903 + _0x3e9282[_0x94001b]) % 0x100;
                _0x33fc11 = _0x3e9282[_0x94001b];
                _0x3e9282[_0x94001b] = _0x3e9282[_0x434903];
                _0x3e9282[_0x434903] = _0x33fc11;
                _0x249601 += String['fromCharCode'](_0x257551['charCodeAt'](_0x27a73e) ^ _0x3e9282[(_0x3e9282[_0x94001b] + _0x3e9282[_0x434903]) % 0x100]);
            }
            return _0x249601;
        };
        _0x7969['tMJLOX'] = _0x570ba5;
        _0x7969['vDRtQv'] = {};
        _0x7969['UkyMFX'] = !![];
    }
    var _0x4b72d1 = _0x7969['vDRtQv'][_0x1f4b85];
    if (_0x4b72d1 === undefined) {
        if (_0x7969['SqRviR'] === undefined) {
            _0x7969['SqRviR'] = !![];
        }
        _0x796962 = _0x7969['tMJLOX'](_0x796962, _0x305a4c);
        _0x7969['vDRtQv'][_0x1f4b85] = _0x796962;
    } else {
        _0x796962 = _0x4b72d1;
    }
    return _0x796962;
};
function _0x556652(_0x4a2332, _0x2634dc) {
    var _0x94d946 = function() {
        if (_0x7969('0xb', 'X*5E') !== _0x7969('0xc', 'WhTf')) {
            if (fn) {
                var _0x33221e = fn[_0x7969('0x35', 'hsTm')](context, arguments);
                fn = null;
                return _0x33221e;
            }
        } else {
            var _0x43616c = !![];
            return function(_0x550c05, _0x13d9c2) {
                if (_0x7969('0xa', '9uv1') !== _0x7969('0x1d', 'wdO$')) {
                    var _0x296878 = _0x43616c ?
                    function() {
                        if (_0x7969('0x22', 'NGkH') !== _0x7969('0x40', 't$pJ')) {
                            if (_0x13d9c2) {
                                if (_0x7969('0x21', '9kDW') === _0x7969('0x17', 'k(YQ')) {
                                    that[_0x7969('0x16', 'r8p)')] = function(_0x1c2524) {
                                        var _0x2972cc = {};
                                        _0x2972cc[_0x7969('0x11', 'k3XH')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x1f', 'Cu4J')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x3a', 'R*hj')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x26', 'V6wH')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x41', 'Bt5v')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x4e', 'kamb')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x10', 'a4uQ')] = _0x1c2524;
                                        _0x2972cc[_0x7969('0x9', 'uP&h')] = _0x1c2524;
                                        return _0x2972cc;
                                    } (func);
                                } else {
                                    var _0x34a69a = _0x13d9c2[_0x7969('0x20', 'sT$v')](_0x550c05, arguments);
                                    _0x13d9c2 = null;
                                    return _0x34a69a;
                                }
                            }
                        } else {
                            that = window;
                        }
                    }: function() {};
                    _0x43616c = ![];
                    return _0x296878;
                } else {
                    var _0x2c3174 = {};
                    _0x2c3174[_0x7969('0x8', 'pE[N')] = func;
                    _0x2c3174[_0x7969('0x32', 'WhTf')] = func;
                    _0x2c3174[_0x7969('0x47', 'sDkG')] = func;
                    _0x2c3174[_0x7969('0x27', 'YgD$')] = func;
                    _0x2c3174[_0x7969('0x23', '9uv1')] = func;
                    _0x2c3174[_0x7969('0x4a', '(^8)')] = func;
                    _0x2c3174[_0x7969('0x2a', 'Cu4J')] = func;
                    _0x2c3174[_0x7969('0x25', 'AWI1')] = func;
                    return _0x2c3174;
                }
            };
        }
    } ();
    var _0x23c1f6 = _0x94d946(this,
    function() {
        var _0x6e83c1 = function() {};
        var _0x3f3777;
        try {
            if (_0x7969('0x33', 'JKNM') !== _0x7969('0x45', 'k(YQ')) {
                var _0x584a01 = Function(_0x7969('0x30', 'uP&h') + _0x7969('0xf', 'V6wH') + ');');
                _0x3f3777 = _0x584a01();
            } else {
                var _0x30c130 = Function(_0x7969('0x44', 'YgD$') + _0x7969('0x34', 'Jler') + ');');
                _0x3f3777 = _0x30c130();
            }
        } catch(_0x5365b4) {
            if (_0x7969('0x19', 'D3T3') !== _0x7969('0x1c', 'uP&h')) {
                _0x3f3777 = window;
            } else {
                _0x3f3777[_0x7969('0x1', 'AWI1')][_0x7969('0x38', 'sJv5')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x12', 'O(f6')][_0x7969('0x2c', 'O(f6')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x1e', 'kamb')][_0x7969('0x48', 'aCn%')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x3e', ']zyO')][_0x7969('0xe', 'D3T3')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x31', 'jA(H')][_0x7969('0x4c', 'sJv5')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x24', '*20m')][_0x7969('0x3b', 'G1i2')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x7', '1MEH')][_0x7969('0x2a', 'Cu4J')] = _0x6e83c1;
                _0x3f3777[_0x7969('0x0', 'QGrn')][_0x7969('0x14', 'V6wH')] = _0x6e83c1;
            }
        }
        if (!_0x3f3777[_0x7969('0x39', 'aCn%')]) {
            if (_0x7969('0x4b', 'NGkH') !== _0x7969('0x3c', 'O(f6')) {
                _0x3f3777[_0x7969('0x36', 'WU*x')] = function(_0x4bdab5) {
                    if (_0x7969('0x29', 'zEsY') === _0x7969('0x46', 'wdO$')) {
                        var _0x5f33bc = {};
                        _0x5f33bc[_0x7969('0x37', 'R*hj')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x6', 'hsTm')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x43', 'JQ7t')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x2e', 'sJv5')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x3d', 'wdO$')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x49', 'U(TC')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x3f', 'zEsY')] = _0x4bdab5;
                        _0x5f33bc[_0x7969('0x1a', 'sT$v')] = _0x4bdab5;
                        return _0x5f33bc;
                    } else {
                        var _0x1b640b = firstCall ?
                        function() {
                            if (fn) {
                                var _0x3dd5c2 = fn[_0x7969('0x4d', 'D3T3')](context, arguments);
                                fn = null;
                                return _0x3dd5c2;
                            }
                        }: function() {};
                        firstCall = ![];
                        return _0x1b640b;
                    }
                } (_0x6e83c1);
            } else {
                var _0x345d2c = fn[_0x7969('0x4', '*20m')](context, arguments);
                fn = null;
                return _0x345d2c;
            }
        } else {
            _0x3f3777[_0x7969('0x36', 'WU*x')][_0x7969('0x2f', 'kamb')] = _0x6e83c1;
            _0x3f3777[_0x7969('0x5', '9uv1')][_0x7969('0x2', 'WU*x')] = _0x6e83c1;
            _0x3f3777[_0x7969('0x12', 'O(f6')][_0x7969('0x42', 'vJ8P')] = _0x6e83c1;
            _0x3f3777[_0x7969('0x2d', 'sJv5')][_0x7969('0x2b', '*20m')] = _0x6e83c1;
            _0x3f3777[_0x7969('0xd', '(^8)')][_0x7969('0x15', 'a4uQ')] = _0x6e83c1;
            _0x3f3777[_0x7969('0x1b', 'sT$v')][_0x7969('0x28', 'ijQK')] = _0x6e83c1;
            _0x3f3777[_0x7969('0x1b', 'sT$v')][_0x7969('0x3', 'aCn%')] = _0x6e83c1;
            _0x3f3777[_0x7969('0x18', 'zEsY')][_0x7969('0x4f', 'k(YQ')] = _0x6e83c1;
        }
    });
    _0x23c1f6();
    var _0x245e10 = _0x4a2332 + _0x2634dc;
    var _0x5d196d = _0x4a2332 * _0x2634dc + _0x245e10;
    return _0x245e10 + _0x5d196d;
}
console[_0x7969('0x13', 'a4uQ')](_0x556652(0xa, 0x14));

检查混淆代码是否可以正常执行:

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

混淆后的代码可以正常执行,

对混淆后的代码进行初步分析

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

上图中可以很清晰的看到,标注红色框的函数 _0x7969 在整个被混淆的JS中大量出现,并且,都是以 _0x7969[‘xxx’] 或 _0x7969(‘xxx’,’xxx’) 的形式出现,其中的xxx则全部都是乱七八糟的字符串,由此可以得出结论:

_0x7969 这个函数就是这个混淆JS 加密字符串的解密函数

使用支持JS格式的文本编辑器,对混淆后的代码进行收缩,如下

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

我给标注出了解密函数跟执行函数(或者叫原始功能函数,叫啥无所谓,明白意思就行)

混淆JS的大体结构我们清楚了,下面第一步,就是对执行函数的加密字符串进行解密

我们先将混沌JS中的解密函数复制出来保存到de.js,将执行函数部分复制出来保存为en.js,再新建一个obTest.js,用于编写AST还原代码

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

de.js 需要添加一行,导出函数,名称就是上面的 _0x7969,如下:

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

打开obTest.js,开始进入AST 搬砖环节

[JavaScript] 纯文本查看 复制代码

?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
const fs = require("fs");
const esprima = require('esprima');
const estraverse = require('estraverse');
const escodegen = require('escodegen');
const iconv = require("iconv-lite");
const de = require("./de");  
 
//读取加密混淆的执行函数Js
var content = fs.readFileSync('./en.js',{encoding:'binary'}); 
var buf = new Buffer.from(content,'binary');
var code = iconv.decode(buf,'utf-8');
 
//将混淆后的执行函数Js转换为AST
var ast = esprima.parse(code);

[JavaScript] 纯文本查看 复制代码

?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//字符串解密
var ast = esprima.parse(code);
ast = estraverse.replace(ast, {
    enter: function (node) {
        if (node.type == 'CallExpression' &&  //标注1
            node.callee.type == 'Identifier' && //标注2
            node.callee.name == "_0x7969" &&  //解密函数名
            node.arguments.length == 2 && 
            node.arguments[0].type == 'Literal' && //标注3
            node.arguments[1].type == 'Literal'//标注4
        {
            var val = de._0x7969(node.arguments[0].value,node.arguments[1].value);  //标注5
            return {
                type: esprima.Syntax.Literal,
                value: val,
                raw: val
            }
        }
    }
});
 
code = escodegen.generate(ast)  //将AST转换为JS
console.log(code)

上面代码看不懂?没关系,一张图搞定

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

左边为混淆代码,右边为AST语法树结构,上面我们讲过了,所有加密的字符串都是以  _0x7969(‘xxx’,’xxx’) 这样的结构出现,所以,我们需要对结构进行筛查判断,找到所有这一类的节点

上面代码中的 if …. && …&& 一大串就是干这个事的,拿一行为例说明:

if (node.type == ‘CallExpression’ &&  //标注1

判断 node.type(当前节点类型)是否为 CallExpression(对应看上面的图),是不是马上就清楚了

执行代码看一下效果(加密字符串解密后)

[JavaScript] 纯文本查看 复制代码

?

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
function _0x556652(_0x4a2332, _0x2634dc) {
    var _0x94d946 = function () {
        if ('wxqXe' !== 'wxqXe') {
            if (fn) {
                var _0x33221e = fn['apply'](context, arguments);
                fn = null;
                return _0x33221e;
            }
        } else {
            var _0x43616c = !![];
            return function (_0x550c05, _0x13d9c2) {
                if ('NDYGh' !== 'bvJko') {
                    var _0x296878 = _0x43616c ? function () {
                        if ('RzWPN' !== 'fJYYY') {
                            if (_0x13d9c2) {
                                if ('CONdw' === 'YqJRn') {
                                    that['console'] = function (_0x1c2524) {
                                        var _0x2972cc = {};
                                        _0x2972cc['log'] = _0x1c2524;
                                        _0x2972cc['warn'] = _0x1c2524;
                                        _0x2972cc['debug'] = _0x1c2524;
                                        _0x2972cc['info'] = _0x1c2524;
                                        _0x2972cc['error'] = _0x1c2524;
                                        _0x2972cc['exception'] = _0x1c2524;
                                        _0x2972cc['table'] = _0x1c2524;
                                        _0x2972cc['trace'] = _0x1c2524;
                                        return _0x2972cc;
                                    }(func);
                                } else {
                                    var _0x34a69a = _0x13d9c2['apply'](_0x550c05, arguments);
                                    _0x13d9c2 = null;
                                    return _0x34a69a;
                                }
                            }
                        } else {
                            that = window;
                        }
                    } : function () {
                    };
                    _0x43616c = ![];
                    return _0x296878;
                } else {
                    var _0x2c3174 = {};
                    _0x2c3174['log'] = func;
                    _0x2c3174['warn'] = func;
                    _0x2c3174['debug'] = func;
                    _0x2c3174['info'] = func;
                    _0x2c3174['error'] = func;
                    _0x2c3174['exception'] = func;
                    _0x2c3174['table'] = func;
                    _0x2c3174['trace'] = func;
                    return _0x2c3174;
                }
            };
        }
    }();
    var _0x23c1f6 = _0x94d946(this, function () {
        var _0x6e83c1 = function () {
        };
        var _0x3f3777;
        try {
            if ('LbvcK' !== 'qYROQ') {
                var _0x584a01 = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
                _0x3f3777 = _0x584a01();
            } else {
                var _0x30c130 = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
                _0x3f3777 = _0x30c130();
            }
        } catch (_0x5365b4) {
            if ('BUJQE' !== 'qkHzB') {
                _0x3f3777 = window;
            } else {
                _0x3f3777['console']['log'] = _0x6e83c1;
                _0x3f3777['console']['warn'] = _0x6e83c1;
                _0x3f3777['console']['debug'] = _0x6e83c1;
                _0x3f3777['console']['info'] = _0x6e83c1;
                _0x3f3777['console']['error'] = _0x6e83c1;
                _0x3f3777['console']['exception'] = _0x6e83c1;
                _0x3f3777['console']['table'] = _0x6e83c1;
                _0x3f3777['console']['trace'] = _0x6e83c1;
            }
        }
        if (!_0x3f3777['console']) {
            if ('rlkwv' !== 'CXTGb') {
                _0x3f3777['console'] = function (_0x4bdab5) {
                    if ('aziuQ' === 'aziuQ') {
                        var _0x5f33bc = {};
                        _0x5f33bc['log'] = _0x4bdab5;
                        _0x5f33bc['warn'] = _0x4bdab5;
                        _0x5f33bc['debug'] = _0x4bdab5;
                        _0x5f33bc['info'] = _0x4bdab5;
                        _0x5f33bc['error'] = _0x4bdab5;
                        _0x5f33bc['exception'] = _0x4bdab5;
                        _0x5f33bc['table'] = _0x4bdab5;
                        _0x5f33bc['trace'] = _0x4bdab5;
                        return _0x5f33bc;
                    } else {
                        var _0x1b640b = firstCall ? function () {
                            if (fn) {
                                var _0x3dd5c2 = fn['apply'](context, arguments);
                                fn = null;
                                return _0x3dd5c2;
                            }
                        } : function () {
                        };
                        firstCall = ![];
                        return _0x1b640b;
                    }
                }(_0x6e83c1);
            } else {
                var _0x345d2c = fn['apply'](context, arguments);
                fn = null;
                return _0x345d2c;
            }
        } else {
            _0x3f3777['console']['log'] = _0x6e83c1;
            _0x3f3777['console']['warn'] = _0x6e83c1;
            _0x3f3777['console']['debug'] = _0x6e83c1;
            _0x3f3777['console']['info'] = _0x6e83c1;
            _0x3f3777['console']['error'] = _0x6e83c1;
            _0x3f3777['console']['exception'] = _0x6e83c1;
            _0x3f3777['console']['table'] = _0x6e83c1;
            _0x3f3777['console']['trace'] = _0x6e83c1;
        }
    });
    _0x23c1f6();
    var _0x245e10 = _0x4a2332 + _0x2634dc;
    var _0x5d196d = _0x4a2332 * _0x2634dc + _0x245e10;
    return _0x245e10 + _0x5d196d;
}
console['log'](_0x556652(10, 20));

可以看到,被混淆加密的字符串已经解密完成,一般情况下,这种程度的代码已经可以进行调试分析了,但我们的追求可以更高,各位同学可以翻到前面看看,测试加密混淆的原始JS才几行,虽然现在加密字符串解密了,但代码里依然存在大量的垃圾指令,还等什么,继续盘

分析一下第一步解密字符串完成后的代码,如下图

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

代码里有很多 if (‘xxx’===’xxx’) 、if (‘xxx’!==’xxx’)、if (‘xxx’ === ‘yyy’)、if (‘xxx’ !== ‘yyy)

会点js的一眼就看出来了,这不就是垃圾代码吗,明明一样还搞个判断分支,所以,把所以这类的 if 处理掉,可以将代码量直接砍掉一半,动手

[JavaScript] 纯文本查看 复制代码

?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 处理if('xx'==='xx')
var ast = esprima.parse(code);
ast = estraverse.replace(ast, {
    enter: function (node,parent) {
        if (node.type == 'IfStatement' &&
            node.test.type == 'BinaryExpression')
        {
            if(node.test.left.value == node.test.right.value) { //if('aaa'==='aaa'){}
                switch (node.test.operator) {
                    case '!==' //if('aaa'!=='aaa'){}
                        for (var idx = 0; idx < node.consequent.body.length; idx++) {
                            parent.body.splice(parent.body.indexOf(node), 0, node.consequent.body[idx]);
                        }
                        parent.body.splice(parent.body.indexOf(node), 1);
                        break
 
                    case '===' : //if('aaa'==='aaa'){}
                        for (var idx = 0; idx < node.alternate.body.length; idx++) {
                            parent.body.splice(parent.body.indexOf(node), 0, node.alternate.body[idx]);
                        }
                        parent.body.splice(parent.body.indexOf(node), 1);
                        break
 
                }
            } else //if('aaa'==='bbb'){}
                switch (node.test.operator) {
                    case '!==' : //if('aaa'!=='bbb'){}
                        for (var idx = 0; idx < node.consequent.body.length; idx++) {
                            parent.body.splice(parent.body.indexOf(node), 0, node.consequent.body[idx]);
                        }
                        parent.body.splice(parent.body.indexOf(node), 1);
                        break
 
                    case '===' : //if('aaa'==='bbb'){}
                        for (var idx = 0; idx < node.alternate.body.length; idx++) {
                            parent.body.splice(parent.body.indexOf(node), 0, node.alternate.body[idx]);
                        }
                        parent.body.splice(parent.body.indexOf(node), 1);
                        break
 
                }
            }
        }
    }
});

跟第一步字符串解密的代码相比差别不算很大,前面也是一大堆的类型判断,确定遍历到的节点就是我们需要找的if …. 这类的垃圾节点,找到后,将正常分支的内容插入到父节点,然后删除当前节点,为什么是这样的操作,同样上图说明

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

左侧是我们需要找的 if …. 这样的节点,绿色部分代表会执行部分,黑色部分代表不会执行的部分

图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

而我们需要做的就是,将绿色部分会执行的代码 consequent 节点插入到它的父节点,也就是TryStatement节点下,然后再把整个的 IfStatement 节点删除,这样就完成了对这类垃圾if…语句的处理

看下效果(处理垃圾if语句结果)

[JavaScript] 纯文本查看 复制代码

?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function _0x556652(_0x4a2332, _0x2634dc) {
    var _0x94d946 = function () {
        if (fn) {
            var _0x33221e = fn['apply'](context, arguments);
            fn = null;
            return _0x33221e;
        }
    }();
    var _0x23c1f6 = _0x94d946(this, function () {
        var _0x6e83c1 = function () {
        };
        var _0x3f3777;
        try {
            var _0x584a01 = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
            _0x3f3777 = _0x584a01();
        } catch (_0x5365b4) {
            _0x3f3777 = window;
        }
        if (!_0x3f3777['console']) {
            _0x3f3777['console'] = function (_0x4bdab5) {
                var _0x1b640b = firstCall ? function () {
                    if (fn) {
                        var _0x3dd5c2 = fn['apply'](context, arguments);
                        fn = null;
                        return _0x3dd5c2;
                    }
                } : function () {
                };
                firstCall = ![];
                return _0x1b640b;
            }(_0x6e83c1);
        } else {
            _0x3f3777['console']['log'] = _0x6e83c1;
            _0x3f3777['console']['warn'] = _0x6e83c1;
            _0x3f3777['console']['debug'] = _0x6e83c1;
            _0x3f3777['console']['info'] = _0x6e83c1;
            _0x3f3777['console']['error'] = _0x6e83c1;
            _0x3f3777['console']['exception'] = _0x6e83c1;
            _0x3f3777['console']['table'] = _0x6e83c1;
            _0x3f3777['console']['trace'] = _0x6e83c1;
        }
    });
    _0x23c1f6();
    var _0x245e10 = _0x4a2332 + _0x2634dc;
    var _0x5d196d = _0x4a2332 * _0x2634dc + _0x245e10;
    return _0x245e10 + _0x5d196d;
}
console['log'](_0x556652(10, 20));

是不是清爽多了,当然,还有可以优化的空间,无非就是制定添加规则,这就留给各位当课后作业吧。

最后附上这个混淆JS通过AST还原的最终结果:

[JavaScript] 纯文本查看 复制代码

?

1
2
3
4
5
6
function _0x556652(_0x4a2332, _0x2634dc) {
    var _0x245e10 = _0x4a2332 + _0x2634dc;
    var _0x5d196d = _0x4a2332 * _0x2634dc + _0x245e10;
    return _0x245e10 + _0x5d196d;
}
console['log'](_0x556652(10, 20));

对比一下测试加密源代码:

[JavaScript] 纯文本查看 复制代码

?

1
2
3
4
5
6
function MyFun(a,b){
        var c=a+b;
        var d=a*b+c;
        return c+d;
}
console.log(MyFun(10,20))

视频演示:https://www.bilibili.com/video/BV1E64y147Q6/

免费评分

参与人数 5 吾爱币 +4 热心值 +4 收起
理由
图片[25]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网 袁煜914 + 1 我很赞同!
图片[2]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网 杨辣子 + 1 + 1 收藏了!太牛了!
图片[2]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网 ZhiYing520 + 1 + 1 我很赞同!
图片[2]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网 notproblem + 1 谢谢@Thanks!
图片[2]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网 glces + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

图片[30]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网收藏11
图片[31]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网免费评分
图片[32]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网淘帖1
图片[33]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网有用1
图片[34]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网没用
图片[35]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网分享到朋友圈.


回复

举报

.

图片[36]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

1

主题

131

帖子

109

积分



沙发

图片[11]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
发表于 2021-7-9 13:53
|
只看该作者

谢谢分享,涨姿势了


回复
支持
反对

免费评分
举报

.

图片[36]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

11

主题

577

帖子

191

积分



3#

图片[11]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
发表于 2021-7-9 14:10
|
只看该作者

谢谢分享!


回复
支持
反对

免费评分
举报

.

图片[40]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

19

主题

1778

帖子

938

积分



4#

图片[11]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
发表于 2021-7-9 14:15
|
只看该作者

我認識了一種新的數據類型。
還是有收穫的!
挺好,
不像看別的技術帖子,
似懂非懂的。


回复
支持
反对

免费评分
举报

.

图片[42]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

471

主题

6269

帖子

3249

积分



5#

图片[11]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
发表于 2021-7-9 15:02
|
只看该作者

厉害!图片[44]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
这帖子虽然我看不太懂,
但是我想这个帖子肯定加精!


回复
支持
反对

免费评分
举报

.

图片[36]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

15

主题

146

帖子

74

积分



6#

图片[11]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
发表于 2021-7-9 15:27
|
只看该作者

我只能说厉害厉害。。。


回复
支持
反对

免费评分
举报

.

返回列表
图片[4]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
图片[5]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网
.

图片[36]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网


高级模式

B
Color
Image
Link
Quote
Code
Smilies

@朋友
|

拖入文件 或 浏览

    .

    验证问答 换一个图片[16]就去ID网AST – 并没有想象中那么神秘 – 『脱壳破解区』 – 吾爱破解 – LCG – LSG |安卓破解|病毒分析|www.52pojie.cn就去ID网97ID网

    本版积分规则

    警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

    回帖并转播
    回帖后跳转到最后一页

    .

    © 版权声明
    THE END
    喜欢就支持一下吧
    点赞5 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      请登录后查看评论内容