From 6f6b2680a328988b3fda762d22be461d84e46a14 Mon Sep 17 00:00:00 2001 From: aiyingfeng Date: Tue, 22 Aug 2023 16:06:44 +0800 Subject: [PATCH] =?UTF-8?q?13.AST=E9=81=8D=E5=8E=86=E6=96=B9=E5=BC=8Fenter?= =?UTF-8?q?=E5=92=8Cexit=E7=9A=84=E5=8C=BA=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../13.AST遍历方式enter和exit的区别/README.md | 92 +++++++++++++++++++ .../decode_obfuscator.js | 28 ++++++ .../decode_obfuscator1.js | 26 ++++++ .../13.AST遍历方式enter和exit的区别/encode.js | 1 + 4 files changed, 147 insertions(+) create mode 100644 AST抽象语法树/13.AST遍历方式enter和exit的区别/README.md create mode 100644 AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator.js create mode 100644 AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator1.js create mode 100644 AST抽象语法树/13.AST遍历方式enter和exit的区别/encode.js diff --git a/AST抽象语法树/13.AST遍历方式enter和exit的区别/README.md b/AST抽象语法树/13.AST遍历方式enter和exit的区别/README.md new file mode 100644 index 0000000..d2a9238 --- /dev/null +++ b/AST抽象语法树/13.AST遍历方式enter和exit的区别/README.md @@ -0,0 +1,92 @@ +# AST遍历方式enter和exit的区别 + +测试代码 + +```javascript +var a = 'a' + 'b' + 'c' + d + 'e' + 'f'; +``` + +**默认的遍历方式enter** + +从代码结构的角度看,enter 钩子通常与深度优先遍历的进入节点的过程相对应,符合从上到下、从外到内的思维逻辑。 + +```javascript +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +const t = require('@babel/types'); +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + + +const visitor = { + BinaryExpression(path){ + console.log(path.toString()) + const {confident, value} = path.evaluate(); + confident && path.replaceWith(t.valueToNode(value)); + }, +} + +traverse(ast, visitor); + +// 将修改后的AST重新生成为代码 +const modifiedCode = generator(ast).code; +console.log(modifiedCode); +``` + +打印内容: + + 'a' + 'b' + 'c' + d + 'e' + 'f' + 'a' + 'b' + 'c' + d + 'e' + 'a' + 'b' + 'c' + d + 'a' + 'b' + 'c' + var a = "abc" + d + 'e' + 'f'; + +**exit遍历方式** + +从代码结构的角度看,exit 钩子通常与深度优先遍历的离开节点的过程相对应,符合从下到上、从内到外的思维逻辑。 + +```javascript +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +const t = require('@babel/types'); +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + + +const visitor = { + BinaryExpression: { + exit: function(path) { + console.log(path.toString()) + const {confident, value} = path.evaluate(); + confident && path.replaceWith(t.valueToNode(value)); + } + }, +} + +traverse(ast, visitor); + +// 将修改后的AST重新生成为代码 +const modifiedCode = generator(ast).code; +console.log(modifiedCode); +``` + +打印内容: + + 'a' + 'b' + "ab" + 'c' + "abc" + d + "abc" + d + 'e' + "abc" + d + 'e' + 'f' + var a = "abc" + d + 'e' + 'f'; diff --git a/AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator.js b/AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator.js new file mode 100644 index 0000000..4837e2f --- /dev/null +++ b/AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator.js @@ -0,0 +1,28 @@ +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +const t = require('@babel/types'); +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + + +const visitor = { + BinaryExpression: { + exit: function(path) { + console.log(path.toString()) + const {confident, value} = path.evaluate(); + confident && path.replaceWith(t.valueToNode(value)); + } + }, +} + +traverse(ast, visitor); + +// 将修改后的AST重新生成为代码 +const modifiedCode = generator(ast).code; +console.log(modifiedCode); \ No newline at end of file diff --git a/AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator1.js b/AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator1.js new file mode 100644 index 0000000..7b1e147 --- /dev/null +++ b/AST抽象语法树/13.AST遍历方式enter和exit的区别/decode_obfuscator1.js @@ -0,0 +1,26 @@ +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +const t = require('@babel/types'); +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + + +const visitor = { + BinaryExpression(path){ + console.log(path.toString()) + const {confident, value} = path.evaluate(); + confident && path.replaceWith(t.valueToNode(value)); + }, +} + +traverse(ast, visitor); + +// 将修改后的AST重新生成为代码 +const modifiedCode = generator(ast).code; +console.log(modifiedCode); \ No newline at end of file diff --git a/AST抽象语法树/13.AST遍历方式enter和exit的区别/encode.js b/AST抽象语法树/13.AST遍历方式enter和exit的区别/encode.js new file mode 100644 index 0000000..b86c49a --- /dev/null +++ b/AST抽象语法树/13.AST遍历方式enter和exit的区别/encode.js @@ -0,0 +1 @@ +var a = 'a' + 'b' + 'c' + d + 'e' + 'f'; \ No newline at end of file