0.测试通用demo
1 | var arrs=new Array("java","python","js","c++","go"); |
1.JavaScript 压缩
JavaScript 压缩即去除 JavaScript 代码中的不必要的空格、换行等内容或者把一些可能公用的代码进行处理实现共享,最后输出的结果都压缩为几行内容,代码可读性变得很差,同时也能提高网站加载速度。
工具:Webpack、在线压缩工具
1 | var arrs=new Array("java","python","js","c++","go");function testDemo(){for(i=0;i<arrs.length;i++){console.log(arrs[i])}}testDemo(); |
还原工具:在线解缩工具、ide、chrome
可以发现通过压缩方式,几乎没有任何作用,因为这种压缩方式仅仅是降低了代码的直接可读性。
2.JavaScript代码混淆
使用变量替换、字符串阵列化、控制流平坦化、多态变异、僵尸函数、调试保护等手段,使代码变地难以阅读和分析,达到最终保护的目的。
混淆技术主要有以下几种:
- 变量混淆:将带有含意的变量名、方法名、常量名随机变为无意义的类乱码字符串,降低代码可读性,如转成单个字符或十六进制字符串。
- 字符串混淆:将字符串阵列化集中放置、并可进行 MD5 或 Base64 加密存储,使代码中不出现明文字符串,这样可以避免使用全局搜索字符串的方式定位到入口点。
- 属性加密:针对 JavaScript 对象的属性进行加密转化,隐藏代码之间的调用关系。
- 控制流平坦化:打乱函数原有代码执行流程及函数调用关系,使代码逻变得混乱无序。
- 僵尸代码:随机在代码中插入无用的僵尸代码、僵尸函数,进一步使代码混乱。
- 调试保护:基于调试器特性,对当前运行环境进行检验,加入一些强制调试 debugger 语句,使其在调试模式下难以顺利执行 JavaScript 代码。
- 多态变异:使 JavaScript 代码每次被调用时,将代码自身即立刻自动发生变异,变化为与之前完全不同的代码,即功能完全不变,只是代码形式变异,以此杜绝代码被动态分析调试。
- 锁定域名:使 JavaScript 代码只能在指定域名下执行。
- 反格式化:如果对 JavaScript 代码进行格式化,则无法执行,导致浏览器假死。
- 特殊编码:将 JavaScript 完全编码为人不可读的代码,如表情符号、特殊表示内容等等。如使用 aaencode、jjencode、jsfuck 等工具对代码进行混淆和编码。
- 加壳干扰:在代码用eval包裹,然后对eval参数进行加密,并埋下陷阱,在解码时插入无用代码,干扰显示,大量换行、注释、字符串等大量特殊字符,导致显示卡顿。
工具:Obfuscator
以下简单举几个有意思的例子:
2.1调试保护
这里仅对demo做了修改标识符名称与调试保护,可以看到代码以经不是很好看懂了。
1 | var arrs = new Array('java', 'python', 'js', 'c++', 'go'); |
这里使用下条件断点的方式完轻松绕过。
2.2反格式化
开启之后,混淆后的 JavaScript 会以强制一行形式显示,如果我们将混淆后的代码进行格式化(美化)或者重命名,该段代码将无法执行.
2.3控制流平坦化
将代码的执行逻辑混淆,使其变得复杂难读。其基本思想是将一些逻辑处理块都统一加上一个前驱逻辑块,每个逻辑块都由前驱逻辑块进行条件判断和分发,构成一个个闭环逻辑,导致整个执行逻辑十分复杂难读。
1 | var arrs = new Array('java', 'python', 'js', 'c++', 'go'); |
由于例子逻辑简单,只是一个简单的循环,但还是可以看出通过该方式处理后的代码,在循环前加了一个逻辑判断。因此,使用控制流扁平化可以使得执行逻辑更加复杂难读,前端混淆都会加上这个选项。
2.4eval
js中的eval()方法就是一个js语言的执行器,它能把其中的参数按照JavaScript语法进行解析并执行,简单来说就是把原本的js代码变成了eval的参数,变成参数后代码就成了字符串,其中的一些字符就会被按照特定格式“编码”。
在线加解密工具:http://www.jqueryfuns.com/tools/jsencode
效果如下:
1 | eval(function(p,a,c,k,e,r){e=String;if('0'.replace(0,e)==0){while(c--)r[e(c)]=k[c];k=[function(e){return r[e]||e}];e=function(){return'[23]'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('var 2=new Array("java","python","js","c++","go");function 3(){for(i=0;i<2.length;i++){console.log(2[i])}}3()',[],4,'||arrs|testDemo'.split('|'),0,{})) |
3.代码加密:
可以通过某种手段将 JavaScript 代码进行加密,转成人无法阅读或者解析的代码,如将代码完全抽象化加密,如 eval 加密。另外还有更强大的加密技术,可以直接将 JavaScript 代码用 C/C++ 实现,JavaScript 调用其编译后形成的文件来执行相应的功能,如 Emscripten 还有 WebAssembly。
基本思路是将一些核心逻辑使用诸如 C/C++ 语言来编写,并通过 JavaScript 调用执行,从而起到二进制级别的防护作用。
加密方式:
3.1Emscripten 这个编译器可以将 C / C++ 代码编译成 asm.js
3.2WebAssembly可以将 C / C++ 代码编译二进制字节码
先用在线工具 生成一个wasm文件,http://mbebenita.github.io/WasmExplorer/
用例:
1 | function loadWebAssembly(filename, imports) { |