jjencode|JS混淆手工解析编码过程以及自定义混淆变体改装
此前发布过关于aaencode的混淆编码,此篇文章继续说同作者的jjencode混淆编码的具体过程。
介绍
首先是jjencode的作者提供的编码测试页:http://utf-8.jp/public/jjencode.html
可以将任何合法的JavaScript代码进行编码,首先我们可以简单测试将以下代码进行编码。
编码前:
alert("Hello, JavaScript" )
编码后:
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+",\\"+$.$__+$.___+"\\"+$.__$+$.__$+$._$_+$.$_$_+"\\"+$.__$+$.$$_+$.$$_+$.$_$_+"\\"+$.__$+$._$_+$._$$+$.$$__+"\\"+$.__$+$.$$_+$._$_+"\\"+$.__$+$.$_$+$.__$+"\\"+$.__$+$.$$_+$.___+$.__+"\\\"\\"+$.$__+$.___+")"+"\"")())();
可见,编码后的JS也是很有意思,仅由符号组成的JS代码。
混淆过程
通过源代码,我们可以看到具体将JS进行编码的函数过程,如下所示:
function jjencode( gv, text )
{
var r="";
var n;
var t;
var b=[ "___", "__$", "_$_", "_$$", "$__", "$_$", "$$_", "$$$", "$___", "$__$", "$_$_", "$_$$", "$$__", "$$_$", "$$$_", "$$$$", ];
var s = "";
for( var i = 0; i < text.length; i++ ){
n = text.charCodeAt( i );
if( n == 0x22 || n == 0x5c ){
s += "\\\\\\" + text.charAt( i ).toString(16);
}else if( (0x21 <= n && n <= 0x2f) || (0x3A <= n && n <= 0x40) || ( 0x5b <= n && n <= 0x60 ) || ( 0x7b <= n && n <= 0x7f ) ){
//}else if( (0x20 <= n && n <= 0x2f) || (0x3A <= n == 0x40) || ( 0x5b <= n && n <= 0x60 ) || ( 0x7b <= n && n <= 0x7f ) ){
s += text.charAt( i );
}else if( (0x30 <= n && n <= 0x39 ) || (0x61 <= n && n <= 0x66 ) ){
if( s ) r += "\"" + s +"\"+";
r += gv + "." + b[ n < 0x40 ? n - 0x30 : n - 0x57 ] + "+";
s="";
}else if( n == 0x6c ){ // 'l'
if( s ) r += "\"" + s + "\"+";
r += "(![]+\"\")[" + gv + "._$_]+";
s = "";
}else if( n == 0x6f ){ // 'o'
if( s ) r += "\"" + s + "\"+";
r += gv + "._$+";
s = "";
}else if( n == 0x74 ){ // 'u'
if( s ) r += "\"" + s + "\"+";
r += gv + ".__+";
s = "";
}else if( n == 0x75 ){ // 'u'
if( s ) r += "\"" + s + "\"+";
r += gv + "._+";
s = "";
}else if( n < 128 ){
if( s ) r += "\"" + s;
else r += "\"";
r += "\\\\\"+" + n.toString( 8 ).replace( /[0-7]/g, function(c){ return gv + "."+b[ c ]+"+" } );
s = "";
}else{
if( s ) r += "\"" + s;
else r += "\"";
r += "\\\\\"+" + gv + "._+" + n.toString(16).replace( /[0-9a-f]/gi, function(c){ return gv + "."+b[parseInt(c,16)]+"+"} );
s = "";
}
}
if( s ) r += "\"" + s + "\"+";
r =
gv + "=~[];" +
gv + "={___:++" + gv +",$$$$:(![]+\"\")["+gv+"],__$:++"+gv+",$_$_:(![]+\"\")["+gv+"],_$_:++"+
gv+",$_$$:({}+\"\")["+gv+"],$$_$:("+gv+"["+gv+"]+\"\")["+gv+"],_$$:++"+gv+",$$$_:(!\"\"+\"\")["+
gv+"],$__:++"+gv+",$_$:++"+gv+",$$__:({}+\"\")["+gv+"],$$_:++"+gv+",$$$:++"+gv+",$___:++"+gv+",$__$:++"+gv+"};"+
gv+".$_="+
"("+gv+".$_="+gv+"+\"\")["+gv+".$_$]+"+
"("+gv+"._$="+gv+".$_["+gv+".__$])+"+
"("+gv+".$$=("+gv+".$+\"\")["+gv+".__$])+"+
"((!"+gv+")+\"\")["+gv+"._$$]+"+
"("+gv+".__="+gv+".$_["+gv+".$$_])+"+
"("+gv+".$=(!\"\"+\"\")["+gv+".__$])+"+
"("+gv+"._=(!\"\"+\"\")["+gv+"._$_])+"+
gv+".$_["+gv+".$_$]+"+
gv+".__+"+
gv+"._$+"+
gv+".$;"+
gv+".$$="+
gv+".$+"+
"(!\"\"+\"\")["+gv+"._$$]+"+
gv+".__+"+
gv+"._+"+
gv+".$+"+
gv+".$$;"+
gv+".$=("+gv+".___)["+gv+".$_]["+gv+".$_];"+
gv+".$("+gv+".$("+gv+".$$+\"\\\"\"+" + r + "\"\\\"\")())();";
return r;
}
使用方式即是:
jjencode( '$', 'alert("Hello, JavaScript" )' )
参数1,就类似于混淆代码中的一个全局变量,参数2就是具体要进行混淆的原JS代码。
代码解析
接下来我们将这段JS函数进行解析,将混淆后的代码进行阅读,以便更好的理解其编码的思路。
对比混淆
首先编码一个“空文本代码”混淆后的代码,以及一个JS仅有字符“a”混淆后的代码,并将其格式化对比查看。
左边是由空字符构成的混淆后代码,右边是由字符a构成的混淆后代码。
由此我们基本可以看出其中多出来的部分就是具体我们原本的JS代码。
为了测试,我们此次混淆一段代码并将其执行,如下:
其实际就是:
console.log("tokyo")
待更新。。。。。!2
jjencode|JS混淆手工解析编码过程以及自定义混淆变体改装的更多相关文章
- zepto.js 源码解析
http://www.runoob.com/w3cnote/zepto-js-source-analysis.html Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jqu ...
- JS引擎线程的执行过程的三个阶段(二)
继续JS引擎线程的执行过程的三个阶段(一) 内容, 如下: 三. 执行阶段 1. 网页的线程 永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数推进事件队列,等待JS引 ...
- JS命名空间模式解析
简介 在SF上看到这样一个提问: 如题,因为不得已的原因,需要写若干个全局函数.但又不想这样: window.a = function(){} window.b = function(){} wind ...
- underscore.js源码解析(五)—— 完结篇
最近公司各种上线,所以回家略感疲惫就懒得写了,这次我准备把剩下的所有方法全部分析完,可能篇幅过长...那么废话不多说让我们进入正题. 没看过前几篇的可以猛戳这里: underscore.js源码解析( ...
- underscore.js源码解析(四)
没看过前几篇的可以猛戳这里: underscore.js源码解析(一) underscore.js源码解析(二) underscore.js源码解析(三) underscore.js源码GitHub地 ...
- GET&&POST请求编码过程
编码.解码 我们在开发过程中不可避免的一个话题就是编码和解码,那么什么是编码什么是解码呢?为什么要进行编码和解码呢?下面我们一一分析! 编码和解码的概念 编码是信息从一种形式或格式转换为另一种形式的过 ...
- JS 字符串转 GBK 编码超精简实现
前言 JS 中 GBK 编码转字符串是非常简单的,直接调用 TextDecoder 即可: const gbkBuf = new Uint8Array([196, 227, 186, 195, 49, ...
- js中eval详解,用Js的eval解析JSON中的注意点
先来说eval的用法,内容比较简单,熟悉的可以跳过eval函数接收一个参数s,如果s不是字符串,则直接返回s.否则执行s语句.如果s语句执行结果是一个值,则返回此值,否则返回undefined. 需要 ...
- oracle 内存结构 share pool sql解析的过程
1.sql解析的过程 oracle首先将SQL文本转化为ASCII字符,然后根据hash函数计算其对应的hash值(hash_value).根据计算出的hash值到library cache中找到对应 ...
- Js/Jquery- Base64和UrlEncode编码解码
最近几天遇到一些URL参数明文显示的问题,因为是明文显示,容易让人通过改变参数查看到他没有权限看到内容. 一开始我的做法是自定义了规则,然后原始的那种URL编码.可是URL编译后效果不理想,他无法编译 ...
随机推荐
- HTML基础知道了解
第1章 Html介绍 1.Html和CSS的关系 1.1 学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言.下面我们就来了解下这三门技术都是用来实现什么的: 1.2 HT ...
- 安装TortoiseSVN. msi 报错 2503 2502错误
tortoisegit下载地址 https://tortoisegit.org/download/ [错误现象] 安装TortoiseSVN. msi 报错 2503 2502错误 [错误原因] 没有 ...
- spring security 从零开始搭建
1.引入 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring ...
- js内置方法
数组: 1.push()数组最后添加元素,pop()数组删除最后一个: unshift()数组开头添加元素,shift()删除数字第一个: 注意:push()和unshift()可以添加 ...
- CH340N串口无法检测问题的解决
问题原因: type-C有好几种类型,其中包括能传输数据的,也有不能传输数据.只能供电的.(本质差别就是引脚数目不同) 问题解决:只要将原来的type-C转USB的充电线换成数据线,电脑就能识别CH3 ...
- 洛谷P4342 [IOI1998]Polygon
题目 https://www.luogu.com.cn/problem/P4342 我会做IOI题辣 思路 算法设计与分析的课堂例题. 首先这是一个环状DP,那么根据老套路,破环成链.发现要求的东西也 ...
- [Python.Unix和Linux系统管理指南]书籍
Python.Unix和Linux系统管理指南书籍下载地址 提取码:eqf4 内容简介 · · · · · · <Python UNIX和Linux系统管理指南>介绍了Python语言如 ...
- vue项目的两种构建工具Vue CLI和Vite
Vue CLI官方项目搭建工具,使用的打包器是webpack,webpack使用的模块化规范是commonjs模块: Vite主要特点是开发环境启动迅速,因为是使用的ES模块,这是在现代浏览器开始原生 ...
- cadence报错because the library part is newer than the part in the design cache.Select the part in the cache and choose Design-Update Cache,and then place the part again.
cadence报错because the library part is newer than the part in the design cache.Select the part in the ...
- C#定时任务(Timer)
新建Timer类 using BaseAsset.Data.Infrastructure; using BaseAsset.Data.Repositories; using BaseAsset.Ent ...