JS逆向基础之反调试
截至目前的话大家应该都知道我们在进行js逆向的时候需要打开浏览器开发者工具进行网页的调试,但是在有时候网站会阻止我们去调试它的代码,而其阻止我们的手段也是多种多样的。接下来我们就来简单了解一下逆向过程中常见的反调试手段。
一、无限debugger
在有的网站中,当我们想要打开开发者工具调试代码的时候,总是会被自动断点到一个debugger的代码处无限的执行debugger。如下方所示:
针对这种情况,我们可以有以下几种常用的手段。
1.1 单独禁用某处的断点
这里我们可以选择将此debugger处的断点直接禁用,只需要在该行代码行数那里点击鼠标右键然后选择Never pause here
再刷新页面就不会在此处断下了。
1.2 添加条件断点
在debugger行数的位置单击鼠标右键,然后选择add conditional breakpoint
,再添加false然后回车,也可以跳过无限debugger。但是要注意,有的无限debugger是经混淆之后通过定时器来实现的,这种情况下就需要修改js代码来解决。
1.3 本地js替换
我们可以将网站中的js文件保存到本地中进行修改,主要是将无限debugger相关的代码替换或者删除,这样来达到绕过无限debugger的目的。修改之后可以通过浏览器开发者工具或者其他的抓包工具如:fiddler、charles或者mitmproxy等来进行动态拦截并替换掉js文件。
1.4 注入代码替换掉js中的无限debugger
这里其实就是用到了hook技术,通过注入一段js代码去拦截debugger处的代码并将其进行替换。这个方案目前不太好找案例,但是大家可以简单通过下方描述来了解一下先。
// 定义 XMLHttpRequest 原型对象
const XHR = XMLHttpRequest.prototype;// 保存原始 send 方法
const originalSend = XHR.send;// 重写 send 方法
XHR.send = function() {// 将所有的 debugger 替换为 console.logconst args = Array.from(arguments).map(arg => arg.replace(/debugger;/g, 'console.log("debugger");'));// 调用原始 send 方法并返回结果return originalSend.apply(this, args);
};// 定义 fetch 函数
const originalFetch = window.fetch;// 重写 fetch 函数
window.fetch = function() {// 将所有的 debugger 替换为 console.logconst args = Array.from(arguments).map(arg => arg.replace(/debugger;/g, 'console.log("debugger");'));// 调用原始 fetch 方法并返回结果return originalFetch.apply(this, args);
};
这段代码其实就是通过Hook XMLHttpRequest
和 fetch
函数,在请求发送前将无限 debugger 语句替换为普通语句,并在请求完成后恢复原来的代码。
二、开发者工具禁用
开发者工具禁用其实就是站点中禁用了F12或者鼠标右键或者其他能够打开开发者工具的快捷键,其中大多数是禁用了F12和鼠标右键。很少会出现禁用其他快捷键的站点,毕竟并不是所有的浏览器打开开发者工具的快捷键都是ctrl+shift+i。还有的站点在打开开发者工具的时候会自动关闭页面或者跳转到其他页面。遇到这些情况的时候我们的处理方式主要有以下几种:
1. 在禁用了其中某些快捷键的时候我们可以考虑使用其他的打开开发者工具的方式来打开开发者工具。例如禁用了F12那我们就选择使用鼠标右键再去打开。
2.更换浏览器,有的站点会根据浏览器来判断。
3.打开开发者工具页面自动关闭。可以通过HOOK来定位到参数然后在页面关闭之前进行断点。如果是没有找到参数位置的话可以先任意断点然后定位到页面关闭的位置先将关闭页面的js替换。
4.打开开发者工具之后页面发生跳转。这种情况一般是网站做了触发限制,我们可以使用页面中的事件监听断点event listener breakpoint。
三、控制台问题
在有的站点中,打开开发者工具之后,console会无限输出某些内容或者会无限执行清空操作,导致我们无法通过console来调试js代码中的部分逻辑。那么其实到这里大家也应该能够猜测到,这种情况就是通过js代码来实现的,所以我们只需要定位到这些无限清空或者无限输出的代码位置然后通过hook技术来将其进行替换或者删除即可。
四、蜜獾
蜜獾也称为“蜜獾攻击”,其目标是欺骗黑客攻击虚假系统,以便安全人员能够监视和记录他们的活动,通常被用于保护真实系统免受攻击。
在JS逆向中,蜜獾通常指的是被嵌入到网站或者应用程序中的一些特殊代码(无用代码块和花指令)。这些代码可能并不会对底层逻辑有任何影响,而这些代码通常都是单独的一块或者多块,哪怕是将这些代码删除也不会影响到原页面的正常运行。除了无用代码之外,还会存在着一些花指令,例如一些调用、跳转等,这些指令通常将大家引导到一个错误的调用逻辑之中。
当然,由于JS是一门解释性的语言,所以从严格意义来讲并不存在花指令这种概念。花指令通常指汇编语言中的一些特殊指令,用于执行一些非常规操作或性能优化。
在JavaScript中,可以使用一些高级技术来实现类似于花指令的效果。例如:
- WebAssembly:WebAssembly是一种新型的二进制格式,它可以在浏览器中运行本地代码。通过使用WebAssembly,开发者可以直接使用C/C++等语言编写高效的算法,并且可以获得比JavaScript更好的性能。
- asm.js:asm.js是一种JavaScript子集,它专门为了提高性能而设计。asm.js代码经过特殊编译后可以达到近乎原生代码的速度。
- SIMD.js:SIMD(单指令多数据)是一种处理大量数据的技术,在JavaScript中可以通过使用SIMD.js库来实现。该库提供了一些类似于花指令的API,用于执行高效的向量计算和浮点数运算等操作。
需要注意的是,在JavaScript中使用这些技术需要具备较强的编程和计算机系统知识,并且需要考虑到跨平台和兼容性等问题。其核心就是添加一些毫无意义却能够混淆视听的代码,如下方将一个二项式转函数花指令。
function aaa(a, b){return a+b
}
function bbb(a,b){return aaa(a,b)
}
aaa(1, 2) // 输出7
此处看到的是一个非常简单的例子,在实际的逆向过程中,代码可能是有成百上千乃至上万行,所以调用的函数与实际定义的函数可能会有很大的差别。一般能力足够的情况下会选择使用AST技术来还原掉花指令,当然并不是说只能去AST,不怕严重脱发的话选择硬扣也是完全可以的。
五、内存爆破
平时在调试js代码时,经常会出现浏览器卡死的情况,有时候是在调试js的过程中,有时候是在console中调试代码的过程中,有时候是在格式化代码之后,甚至有时候在打开开发者工具之后直接卡崩溃。这些情况其实就是因为在网站中存在着监测状态的代码,这些代码在监测到我们开始调试的一些状态之后就会执行一段占用内存或者能让浏览器内存溢出的代码,从而导致我们的调试没有办法继续进行。
而解决办法就是找到这段让浏览器发生崩溃的代码,然后将其进行替换或者删除。
六、代码混淆
6.1 eval混淆
eval是v8引擎中定义的一个方法,这个方法能够执行一段JS代码,该方法中传入的是字符串,该字符串是一串可执行的js代码。例如:
jscode = "(function(){return 3})()"
result = eval(jscode)
console.log(result)
进一步处理的话就可以将jscode进行base64编码,然后eval中解码后再进行还原。如下:
// jscode = btoa("(function(){return 3})()")
jscode = "KGZ1bmN0aW9uKCl7cmV0dXJuIDN9KSgp"
result = eval(atob(jscode))
console.log(result)
6.2 aa混淆
其主要是利用了unicode特性进行混淆,将js代码转变成了一些常用的网络表情,例如,将上方的三行代码进行aa混淆之后代码如下:
゚ω゚ノ = /`m´)ノ ~┻━┻ //*´∇`sojson.com*/ ['_'];
o = (゚ー゚) = _ = 3;
c = (゚Θ゚) = (゚ー゚) - (゚ー゚);
(゚Д゚) = (゚Θ゚) = (o ^ _ ^ o) / (o ^ _ ^ o);
(゚Д゚) = {゚Θ゚: '_',゚ω゚ノ: ((゚ω゚ノ == 3) + '_') [゚Θ゚],゚ー゚ノ: (゚ω゚ノ + '_')[o ^ _ ^ o - (゚Θ゚)],゚Д゚ノ: ((゚ー゚ == 3) + '_')[゚ー゚]
};
(゚Д゚) [゚Θ゚] = ((゚ω゚ノ == 3) + '_') [c ^ _ ^ o];
(゚Д゚) ['c'] = ((゚Д゚) + '_') [(゚ー゚) + (゚ー゚) - (゚Θ゚)];
(゚Д゚) ['o'] = ((゚Д゚) + '_') [゚Θ゚];
(゚o゚) = (゚Д゚) ['c'] + (゚Д゚) ['o'] + (゚ω゚ノ + '_')[゚Θ゚] + ((゚ω゚ノ == 3) + '_') [゚ー゚] + ((゚Д゚) + '_') [(゚ー゚) + (゚ー゚)] + ((゚ー゚ == 3) + '_') [゚Θ゚] + ((゚ー゚ == 3) + '_') [(゚ー゚) - (゚Θ゚)] + (゚Д゚) ['c'] + ((゚Д゚) + '_') [(゚ー゚) + (゚ー゚)] + (゚Д゚) ['o'] + ((゚ー゚ == 3) + '_') [゚Θ゚];
(゚Д゚) ['_'] = (o ^ _ ^ o) [゚o゚] [゚o゚];
(゚ε゚) = ((゚ー゚ == 3) + '_') [゚Θ゚] + (゚Д゚).゚Д゚ノ + ((゚Д゚) + '_') [(゚ー゚) + (゚ー゚)] + ((゚ー゚ == 3) + '_') [o ^ _ ^ o - ゚Θ゚] + ((゚ー゚ == 3) + '_') [゚Θ゚] + (゚ω゚ノ + '_') [゚Θ゚];
(゚ー゚) += (゚Θ゚);
(゚Д゚)[゚ε゚] = '\\';
(゚Д゚).゚Θ゚ノ = (゚Д゚ + ゚ー゚)[o ^ _ ^ o - (゚Θ゚)];
(o゚ー゚o) = (゚ω゚ノ + '_')[c ^ _ ^ o];
(゚Д゚) [゚o゚] = '\"';
(゚Д゚) ['_']((゚Д゚) ['_'](゚ε゚ + (゚Д゚)[゚o゚] + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚ー゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (o ^ _ ^ o)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚ー゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (c ^ _ ^ o) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (o ^ _ ^ o) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (o ^ _ ^ o)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (c ^ _ ^ o) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (o ^ _ ^ o) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (c ^ _ ^ o) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (o ^ _ ^ o)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚ー゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (o ^ _ ^ o)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚ー゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚o゚])(゚Θ゚))((゚Θ゚) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚o゚]);
这串混淆后的代码在引擎中是完全可以正常运行的。
可以看出aa混淆的代码基本上已经完全不像是代码了,更像是女孩子们喜欢使用的表情,但是其也有缺点,就是压栈严重,所以并不适合代码量比较大的脚本加密。
压栈(Stack)是一种常见的数据结构,具有“后进先出”(Last-In-First-Out,LIFO)的特点。这种数据结构的特点是,只能在栈顶进行插入和删除操作。当一个元素被插入到栈中后,只有在这个元素被删除之后,才能插入下一个元素。
压栈的操作又称为入栈(Push),弹出栈的操作又称为出栈(Pop)。栈还具有许多其他的操作,比如获取栈顶元素(Top)、判断栈是否为空(IsEmpty)等等。
栈被广泛应用于计算机科学中。比如,编译器使用栈来管理函数的调用和返回,操作系统使用栈来存储函数调用的上下文信息等等。
6.3 jj混淆
jj混淆与aa混淆是差不多的,主要也是利用了unicode特性,将代码转换成有着大量符号的混淆文本。将3.1中的代码进行jj混淆后如下:
sojson=~[];/*sojson.com*/sojson={___:++sojson,/*sojson.com*/$$$$:(![]+"")[sojson],__$:++sojson,$_$_:(![]+"")[sojson],_$_:++sojson,$_$$:({}+"")[sojson],$$_$:(sojson[sojson]+"")[sojson],_$$:++sojson,$$$_:(!""+"")[sojson],$__:++sojson,$_$:++sojson,$$__:({}+"")[sojson],$$_:++sojson,$$$:++sojson,$___:++sojson,$__$:++sojson};sojson.$_=(sojson.$_=sojson+"")[sojson.$_$]+(sojson._$=sojson.$_[sojson.__$])+(sojson.$$/*sojson.com*/=(sojson.$+"")[sojson.__$])+((!sojson)+"")[sojson._$$]+(sojson.__=sojson.$_[sojson.$$_])+(sojson.$=(!""+"")[sojson.__$])+(sojson._=(!""+"")[sojson._$_])+sojson.$_[sojson.$_$]+sojson.__+sojson._$+sojson.$;/*sojson.com*/sojson.$$=sojson.$+(!""+"")[sojson._$$]+sojson.__+sojson._+sojson.$+sojson.$$/*sojson.com*/;sojson.$=(sojson.___)[sojson.$_][sojson.$_];sojson.$(sojson.$(sojson.$$+"\""+"\\"+sojson.__$+sojson.$_$+sojson._$_+"\\"+sojson.__$+sojson.$$_+sojson._$$+sojson.$$__+sojson._$+sojson.$$_$+sojson.$$$_+" \\"+sojson.$$$+sojson.$_$+" \\\"\\"+sojson.__$+sojson.__$+sojson._$$+"\\"+sojson.__$+sojson.___+sojson.$$$+"\\"+sojson.__$+sojson._$$+sojson._$_+sojson.__$+sojson.$_$$+"\\"+sojson.__$+sojson.$_$+sojson.$_$+"\\"+sojson.__$+sojson.__$+sojson.$$_+sojson.___+sojson.$_$_+"\\"+sojson.__$+sojson._$_+sojson.$$$+sojson.$__$+sojson._+"\\"+sojson.__$+sojson.__$+sojson._$$+"\\"+sojson.__$+sojson.___+sojson._$$+(![]+"")[sojson._$_]+sojson.$$$+sojson.$$__+"\\"+sojson.__$+sojson.$_$+sojson.$_$+"\\"+sojson.__$+sojson._$_+sojson.$$_+sojson.___+sojson.$$_$+"\\"+sojson.__$+sojson._$$+sojson.___+"\\"+sojson.__$+sojson.__$+sojson._$_+sojson._+"\\"+sojson.__$+sojson.__$+sojson.__$+"\\"+sojson.__$+sojson.___+sojson.$__+"\\"+sojson.__$+sojson.__$+sojson.$$_+sojson.$__$+"\\"+sojson.__$+sojson.__$+sojson._$$+"\\"+sojson.__$+sojson._$_+sojson._$$+"\\"+sojson.__$+sojson.$__+sojson.$$$+"\\"+sojson.__$+sojson.$$_+sojson.___+"\\\"\\"+sojson.__$+sojson._$_+"\\"+sojson.__$+sojson.$$_+sojson._$_+sojson.$$$_+"\\"+sojson.__$+sojson.$$_+sojson._$$+sojson._+(![]+"")[sojson._$_]+sojson.__+" \\"+sojson.$$$+sojson.$_$+" "+sojson.$$$_+"\\"+sojson.__$+sojson.$$_+sojson.$$_+sojson.$_$_+(![]+"")[sojson._$_]+"("+sojson.$_$_+sojson.__+sojson._$+sojson.$_$$+"(\\"+sojson.__$+sojson.$_$+sojson._$_+"\\"+sojson.__$+sojson.$$_+sojson._$$+sojson.$$__+sojson._$+sojson.$$_$+sojson.$$$_+"))\\"+sojson.__$+sojson._$_+sojson.$$__+sojson._$+"\\"+sojson.__$+sojson.$_$+sojson.$$_+"\\"+sojson.__$+sojson.$$_+sojson._$$+sojson._$+(![]+"")[sojson._$_]+sojson.$$$_+"."+(![]+"")[sojson._$_]+sojson._$+"\\"+sojson.__$+sojson.$__+sojson.$$$+"(\\"+sojson.__$+sojson.$$_+sojson._$_+sojson.$$$_+"\\"+sojson.__$+sojson.$$_+sojson._$$+sojson._+(![]+"")[sojson._$_]+sojson.__+")"+"\"")())(sojson={___:++sojson,$$$$:(![]+"")[sojson]});
可以看到,混淆后的代码有很多的$符号,可读性几乎是没有的,所以这种代码是必须去还原之后才能够进行逆向,一般可以通过一些解码工具进行解码,当然也可以将其复制到控制台中运行。如果整体执行失败的话可以按照;
进行分割然后逐行进行分析调试。
除了上述混淆之外,代码混淆的方式还有许许多多,如jsfuck混淆
、OB混淆
、OLLVM混淆
等等。如我们在马蜂窝案例中所见就是一个典型的OB混淆代码。