V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
gzzhanghao
V2EX  ›  JavaScript

写了个反编译 JavaScript 的 babel 插件

  •  
  •   gzzhanghao · 2016-10-02 16:09:10 +08:00 · 7143 次点击
    这是一个创建于 2762 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先上项目地址: https://github.com/gzzhanghao/babel-plugin-transform-beautifier

    js-beautifier反编译出来的代码长这样:

    function _scrollToView(a) {
      var b = this, c = b.listItems.eq(b.currentFocus), d = b.list.scrollTop(), e = c.height(), f = c.position().top, g = Math.abs(f), h = b.list.height();
      return "search" === a ? e > h - f ? b.list.scrollTop(d + (f - (h - e))) :-1 > f && b.list.scrollTop(f - e) :"up" === a ? -1 > f && b.list.scrollTop(d - g) :"down" === a && e > h - f && b.list.scrollTop(d + (g - h + e)), 
    b;
    }
    

    先通过babel-plugin-transform-beautifier再用js-beautifier反编译出来的代码长这样:

    function _scrollToView(a) {
      var b = this;
      var c = b.listItems.eq(b.currentFocus);
      var d = b.list.scrollTop();
      var e = c.height();
      var f = c.position()
          .top;
      var g = Math.abs(f);
      var h = b.list.height();
    
      if ("search" === a) {
        if (e > h - f) {
          b.list.scrollTop(d + (f - (h - e)));
        } else if (-1 > f) {
          b.list.scrollTop(f - e);
        }
      } else if ("up" === a) {
        if (-1 > f) {
          b.list.scrollTop(d - g);
        }
      } else if ("down" === a && e > h - f) {
        b.list.scrollTop(d + (g - h + e));
      }
    
      return b;
    }
    

    代码片段取自这里

    使用方法

    先用 npm 安装:

    npm i --save-dev babel-plugin-transform-beautifier
    

    然后给 babel 加上对应 plugin 就好:

    {
        plugins: ['transform-beautifier'],
    }
    

    注意: 插件只负责正常 beautifier 不做的事,也就是说要反编译一份代码我们需要先让它通过babel-plugin-transform-beautifier再通过js-beautifier

    How it works

    插件的主要作用是通过各种转换把js-beautifier不做的事情给做了,比如把 SequenceExpression 拆成多个 Statement ,还有就是把 LogicalExpressionConditionalExpression 转换成 IfStatement

    比如下面的代码:

    a = b, a() && b ? c() : d()
    

    经过转换会变成:

    a = b
    if (a() && b) {
        c()
    } else {
        d()
    }
    

    除此之外还有很多转换规则,这里不一一列举。

    15 条回复    2016-10-04 01:22:27 +08:00
    DoraJDJ
        1
    DoraJDJ  
       2016-10-02 16:28:58 +08:00
    这应该得叫反混淆吧...
    JS 编译完全没听说过
    moyang
        2
    moyang  
       2016-10-02 16:32:59 +08:00 via Android
    对,反混淆。感觉还是很有意义的,特别是拆 sequential expression ,对放 debug break 很有用
    bramblex
        3
    bramblex  
       2016-10-02 16:43:57 +08:00 via Android
    人家那是压缩,不是混淆…
    yangxiongguo
        4
    yangxiongguo  
       2016-10-02 18:11:42 +08:00
    chrome 里按一下 {} ?
    justjavac
        5
    justjavac  
       2016-10-02 19:46:43 +08:00 via Android
    反压缩
    moyang
        6
    moyang  
       2016-10-02 20:19:18 +08:00 via Android
    @yangxiongguo 这样如果一堆 statement 是 a,b,c 这样下来的你就没法放 break point 在 b ,只能放在 a 然后往后走
    gzzhanghao
        7
    gzzhanghao  
    OP
       2016-10-02 20:21:09 +08:00 via iPhone
    楼上干嘛那么纠结用词问题…在这个语境下我说反编译应该都知道这是在干嘛吧(´・_・`)
    gzzhanghao
        8
    gzzhanghao  
    OP
       2016-10-02 20:28:29 +08:00 via iPhone
    @yangxiongguo chrome 的格式化工具不会处理`a?b:c`和`a&&b`这两种情况,实际处理效果和 js-beautify 生成的结果并没有多大区别
    fulvaz
        9
    fulvaz  
       2016-10-02 21:18:07 +08:00
    .....不, 我点进来是以为楼主实现了从 js 反编译到 c++或者汇编什么的, 并不以为只是 beautify
    gzzhanghao
        10
    gzzhanghao  
    OP
       2016-10-02 22:16:53 +08:00
    @fulvaz 那叫编译吧,这样的话反编译是指从 v8 生成的汇编变回 js ,这就有点高端了_(:з」∠)_
    crysislinux
        11
    crysislinux  
       2016-10-02 22:29:53 +08:00
    不错,点赞
    qfdk
        12
    qfdk  
       2016-10-03 13:52:56 +08:00 via iPhone
    有个词叫做 pretty print 找个 js 的就好了 每次碰到混淆的代码就这么处理
    gzzhanghao
        13
    gzzhanghao  
    OP
       2016-10-03 15:03:19 +08:00
    @qfdk 其实就是 beautifier 吧,这个工具不是用来格式化代码的,而是用来把一些压缩后的语句恢复正常的。

    比如下面这段代码:

    ```javascript
    if (a) {
    b()
    } else if (c) {
    d()
    }
    ```

    uglifyjs 会把它转换成`a ? b : c && d`,我所知道的所有代码格式化工具对这种表达式都只是原样输出,而我这个工具能把它变回原来的 if 语句。这点从我上面贴出来的代码就可以看出区别了。
    aaronrzh
        14
    aaronrzh  
       2016-10-03 23:22:36 +08:00
    其实就是个格式化 js 的工具
    gzzhanghao
        15
    gzzhanghao  
    OP
       2016-10-04 01:22:27 +08:00
    @aaronrzh 还是不太一样的,格式化的工作是交给 js-beautifier 完成的,这个只负责把代码逻辑还原出来
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3558 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:05 · PVG 19:05 · LAX 04:05 · JFK 07:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.