帮酷LOGO
0 0 评论
  • 显示原文与译文双语对照的内容
文章标签:Javascript  CHAR  字符  characters  JAVA  
Write any JavaScript with 6 Characters: []()!+

  • 源代码名称:jsfuck
  • 源代码网址:http://www.github.com/aemkei/jsfuck
  • jsfuck源代码文档
  • jsfuck源代码下载
  • Git URL:
    git://www.github.com/aemkei/jsfuck.git
  • Git Clone代码到本地:
    git clone http://www.github.com/aemkei/jsfuck
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/aemkei/jsfuck
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
  • JSFuck []()+!

    JSFuck是一种基于JavaScript的原子部分的深奥和教育的编程风格。 它只使用六个不同的字符来编写和执行代码。

    它不依赖于浏览器,所以你甚至可以在 Node.js. 上运行它

    演示:jsfuck.com

    @aemkei好友组成。

    示例

    下面的源代码将执行 alert(1):

    [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[
    ]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]
    ])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![
    ]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![
    ]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[
    ]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![
    ]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])
    [+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[
    ])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

    基本

    
    false =>![]
    
    
    true =>!![]
    
    
    undefined => [][[]]
    
    
    NaN => +[![]]
    
    
    0 => +[]
    
    
    1 => +!+[]
    
    
    2 =>!+[]+!+[]
    
    
    10 => +[[+!+[]]+[+[]]]
    
    
    Array => []
    
    
    Number => +[]
    
    
    String => []+[]
    
    
    Boolean =>![]
    
    
    Function => []["filter"]
    
    
    run => []["filter"]["constructor"]( CODE )()
    
    
    eval => []["filter"]["constructor"]("return eval")()( CODE )
    
    
    window => []["filter"]["constructor"]("return this")()
    
    
    
    

    请参见这里的完整列表

    工作原理

    注意:可以随意加入讨论: https://gitter.im/aemkei/jsfuck

    [] --括号

    让我们先从左括号和右括号开始,看看这里有什么。 它们对于这个项目非常有用,并且被视为核心元素,因为它们提供了一种方法来:

    • 处理数组
    • 访问属性和方法。

    [] --array-文字

    创建新数组:

    [] // an empty array[[]] // an array with one element (another array)

    [X][i] - array/Object 访问

    [][[]] // undefined, same as [][""]

    稍后我们将能够做到这一点:

    "abc"[0] // get single letter[]["length"] // get property[]["fill"] // get methods

    [X][0] --array-封装技巧

    通过将表达式包装在 array 中,然后在索引零处获取元素,我们可以在一个表达式上应用。 这意味着括号 [] 可以替换括号 () 来隔离表达式:

     [X][0] // X++[ ++[ ++[X][0] ][0] ][0] // X + 3

    + --加号

    这里符号非常有用,因为它允许我们:

    • 创建数字
    • 将两个值相加
    • 串联字符串
    • 创建字符串

    当前版本JSFuck使用很多,但我们不确定它们是否是基本的。

    转换为数字

    +[] // 0 - the number 0

    递增数字

    使用前面提到的array 环绕技巧 上面:

    ++[ 0 ][ 0 ] // 1++[ [] ][ +[] ] // 1

    正在获取 undefined

    在空 array 中按索引获取元素将返回 undefined:

    [][ 0 ] // undefined[][ +[] ] // get first element (undefined)[][ [] ] // look for property""

    正在获取 NaN

    undefined 强制转换为数字将导致 not-a-number:

    +[][[]] // +undefined = NaN

    添加数字

    1+1// 2++[[]][+[]] +++[[]][+[]] // 2

    使用++的较短方法:

    ++[ 1][ 0] // 2++[++[[]][ 0]][ 0] // 2++[++[[]][+[]]][+[]] // 2

    使用这里技术,我们可以访问所有数字:

    0123456789

    +[] --强制转换为字符串

    组合加号和括号将把其他值转换为字符串:

     [] +[] //"" - empty string+[] +[] //"0" [][[]] +[] //"undefined"++[][[]] +[] //"NaN++[[]][+[]] +[] //"1"

    "word"[i] --获取单个字符

    在字符串中,我们也可以得到单个字符:

    "undefined" [ 0] //"u"[ "undefined" ][ 0][ 0] //"u"[ undefined+[] ][+[]][+[]] //"u"[ [][+[]] +[] ][+[]][+[]] //"u"
    [[][+[]]+[]][+[]][ 1 ] // n[[][+[]]+[]][+[]][ ++[[]][+[]] ] // n

    由于我们有"nan"和"未定义",我们得到以下字符:

    NadefiNu

    + --合并字符

    现在我们可以将字符连接到新单词。

    // can be written using []+ only:"undefined"[4] //"f""undefined"[5] //"i""undefined"[6] //"n""undefined"[3] //"d"// combine using +"f"+"i"+"n"+"d"//"find"

    "e" --指数表示法中的数字

    从"未定义"中得到字符"e",可以使用指数表示法构造非常大的数字,并获得对 Infinity的引用:

    +("1e309") // Infinity+("1e309") +[] //"Infinity"+("11e100") // 1.1e+101+("11e100") +[] //"1.1e+101" (gives us `.` and `+`)+("0.0000001") // 1e-7+("0.0000001") +[] //"1e-7" (gives us `-`)

    生成的字符:

    ifiNty.+-

    []["method"] --访问方法

    新的combinded字符可以形成方法名。 可以使用方括号表示法访问这些内容:

    []["f"+"i"+"n"+"d"] // where"f" is the first char of"false" and so on[]["find"] // same as the dot syntax:[]. find

    注意:在"未定义"。"nan"和"无穷"中,我们可以在对象中找到的唯一方法就是 Array.prototype.find

    method+[] --获取方法定义

    我们可以将一个方法转换为字符串,并将它的定义作为字符串:

    []["find"] +[]

    这将返回以下字符串:

    "function find() { [native code] }"

    注意:本机函数的字符串表示不是ECMAScript标准的一部分,并且不同的浏览器之间存在不同。 例如 Firefox 将输出一个稍有不同的字符串,并使用 N 附加行中断。

    生成的字符:

    • 使用 acdefiNotu
    • {}()[]

    生成的方法:

    • .concat
    • .find

    - 逻辑非运算符!

    这是原始JSFuck集中的第四个字符,用于创建布尔值。

    注意:这个符号也可以被其他人替代,比如 < 或者 =。 请参阅"备选方案"below 节。

    X - 转换为布尔值!

    逻辑"非"运算符可以用于创建 booelans falsetrue:

    ![] // false!![] // true

    X+[] - 获取"true"和"false""!

    布尔值可以强制转换为字符串:

    ![] +[] //"false"!![] +[] //"true"

    这将使我们能够访问更多字符:

    aeflrstu

    通过设置 上面,我们将拥有 {}()[]+. INacdefilnorstuvy 来访问这些方法:

    • call
    • concat
    • constructor
    • entries
    • every
    • fill
    • filter
    • find
    • fontcolor
    • includes
    • italics
    • reduce
    • reverse
    • slice
    • sort

    重要的是:我们可以使用其他符号( 如 = ) 创建布尔值,因为它们是更强大的( 请参见"。

    X["constructor"] --原始包装器名称

    使用 .constructor,我们对创建实例的函数有一个引用。 对于基元值,它将返回相应的内置包装器:

    0 ["constructor"] // Number"" ["constructor"] // String[] ["constructor"] // Arrayfalse ["constructor"] // Boolean[].find ["constructor"] // Function

    使用 +[] 将它们转换成字符串并检索它的函数 NAME,以获取更多字符:

    0["constructor"]+[] //"function Number() {.. . }"

    可用的新字符:mbsgbaf

    。以及更多的方法和属性:

    • arguments
    • big
    • bind
    • bold
    • name
    • small
    • some
    • sub
    • substr
    • substring
    • toString
    • trim

    () --括号

    调用方法

    因为我们可以访问方法,所以我们可以调用它们来获得更多的。 为此,我们需要在这里引入另外两个符号 ()

    不带参数的示例:

    ""["fontcolor"]() //"<font color="undefined"></font>"[]["entries"]() +[] //"[object Array Iterator]"

    新字符:

    j<>="/

    number.toString(x) - 获取任何 lowercase-字母

    toString 方法的有一个可选参数,指定要使用( 2和 36之间)的基。 对于 base 36,我们可以检索任何 lowercase 字母:

    10["toString"](36) //"a"11["toString"](36) //"b"...34["toString"](36) //"y"35["toString"](36) //"z"

    公开的字符:abcdefghijklmnopqrstuvwxyz

    Function("code")() --评估代码

    函数构造函数是JSFuck中的主关键字: 它接受一个字符串作为参数,并返回一个新的匿名函数,这个字符串作为函数体。 所以它基本上让你计算任何代码作为一个字符串。 这类似于 eval,不需要引用全局范围( a。k )。 window ) 我们可以通过 []["find"]["constructor"] 获取函数构造函数 比如。

    这是JS-to-JSFuck编译器的第一个主要步骤,也是一个重要。 。

    Function("return this")() --窗口

    评估时 function anonymous() { return this } 下面是调用上下文,它是对全局作用域的引用: window

    获得对 window的引用是JSFuck的另一个巨大进步。 使用括号字符,我们只能在可用的对象中进行挖掘: 数字,数组,一些函数。"。"。引用全局范围,我们现在可以访问任何全局变量。

    组合字符

    我们可以使用 .concat 来组合字符串,而不是 +:

    "f"["concat"]("i")["concat"]("l")["concat"]("l") // fill

    问题:我们需要结合"c"。"o"。"n"。"c"。"a"和"t"来获得"连接"。

    布尔值

    可以用多于一个使用的"有力"字符替换。!

    = - 布尔值+ 赋值值

    X==X// trueX==Y// falseX=Y// assign a new value

    > - 布尔+ 创建数字

    X>Y// trueX>X// falseX>>Y// number

    一个更复杂的例子是只使用 []>+ 获取字符"f":

    [[ []>[] ] + [] ] [[]>>[]] [[]>>[]]
    [[ false ] + [] ] [ 0] [ 0]
    [ "false" ] [ 0] [ 0]
     "false" [ 0]

    电子邮件编号

    我们可以使用布尔值和bitshift运算符来创建数字,而不是 +:

    true>>false// 1true<<true// 2true<<true<<true// 4

    问题:一些数字( 像 5 ) 很难获得。 但是在使用字符串时是有可能的,例如 "11">> true

    执行函数

    执行除使用 () 以外的其他函数的方法:

    • 使用反斜杠:`
    • 处理事件:on...
    • 构造函数:new.. .
    • 类型转换:toString|valueOf
    • 符号数据类型:[Symbol...]

    使用反向引用的

    我们可以使用反引号来执行函数,而不是使用开始和结束括号。 在ES6中,它们可以用来插入字符串,并为标记的模板文本提供一个表达式。

    ([]["entries"]``).constructor// Object

    这将给我们来自"对象"的字符并访问它的方法。

    不幸的是,我们只能传递一个字符串( 从基本字母表中)。 []+ ) 作为参数。! 不可能调用具有多个参数或者预编译字符串的方法。 为此,我们必须使用 ${}的表达式插值,这将引入新的字符。

    本文详细讨论了在聊天室中反倒的可能性。

    映射类型转换

    执行不带括号的函数的另一种方法是映射 .toString 或者 .valueOf 方法,并隐式调用它们。

    A= []A["toString"] =A["pop"]A+""// will execute A.pop

    注:无法传递参数,它需要 = 出现在我们的基本字母表中。 它只对返回基本类型的方法有效。

    到目前为止,唯一的用例是在 Firefox 中连接 .toSource 以获取特殊字符,如反斜杠。

    触发器事件处理程序

    函数或者方法也可以通过assinging执行到事件处理程序中。 有几种方法可以做到这一点,e.g:

    // override onload event on startonload = f// write image tagsdocument.body.innerHTML='<img onerror=f src=X/>'// throw and handle erroronerror=f; throw'x'// trigger eventonhashchange = f; location.hash=1;

    注:我们需要 = 来分配处理程序。

    问题:我们不能访问 window 或者DOM元素来处理事件处理程序。

    构造函数

    我们还可以使用 new 运算符将函数作为伪对象类型调用:

    newf

    问题:new 运算符与我们的基本符号集不兼容。

    符号

    符号是唯一且不可变的数据类型,可以用作对象属性的标识符。 这里函数可以用于隐式调用函数。

    f[Symbol.toPrimitive] = f; f++;
    f[Symbol.iterator] = f; [...f];

    注意:我们需要 = 来分配函数。

    问题:我们无法使用我们的简化字符集访问 Symbol

    进一步阅读

    JSFuck并不是第一个 ! 世界各地的许多人试图打破所谓的"墙"。 阅读更多内容:



    文章标签:JAVA  Javascript  CHAR  字符  characters  

    Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语