文档章节

JavaScript学习:JSFuck代码阅读笔记

北风其凉
 北风其凉
发布于 2016/02/06 21:42
字数 1181
阅读 704
收藏 11
点赞 1
评论 0

JSFuck源码地址(GitHub):https://github.com/aemkei/jsfuck

JSFuck在OSC上的介绍页面:http://www.oschina.net/p/jsfuck

JSFuck可以将JavaScript代码进行转换,转换后的代码只使用6个字符([,],(,),!,+),实现的功能和转换前代码是一样的。出于好奇和学习的目的,我研究了一下JSFuck的源码。

在网站 http://www.jsfuck.com/ 中有一个例子,将JavaScript语句 alert(1) 转换为只由六种字符的版本:

将这段代码放到HTML文件的script标签下,就可以运行了:

<html>
    <head>
        <title>happy new year</title>
    </head>
    <body>
    <script>
 [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
    </script>
    </body>
</html>

不过,我想了解的是,为什么这段代码会起作用。研究后才发现,这段代码等价于另一段代码:

[]["filter"]["constructor"]("return eval")()("alert(1)")

在这段代码中,alert(1)是我们要转换的JavaScript源码,这段代码的意思是执行JavaScript代码alert(1)。这段代码是由四个字符串和字符[、]、(、)构成的。也就是说,我们只要能把字符串中的每一个字符,都用[,],(,),!,+这六个字符表示出来,那么我们就完全可以将任何一段JavaScript代码,找到仅用这六个字符表示的等价形式。

那么,我们来看一下各个字符的等价形式:(如果用console.log输出右边的部分,则会返回左边的字符,0-9这10个字符外面又套了一层[],这样做是为了保证在之后用+运算符进行拼接时不被系统识别为加法运算)

'0':'[+[]]'
'1':'[+!+[]]'
'2':'[!+[]+!+[]]'
'3':'[!+[]+!+[]+!+[]]'
'4':'[!+[]+!+[]+!+[]+!+[]]'
'5':'[!+[]+!+[]+!+[]+!+[]+!+[]]'
'6':'[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]'
'7':'[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]'
'8':'[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]'
'9':'[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]'
'a':'(false+"")[1]'
'b':'(Function("return{}")()+"")[2]'
'c':'([]["filter"]+"")[3]'
'd':'(undefined+"")[2]'
'e':'(true+"")[3]'
'f':'(false+"")[0]'
'g':'(false+[0]+String)[20]'
'h':'(+(101))["toString"](21)[1]'
'i':'([false]+undefined)[10]'
'j':'(Function("return{}")()+"")[10]'
'k':'(+(20))["toString"](21)'
'l':'(false+"")[2]'
'm':'(Number+"")[11]'
'n':'(undefined+"")[1]'
'o':'(true+[]["filter"])[10]'
'p':'(+(211))["toString"](31)[1]'
'q':'(+(212))["toString"](31)[1]'
'r':'(true+"")[1]'
's':'(false+"")[3]'
't':'(true+"")[0]'
'u':'(undefined+"")[0]'
'v':'(+(31))["toString"](32)'
'w':'(+(32))["toString"](33)'
'x':'(+(101))["toString"](34)[1]'
'y':'(NaN+[Infinity])[10]'
'z':'(+(35))["toString"](36)'
'A':'(+[]+Array)[10]'
'B':'(+[]+Boolean)[10]'
'C':'Function("return escape")()(("")["italics"]())[2]'
'D':'Function("return escape")()([]["filter"])["slice"]("-1")'
'E':'(RegExp+"")[12]'
'F':'(+[]+Function)[10]'
'G':'(false+Function("return Date")()())[30]'
'H':'Function("return unescape")()("%"+(48)+"")'
'I':'(Infinity+"")[0]'
'J':'Function("return unescape")()("%"+(4)+"a")'
'K':'Function("return unescape")()("%"+(4)+"b")'
'L':'Function("return unescape")()("%"+(4)+"c")'
'M':'(true+Function("return Date")()())[30]'
'N':'(NaN+"")[0]'
'O':'(NaN+Function("return{}")())[11]'
'P':'Function("return unescape")()("%"+(50)+"")'
'Q':'Function("return unescape")()("%"+(51)+"")'
'R':'(+[]+RegExp)[10]'
'S':'(+[]+String)[10]'
'T':'(NaN+Function("return Date")()())[30]'
'U':'(NaN+Function("return{}")()["toString"]["call"]())[11]'
'V':'Function("return unescape")()("%"+(56)+"")'
'W':'Function("return unescape")()("%"+(57)+"")'
'X':'Function("return unescape")()("%"+(58)+"")'
'Y':'Function("return unescape")()("%"+(59)+"")'
'Z':'Function("return unescape")()("%"+(5)+"a")'
' ':'(NaN+[]["filter"])[11]'
'!':'Function("return unescape")()("%"+(21)+"")'
'"':'("")["fontcolor"]()[12]'
'#':'Function("return unescape")()("%"+(23)+"")'
'$':'Function("return unescape")()("%"+(24)+"")'
'%':'Function("return escape")()([]["filter"])[20]'
'&':'("")["link"](0+")[10]'
''':'Function("return unescape")()("%"+(27)+"")'
'(':'(false+[]["filter"])[20]'
')':'(true+[]["filter"])[20]'
'*':'Function("return unescape")()("%"+(2)+"a")'
'+':'(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]'
',':'([]["slice"]["call"](false+"")+"")[1]'
'-':'(+(.+[0000000001])+"")[2]'
'.':'(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]'
'/':'(false+[0])["italics"]()[10]'
':':'(RegExp()+"")[3]'
';':'("")["link"](")[14]'
'<':'("")["italics"]()[0]'
'=':'("")["fontcolor"]()[11]'
'>':'("")["italics"]()[2]'
'?':'(RegExp()+"")[2]'
'@':'Function("return unescape")()("%"+(40)+"")'
'[':'(Function("return{}")()+"")[0]'
'\':'Function("return unescape")()("%"+(5)+"c")'
']':'(Function("return{}")()+"")["slice"]("-1")'
'^':'Function("return unescape")()("%"+(5)+"e")'
'_':'Function("return unescape")()("%"+(5)+"f")'
'`':'Function("return unescape")()("%"+(60)+"")'
'{':'(NaN+[]["filter"])[21]'
'|':'Function("return unescape")()("%"+(7)+"c")'
'}':'([]["filter"]+"")["slice"]("-1")'
'~':'Function("return unescape")()("%"+(7)+"e")'

要将上面的字符转换成六种字符的等价形式,还需要用到下面的几个等价形式带入解决:

var SIMPLE = {
  'false':      '![]',
  'true':       '!![]',
  'undefined':  '[][[]]',
  'NaN':        '+[![]]',
  'Infinity':   '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])' // +"1e1000"
};

var CONSTRUCTORS = {
  'Array':    '[]',
  'Number':   '(+[])',
  'String':   '([]+[])',
  'Boolean':  '(![])',
  'Function': '[]["filter"]',
  'RegExp':   'Function("return/"+false+"/")()'
};

使用SIMPLE和CONSTRUCTORS内的等价形式,即可推算出上面那些字符的内容。比如a的等价形式是(false+"")[1],将false替换为![],将""替换为[],将1替换为+!+[],就可以推算出a使用六个字符表示的等价形式为(![]+[])[+!+[]]。(PS:从中不难发现作者aemkei真是用心良苦)

这样看来,以alert(1)为例,每个字符的等价形式如下:

'a':'(![]+[])[+!+[]]'
'l':'(![]+[])[!+[]+!+[]]'
'e':'(!![]+[])[!+[]+!+[]+!+[]]'
'r':'(!![]+[])[+!+[]]'
't':'(!![]+[])[+[]]'
'(':'(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]'
'1':'[+!+[]]'
')':'(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]'

将它们用符号“+”连接起来,就可以获取"alert(1)"的等价形式了!同理我们获得了"filter"、"constuctor"、"return eval"的等价形式,再回头看看这段代码:

[]["filter"]["constructor"]("return eval")()("alert(1)")

将字符串替换后,放入HTML中的script标签里面,或是放到一个js文件里面,就可以用浏览器打开HTML文件查看效果啦!

(图中浏览器版本为:Google Chrome 46.0.2490.80 m)

-- 2016年2月8日 再补充一点:

如果JSFuck找不到一个字符的等价形式(比如输入中含有汉字),那么JSFuck会通过下面的方式找到该字符,以字符“呵”为例:

([]+[])["constructor"]["fromCharCode"]("呵".charCodeAt(0))

其中表达式

"呵".charCodeAt(0)

可以通过计算得出,它的值是21621,那么上面的表达式就可以替换为

([]+[])["constructor"]["fromCharCode"](21621)

将这个表达式中的字符串和数字运用之前介绍的规则进行等价替换,就可以完美地将非ASCII码字符转换为六种JSFuck符号的问题了!

END

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 114
博文 493
码字总数 462457
作品 4
朝阳
程序员
按钮配置之自定义按钮使用(二)— JEPLUS软件快速开发平台

JEPLUS按钮配置之自定义按钮使用(二) 之前的一篇笔记讲的是在列表上添加自定义按钮来完成自己的业务需求,今天这篇笔记就主要讲一下如何在表单上添加自定义按钮来实现自己的业务需求。 一、...

JEPLUS ⋅ 前天 ⋅ 0

JSON,异步加载(学习笔记)

JSON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来数据传输的,前端与后端的数据通信) JSON是静态类(不需要构造),类似于Math,内部...

Mrs_CoCo ⋅ 04/23 ⋅ 0

JavaScript 编程精解 中文第三版 零、前言

零、前言 原文:Introduction 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 We think we are creating the system for our own purp...

ApacheCN_飞龙 ⋅ 06/01 ⋅ 0

平台按钮配置之Action按钮的使用——JEPLUS软件快速开发平台

JEPLUS平台按钮配置之Action按钮的使用 系统开发过程中常规的按钮功能可能无法满足我们的业务需求,这时候就需要我们来使用Action按钮进行业务逻辑的完成,今天这篇笔记就简单介绍一下JEPLU...

JEPLUS ⋅ 前天 ⋅ 0

JavaWeb01-HTML篇笔记(七)

.1 案例三:完成对注册页面的数据的简单校验.1.1.1 需求: 对注册页面的数据进行非空的简单校验!!!如果有某个值没有输入,点击提交,弹出一个对话框进行提示!! 1.1.2 分析:1.1.2.1 技术分...

我是小谷粒 ⋅ 04/28 ⋅ 0

NODE高级编程阅读笔记系列(一)

本篇涉及以下主题 node简单介绍 事件驱动编程 模块化 缓冲区处理 Node简单介绍 直接用官方的那句话: Node.js 是一种建立在Google Chrome's V8 引擎上的non-blocking(非阻塞),event-driven(...

可爱的圣诞老人 ⋅ 05/23 ⋅ 0

前端学习之路(从入门到入坑...)

学习前端两年多了,拿了阿里巴巴实现offer,想结合个人经历总结的前端入门方法,总结从零基础到具备前端基本技能的道路、学习方法、资料。由于能力有限,不能保证面面俱到,只是作为入门参考...

阿小庆 ⋅ 06/14 ⋅ 0

第一章--JavaScript简介

1. JavaScript的构成 1.1. ECMAScript ECMAScript规定了核心语言的组成部分分别为:语法、类型、语句、关键字、保留字、操作符、对象。 宿主环境:Web浏览器、Node、Adobe Flash。 1.2. DOM...

lovewt ⋅ 06/05 ⋅ 0

网易音乐前端实习程序员面试的10个问题,你会几个?

近日,w3cschool app开发者头条上分享了网易音乐前端实习程序员面经,引来了不少程序员粉丝们的围观。 在分享网易音乐前端实习面试问题之前,w3cschool先跟小伙伴们分享前端学习干货: 0、h...

W3Cschool ⋅ 04/17 ⋅ 0

前端要以正确的姿势学习编译原理(上篇)

前端要以正确的姿势学习编译原理(上篇) 发布于 02:05 文章被以下专栏收录

brambles ⋅ 05/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部