新手必看|babel库插件编写方式答疑

举报
悦来客栈的老板 发表于 2022/05/14 00:15:21 2022/05/14
【摘要】 关注它,不迷路。 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除! 问:拿到一个混淆的js,通过怎样的方式对它进行还原? 答: 通过编写还原脚本,读取这个混淆的js文件内容,解析成语法树,再对这棵树进行修剪,修剪过后的语法树,再将其保存为js源代码,生成新的js文件...

关注它,不迷路。

  • 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!

问:拿到一个混淆的js,通过怎样的方式对它进行还原?

答:

  1. 通过编写还原脚本,读取这个混淆的js文件内容,解析成语法树,再对这棵树进行修剪,修剪过后的语法树,再将其保存为js源代码,生成新的js文件输出即可。因此这种方式你需要 一个js混淆源文件和一个对这个文件进行处理的ast解析文件。具体的可以参考这篇文章: 利用AST解混淆先导知识:调用babel库反混淆代码模板

  2. 可以将v神打包的babel库倒入html文件中,然后读取混淆的js文件内容,这样的好处是在还原是可以避免补浏览器相关的环境。这种方式我用的少,推荐第一种方式。

问:怎么调用还原插件?

答:核心主要是 traverse 函数,它的函数定义:


   
  1. function traverse(parent, opts, scope, state, parentPath{
  2. if (!parent) return;
  3.   if (!opts) opts = {};
  4. if (!opts.noScope && !scope) {
  5. if (parent.type !== "Program" && parent.type !== "File") {
  6. throw new Error("You must pass a scope and parentPath unless traversing a Program/File. " + `Instead of that you tried to traverse a ${parent.type} node without ` + "passing scope and parentPath.");
  7. }
  8.   }
  9. visitors.explode(opts);
  10. traverse.node(parent, opts, scope, state, parentPath);
  11. }

这里第一个参数是parent,我们这里传入node即可:


   
  1. let sourceCode = fs.readFileSync(encodeFile, {encoding: "utf-8"});
  2. let ast = parser.parse(sourceCode);

这里的 ast 就是传入的parent,它是个变量名,可以随意,一般我们用它来表示整棵树,用以区分。

第二个参数 opts,它是一个object,看源代码确实看不出怎么传参(也许是我看的不深入),不过有大佬告诉我们怎么传:

traverse(ast, {ExpressionStatement: RemoveComma,});
  

第一个参数是ast,对应的是上面的parent,而opt是一个object,

{ExpressionStatement: RemoveComma,}
  

ExpressionStatement 表示当前遍历的是  Expression表达式,这个需要对照解析网站观看,而 RemoveComma ,我认为它是一个回调函数,它有个一个形参path,path包含了各个方法和属性:


   
  1. function RemoveComma(path) {
  2. // a = 1, b = ddd(), c = null;
  3. // |
  4. // |
  5. // |
  6. // v
  7. // a = 1;
  8. // b = ddd();
  9. // c = null;
  10. let {expression} = path.node
  11. if (!t.isSequenceExpression(expression))
  12. return;
  13. let body = []
  14. expression.expressions.forEach(
  15. express => {
  16. body.push(t.expressionStatement(express))
  17. }
  18. )
  19. path.replaceInline(body)
  20. }

而这种写法不利于大家去直接用,因此我在星球里直接改写成了另外一种写法,效果是一样的,没有差别:


   
  1. const RemoveComma =
  2. {
  3. ExpressionStatement (path)
  4. {
  5. let {expression} = path.node
  6. if (!t.isSequenceExpression(expression))
  7. return;
  8. let body = []
  9. expression.expressions.forEach(
  10. express => {
  11. body.push(t.expressionStatement(express))
  12. }
  13. )
  14. path.replaceInline(body);
  15. },
  16. }

然后再调用这个插件:

traverse(ast, RemoveComma);
  

问:怎么编写还原插件?

答:我会专门写一篇文章来告诉大家怎么编写还原插件。

交流学习

加我好友,拉进群,欢迎讨论AST相关的话题

f4ad28b9a3591e581c6cc335fe8d5a1a.png

文章来源: blog.csdn.net,作者:悦来客栈的老板,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq523176585/article/details/124743784

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。