diff --git a/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/README.md b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/README.md new file mode 100644 index 0000000..98b7653 --- /dev/null +++ b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/README.md @@ -0,0 +1,312 @@ +# AST操作之API用法-path路径-path属性-path方法 + +## path 路径 + +在`@babel/traverse`模块中,path对象表示一个节点(node)在AST树中的位置,提供了一些属性和方法, +用于访问节点的属性、子节点、父节点、兄弟节点等,并且可以对AST树进行修改。 + +读取js代码并转换为ast树 + +```javascript +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); +``` + +## path 属性 + +`path`属性相关的源代码在这个js文件中 + +```javascript +\node_modules\@babel\traverse\lib\path +``` + +**下面是一些常见的path对象的属性API:** + +| api | 功能 | +|--------------------------------|--------------------------------------------------------------------| +| path.node | 获取当前路径对应的节点。 | +| path.parent | 获取当前路径对应节点的父节点。 | +| path.parentPath | 获取当前路径对应节点的父路径。 | +| path.scope | 表示当前path下的作用域,这个也是写插件经常会用到的。 | +| path.container | 用于获取当前path下的所有兄弟节点(包括自身)。 | +| path.type | 获取当前path的节点类型。 | +| path.key | 获取当前path的key值,key通常用于path.get函数。 | + +**1.打印当前路径所对应的某个节点信息** + +需求:打印type、start、end、loc、sourceType、interpreter、body等信息 + +![debugger](./img/1.png) + +编写代码 + +```javascript +const visitor = { + Program(path) { + console.log(path.node.type); + console.log(path.node.start); + console.log(path.node.end); + console.log(path.node.loc); + console.log(path.node.sourceType); + console.log(path.node.interpreter); + console.log(path.node.body); + console.log(path.node.directives); + }, +} +traverse(ast, visitor); +``` + +打印内容: + +```javascript +Program +0 +12 +SourceLocation +{ + start: Position + { + line: 1, column + : + 0, index + : + 0 + } +, + end: Position + { + line: 1, column + : + 12, index + : + 12 + } +, + filename: undefined, + identifierName +: + undefined +} +script +null + [ + Node +{ + type: 'VariableDeclaration', + start +: + 0, + end +: + 12, + loc +: + SourceLocation + { + start: [Position], + end + : + [Position], + filename + : + undefined, + identifierName + : + undefined + } +, + declarations: [[Node]], + kind +: + 'var' +} +] +[] +``` + +**2.判断path是什么type,使用path.isXXX 这个方法** + +需求:遍历所有节点,输出节点类型为NumericLiteral的value值 + +```javascript +const visitor = { + enter(path) { + if (path.isNumericLiteral()) { + console.log(path.type); + console.log(path.node.value); + } + + }, +} + +traverse(ast, visitor); +``` + +打印内容: + +```javascript +NumericLiteral +123 +``` + +**3.获取path的上一级路径path.parentPath;** + +需求:获取上一级路径节点类型 + +```javascript +const visitor = { + enter(path) { + if (path.isNumericLiteral()) { + console.log('当前节点类型:' + path.type); + console.log('上层节点类型:' + path.parentPath.type); + } + }, +} + +traverse(ast, visitor); +``` + +打印内容: + +```javascript +当前节点类型:NumericLiteral +上层节点类型:VariableDeclarator +``` + +**4.获取当前path的key值** + +需求:打印节点VariableDeclarator|BinaryExpression|Identifier的key值 + +```javascript +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; + +let js_code = "var a = 1 + 2;"; + +let ast = parse(js_code, { + sourceType: 'module', +}); + +const visitor = { + "VariableDeclarator|BinaryExpression|Identifier"(path) { + console.log(path.key) + }, +} + +traverse(ast, visitor); +``` + +![debugger](./img/2.png) + +## path 方法 + +`path`方法相关的源代码在这个js文件中 + +```javascript +node_modules\@babel\traverse\lib\path\index.js +\node_modules\@babel\traverse\lib\path +``` + +**下面是一些常见的path对象的方法API:** + +| api | 功能 | +|------------------------------------|--------------------------------------------------------------------| +| path.get(key) | 获取当前路径下指定属性名(key)对应的子路径。例如,path.get("body") 获取当前路径下名为 "body" 的子路径。 | +| path.getSibling(index) | 获取当前路径对应节点的兄弟节点的路径。通过指定索引(index)可以获取相应的兄弟路径。 | +| path.getFunctionParent() | 获取当前路径对应节点的最近的函数父节点的路径。 | +| path.getPrevSibling() | 获取当前path的前一个兄弟节点,返回的是path类型。 | +| path.getAllPrevSiblings() | 获取当前path的所有前兄弟节点,返回的是Array类型,其元素都是path类型。 | +| path.getNextSibling() | 获取当前path的后一个兄弟节点,返回的是path类型。 | +| path.getAllNextSiblings() | 获取当前path的所有后兄弟节点,返回的是Array类型,其元素都是path类型。 | +| path.evaluate() | 用于计算表达式的值,大家可以参考 constantFold 插件的写法。 | +| path.findParent() | 向上查找满足回调函数特征的path,即判断上级路径是否包含有XXX类型的节点。 | +| path.find() | 功能与 path.findParent 方法一样,只不过从当前path开始进行遍历。 | +| path.getFunctionParent() | 获取函数类型父节点,如果不存在,返回 null。 | +| path.getStatementParent() | 获取Statement类型父节点,这个基本上都会有返回值,如果当前遍历的是 Program 或者 File 节点,则会报错。 | +| path.getAncestry() | 获取所有的祖先节点,没有实参,返回的是一个Array对象。 | +| path.isAncestor(maybeDescendant) | 判断当前遍历的节点是否为实参的祖先节点. | +| path.isDescendant(maybeAncestor) | 判断当前遍历的节点是否为实参的子孙节点. | +| path.traverse(visitor) | 遍历当前路径下的所有子节点,并应用指定的 visitor。 | +| path.replaceWith(node) | 用指定的节点替换当前路径对应的节点。 | +| path.remove() | 从 AST 中移除当前路径对应的节点。 | +| path.insertBefore(nodes) | 在当前路径对应节点之前插入一个或多个节点。 | +| path.insertAfter(nodes) | 在当前路径对应节点之后插入一个或多个节点。 | +| path.insertAfter(nodes) | 在当前路径对应节点之后插入一个或多个节点。 | +| path.toString() | 用于将 AST 节点转换回对应的源代码字符串。 | + +**1.删除path,使用remove方法** + +需求:删除变量值 + +```javascript +const visitor = { + enter(path) { + if (path.isNumericLiteral()) { + path.remove() + } + }, +} + +traverse(ast, visitor); + +let {code} = generator(ast); +console.log(code) +``` + +打印内容: + +```javascript +var a; +``` + +**2.替换path,单路径可以使用`replaceWith`方法,多路径则使用`replaceWithMultiple`方法** + +需求:把var a = 123; 修改成var a = 3 ,用replaceWith方法 + +```javascript +const visitor = { + enter(path) { + if (path.isNumericLiteral() && path.node.value == 123) { + path.replaceWith({type: "NumericLiteral", value: 3}); + } + }, +} + +traverse(ast, visitor); +``` + +打印内容: + +```javascript +var a = 3; +``` + +注意点,必须加上`&& path.node.value == 123`判断,否则就是无限循环 + +**3.当前路径所对应的源代码** + +需求:打印当前路径所对应的源代码 + +```javascript +const visitor = { + VariableDeclaration(path) { + console.log(path.toString()); + }, +} + +traverse(ast, visitor); +``` + +打印内容: + +```javascript +var a = 123; +``` \ No newline at end of file diff --git a/AST抽象语法树/5.AST操作之API用法-path路径/encode.js b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/decode.js similarity index 100% rename from AST抽象语法树/5.AST操作之API用法-path路径/encode.js rename to AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/decode.js diff --git a/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/decode_obfuscator.js b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/decode_obfuscator.js new file mode 100644 index 0000000..facd2bb --- /dev/null +++ b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/decode_obfuscator.js @@ -0,0 +1,16 @@ +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; + +let js_code = "var a = 1 + 2;"; + +let ast = parse(js_code, { + sourceType: 'module', +}); + +const visitor = { + "VariableDeclarator|BinaryExpression|Identifier"(path) { + console.log(path.key) + }, +} + +traverse(ast, visitor); diff --git a/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/encode.js b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/encode.js new file mode 100644 index 0000000..fe33765 --- /dev/null +++ b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/encode.js @@ -0,0 +1 @@ +let jscode = "var a = 1 + 2;"; \ No newline at end of file diff --git a/AST抽象语法树/5.AST操作之API用法-path路径/img/1.png b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/img/1.png similarity index 100% rename from AST抽象语法树/5.AST操作之API用法-path路径/img/1.png rename to AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/img/1.png diff --git a/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/img/2.png b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/img/2.png new file mode 100644 index 0000000..efdd965 Binary files /dev/null and b/AST抽象语法树/5.AST操作之API用法-path路径-path属性-path方法/img/2.png differ diff --git a/AST抽象语法树/5.AST操作之API用法-path路径/README.md b/AST抽象语法树/5.AST操作之API用法-path路径/README.md deleted file mode 100644 index 0428db1..0000000 --- a/AST抽象语法树/5.AST操作之API用法-path路径/README.md +++ /dev/null @@ -1,268 +0,0 @@ -# AST操作之API用法-path路径 - -## path 路径 - -在`@babel/traverse`模块中,path对象表示一个节点(node)在AST树中的位置,提供了一些属性和方法, -用于访问节点的属性、子节点、父节点、兄弟节点等,并且可以对AST树进行修改。 - -**下面是一些常见的 path 对象的 API:** - -| api | 功能 | -|--------------------------|--------------------------------------------------------------------| -| path.node | 获取当前路径对应的节点。 | -| path.parent | 获取当前路径对应节点的父节点。 | -| path.parentPath | 获取当前路径对应节点的父路径。 | -| path.get(key) | 获取当前路径下指定属性名(key)对应的子路径。例如,path.get("body") 获取当前路径下名为 "body" 的子路径。 | -| path.getSibling(index) | 获取当前路径对应节点的兄弟节点的路径。通过指定索引(index)可以获取相应的兄弟路径。 | -| path.getFunctionParent() | 获取当前路径对应节点的最近的函数父节点的路径。 | -| path.traverse(visitor) | 遍历当前路径下的所有子节点,并应用指定的 visitor。 | -| path.replaceWith(node) | 用指定的节点替换当前路径对应的节点。 | -| path.remove() | 从 AST 中移除当前路径对应的节点。 | -| path.insertBefore(nodes) | 在当前路径对应节点之前插入一个或多个节点。 | -| path.insertAfter(nodes) | 在当前路径对应节点之后插入一个或多个节点。 | - -**当前路径所对应的源代码** - -需求:打印当前路径所对应的源代码 - -```javascript -const fs = require('fs'); -const {parse} = require("@babel/parser"); -const traverse = require("@babel/traverse").default; - -let encode_file = "./encode.js"; - -let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); -let ast = parse(js_code); - -const visitor = { - VariableDeclaration(path) - { - console.log(path.toString()); - }, -} - -traverse(ast, visitor); -``` - -打印内容: - -```javascript -var a = 123; -``` - -**打印当前路径所对应的某个节点信息** - -需求:打印type、start、end、loc、sourceType、interpreter、body等信息 - -![debugger](./img/1.png) - -编写代码 - -```javascript -const fs = require('fs'); -const {parse} = require("@babel/parser"); -const traverse = require("@babel/traverse").default; - -let encode_file = "./encode.js"; - -let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); -let ast = parse(js_code); - -const visitor = { - Program(path) - { - console.log(path.node.type); - console.log(path.node.start); - console.log(path.node.end); - console.log(path.node.loc); - console.log(path.node.sourceType); - console.log(path.node.interpreter); - console.log(path.node.body); - console.log(path.node.directives); - }, -} - -traverse(ast, visitor); -``` - -打印内容: - -```javascript -Program -0 -12 -SourceLocation { - start: Position { line: 1, column: 0, index: 0 }, - end: Position { line: 1, column: 12, index: 12 }, - filename: undefined, - identifierName: undefined -} -script -null -[ - Node { - type: 'VariableDeclaration', - start: 0, - end: 12, - loc: SourceLocation { - start: [Position], - end: [Position], - filename: undefined, - identifierName: undefined - }, - declarations: [ [Node] ], - kind: 'var' - } -] -[] -``` - -**判断path是什么type,使用path.isXXX 这个方法** - -需求:遍历所有节点,输出节点类型为NumericLiteral的value值 - -```javascript -const fs = require('fs'); -const {parse} = require("@babel/parser"); -const traverse = require("@babel/traverse").default; - -let encode_file = "./encode.js"; - -let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); -let ast = parse(js_code); - -const visitor = { - enter(path) - { - if(path.isNumericLiteral()) - { - console.log(path.type); - console.log(path.node.value); - } - - }, -} - -traverse(ast, visitor); -``` - -打印内容: - -```javascript -NumericLiteral -123 -``` - -**获取path的上一级路径path.parentPath;** - -需求:获取上一级路径节点类型 - -```javascript -const fs = require('fs'); -const {parse} = require("@babel/parser"); -const traverse = require("@babel/traverse").default; - -let encode_file = "./encode.js"; - -let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); -let ast = parse(js_code); - -const visitor = { - enter(path) - { - if(path.isNumericLiteral()) - { - console.log('当前节点类型:'+path.type); - console.log('上层节点类型:'+path.parentPath.type); - } - }, -} - -traverse(ast, visitor); -``` - -打印内容: - -```javascript -当前节点类型:NumericLiteral -上层节点类型:VariableDeclarator -``` - -**删除path,使用remove方法** - -需求:删除变量值 - -```javascript -const fs = require('fs'); -const {parse} = require("@babel/parser"); -const traverse = require("@babel/traverse").default; -const generator = require("@babel/generator").default; -let encode_file = "./encode.js"; - -let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); -let ast = parse(js_code); - -const visitor = { - enter(path) - { - if(path.isNumericLiteral()) - { - path.remove() - } - }, -} - -traverse(ast, visitor); - -// 写入文件 -let {code} = generator(ast); -console.log(code) -fs.writeFile('decode.js', code, (err) => {}); -``` -打印内容: - -```javascript -var a; -``` - -**替换path,单路径可以使用`replaceWith`方法,多路径则使用`replaceWithMultiple`方法** - -需求:把var a = 123; 修改成var a = 3 ,用replaceWith方法 - -```javascript -const fs = require('fs'); -const {parse} = require("@babel/parser"); -const traverse = require("@babel/traverse").default; -const generator = require("@babel/generator").default; -let encode_file = "./encode.js"; - -let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); -let ast = parse(js_code, { - sourceType: 'module', -}); - -const visitor = { - enter(path) { - if (path.isNumericLiteral() && path.node.value == 123) { - path.replaceWith({type: "NumericLiteral", value: 3}); - } - }, -} - -traverse(ast, visitor); - -// 写入文件 -let {code} = generator(ast); -console.log(code) -fs.writeFile('decode.js', code, (err) => { -}); -``` - -打印内容: - -```javascript -var a = 3; -``` - -注意点,必须加上`&& path.node.value == 123`判断,否则就是无限循环 \ No newline at end of file diff --git a/AST抽象语法树/5.AST操作之API用法-path路径/decode.js b/AST抽象语法树/5.AST操作之API用法-path路径/decode.js deleted file mode 100644 index d591410..0000000 --- a/AST抽象语法树/5.AST操作之API用法-path路径/decode.js +++ /dev/null @@ -1 +0,0 @@ -var a = 3; \ No newline at end of file diff --git a/AST抽象语法树/6.AST操作之API用法-node节点/README.md b/AST抽象语法树/6.AST操作之API用法-node节点/README.md new file mode 100644 index 0000000..5bd6b79 --- /dev/null +++ b/AST抽象语法树/6.AST操作之API用法-node节点/README.md @@ -0,0 +1,122 @@ +# AST操作之API用法-node节点 + +在抽象语法树(Abstract Syntax Tree,AST)中,`path.node` 是指表示当前节点的 AST 节点对象。它提供了关于该节点的信息,包括节点的类型和其他属性。 + +看语法就可以猜到`node`就是path的一个属性 + +| api | 功能 | +|:------------------------------------|--------------------------------------| +| path.node.type | 获取当前节点的类型。 | +| path.node.declarations | 对于 VariableDeclaration 节点, 获取变量声明列表。 | +| path.node.init.value | 获取某个节点的值。 | +| delete path.node.init; | 删除节点,使用系统的 delete 方法。 | + +**1.遍历打印出节点类型** + +```javascript +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { +sourceType: 'module', +}); + +const visitor = { + enter(path) { + console.log(path.node.type) + }, +} + +traverse(ast, visitor); +``` + +输出 +```javascript +Program +VariableDeclaration +VariableDeclarator +Identifier +NumericLiteral +var a = 123; +``` + +**2.遍历节点打印出 VariableDeclaration 节点的变量声明列表** + +```javascript +const visitor = { + enter(path) { + console.log(path.node.declarations) + }, +} +``` + +输出 + +```javascript +undefined +[ + Node { + type: 'VariableDeclarator', + start: 4, + end: 11, + loc: SourceLocation { + start: [Position], + end: [Position], + filename: undefined, + identifierName: undefined + }, + id: Node { + type: 'Identifier', + start: 4, + end: 5, + loc: [SourceLocation], + name: 'a' + }, + init: Node { + type: 'NumericLiteral', + start: 8, + end: 11, + loc: [SourceLocation], + extra: [Object], + value: 123 + } + } +] +undefined +undefined +undefined +var a = 123; +``` + +**3.获取某个节点的值** +```javascript +const visitor = { + VariableDeclarator(path) { + console.log(path.node.init.value) + }, +} +``` + +输出 +```javascript +123 +``` + +**4.删除某个节点的值** + +```javascript +const visitor = { + VariableDeclarator(path) { + delete path.node.init.value + }, +} +``` + +输出 +```javascript +var a = undefined; +``` \ No newline at end of file diff --git a/AST抽象语法树/6.AST操作之API用法-node节点/decode_obfuscator.js b/AST抽象语法树/6.AST操作之API用法-node节点/decode_obfuscator.js index 4089908..d57be4a 100644 --- a/AST抽象语法树/6.AST操作之API用法-node节点/decode_obfuscator.js +++ b/AST抽象语法树/6.AST操作之API用法-node节点/decode_obfuscator.js @@ -1,21 +1,24 @@ const fs = require('fs'); -const { parse } = require('@babel/parser'); -const traverse = require('@babel/traverse').default; -const generator = require('@babel/generator').default; -let encode_file = './encode.js'; +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +let encode_file = "./encode.js"; -let js_code = fs.readFileSync(encode_file, { encoding: 'utf-8' }); +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); let ast = parse(js_code, { sourceType: 'module', }); -traverse(ast, { - NumericLiteral(path) { - path.replaceWith( - parse(3).program.body[0].expression - ); +const visitor = { + VariableDeclarator(path) { + delete path.node.init.value }, -}); +} -const output = generator(ast).code; -console.log(output); +traverse(ast, visitor); + +// 写入文件 +let {code} = generator(ast); +console.log(code) +fs.writeFile('decode.js', code, (err) => { +}); diff --git a/AST抽象语法树/7.AST操作之API用法-path.scope属性和方法/README.md b/AST抽象语法树/7.AST操作之API用法-path.scope属性和方法/README.md new file mode 100644 index 0000000..0f12909 --- /dev/null +++ b/AST抽象语法树/7.AST操作之API用法-path.scope属性和方法/README.md @@ -0,0 +1,39 @@ +# AST操作之API用法-path.scope属性和方法 + +**scope相关的源代码在这个js文件中** + +```javascript +node_modules\@babel\traverse\lib\scope\index.js +``` +| api | 说明 | +|:--------------------------------------|-------------------------------------------------------------------------------| +| scope.block | 表示当前作用域下的所有node,参考上面的 this.block = node; | +| scope.dump() | 输出当前每个变量的作用域信息。调用后直接打印,不需要加打印函数 | +| scope.crawl() | 重构scope,在某种情况下会报错,不过还是建议在每一个插件的最后一行加上。 | +| scope.rename(oldName, newName, block) | 修改当前作用域下的的指定的变量名,oldname、newname表示替换前后的变量名,为字符串。注意,oldName需要有binding,否则无法重命名。 | +| scope.traverse(node, opts, state) | 遍历当前作用域下的某些(个)插件。和全局的traverse用法一样。 | +| scope.getBinding(name) | 获取某个变量的binding,可以理解为其生命周期。包含引用,修改之类的信息 | + +**binding常用方法及属性总结** + +```javascript +node_modules\@babel\traverse\lib\scope\binding.js +``` + +目前我看到的只有 变量定义 和 函数定义 拥有binding,其他的获取binding都是undefined。 + +```javascript +let binding = scope.getBinding(name); +``` + +例如: + +var a = 123; 这里的 a 就拥有 binding。 而 function test(a,b,c) {}; 函数名test以及形参a,b,c均拥有 binding。 + +| api | 说明 | +|:---------------------------|------------------------------------------------------------------| +| binding.path | 用于定位初始拥有binding的path; | +| binding.constant | 用于判断当前变量是否被更改,true表示未改变,false表示有更改变量值。 | +| binding.referenced | 用于判断当前变量是否被引用,true表示代码下面有引用该变量的地方,false表示没有地方引用该变量。注意,引用和改变是分开的。 | +| binding.referencePaths | 它是一个Array类型,包含所有引用的path,多用于替换。 | +| binding.constantViolations | 它是一个Array类型,包含所有改变的path,多用于判断。 | \ No newline at end of file diff --git a/AST抽象语法树/8.AST操作之获得当前节点的源代码/RADME.md b/AST抽象语法树/8.AST操作之获得当前节点的源代码/RADME.md new file mode 100644 index 0000000..772cc48 --- /dev/null +++ b/AST抽象语法树/8.AST操作之获得当前节点的源代码/RADME.md @@ -0,0 +1,33 @@ +# AST操作之获得当前节点的源代码 + +path: path.toString() + +node: generator(node).code; + +```javascript +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + +const visitor = { + VariableDeclarator(path) { + console.log(path.toString()) + let {code} = generator(path.node); + console.log(code) + }, +} + +traverse(ast, visitor); +``` + +输出: + + a = 123 + a = 123 diff --git a/AST抽象语法树/5.AST操作之API用法-path路径/decode_obfuscator.js b/AST抽象语法树/8.AST操作之获得当前节点的源代码/decode_obfuscator.js similarity index 58% rename from AST抽象语法树/5.AST操作之API用法-path路径/decode_obfuscator.js rename to AST抽象语法树/8.AST操作之获得当前节点的源代码/decode_obfuscator.js index f9f890e..1c5cd11 100644 --- a/AST抽象语法树/5.AST操作之API用法-path路径/decode_obfuscator.js +++ b/AST抽象语法树/8.AST操作之获得当前节点的源代码/decode_obfuscator.js @@ -10,17 +10,12 @@ let ast = parse(js_code, { }); const visitor = { - enter(path) { - if (path.isNumericLiteral() && path.node.value == 123) { - path.replaceWith({type: "NumericLiteral", value: 3}); - } + VariableDeclarator(path) { + console.log(path.toString()) + let {code} = generator(path.node); + console.log(code) }, } traverse(ast, visitor); -// 写入文件 -let {code} = generator(ast); -console.log(code) -fs.writeFile('decode.js', code, (err) => { -}); diff --git a/AST抽象语法树/8.AST操作之获得当前节点的源代码/encode.js b/AST抽象语法树/8.AST操作之获得当前节点的源代码/encode.js new file mode 100644 index 0000000..9d69cb3 --- /dev/null +++ b/AST抽象语法树/8.AST操作之获得当前节点的源代码/encode.js @@ -0,0 +1 @@ +var a = 123; \ No newline at end of file diff --git a/AST抽象语法树/9.AST操作之构造节点信息/README.md b/AST抽象语法树/9.AST操作之构造节点信息/README.md new file mode 100644 index 0000000..476d7be --- /dev/null +++ b/AST抽象语法树/9.AST操作之构造节点信息/README.md @@ -0,0 +1,46 @@ +# AST操作之构造节点信息 + +需求:将var a;将其转化为var a = 1 + 2; + +```javascript +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + +const visitor = { + VariableDeclarator(path) { + // 使用解构赋值语法 {} 是用来从对象中提取特定属性或方法 + const {init} = path.node + console.log({init}) + const node = { + type: "BinaryExpression", + operator: "+", + left: { + type: "NumericLiteral", + value: 1 + }, + right: { + type: "NumericLiteral", + value: 2 + } + } + // 在 JavaScript 中,|| 是逻辑运算符之一,表示逻辑或(OR) + init || path.set("init", node) + }, +} + +traverse(ast, visitor); +let {code} = generator(ast); +console.log(code) +``` +打印数据: + + { init: null } + var a = 1 + 2; diff --git a/AST抽象语法树/9.AST操作之构造节点信息/decode_obfuscator.js b/AST抽象语法树/9.AST操作之构造节点信息/decode_obfuscator.js new file mode 100644 index 0000000..e283d34 --- /dev/null +++ b/AST抽象语法树/9.AST操作之构造节点信息/decode_obfuscator.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const {parse} = require("@babel/parser"); +const traverse = require("@babel/traverse").default; +const generator = require("@babel/generator").default; +let encode_file = "./encode.js"; + +let js_code = fs.readFileSync(encode_file, {encoding: "utf-8"}); +let ast = parse(js_code, { + sourceType: 'module', +}); + +const visitor = { + VariableDeclarator(path) { + // 使用解构赋值语法 {} 是用来从对象中提取特定属性或方法 + const {init} = path.node + console.log({init}) + const node = { + type: "BinaryExpression", + operator: "+", + left: { + type: "NumericLiteral", + value: 1 + }, + right: { + type: "NumericLiteral", + value: 2 + } + } + + init || path.set("init", node) + }, +} + +traverse(ast, visitor); +let {code} = generator(ast); +console.log(code) \ No newline at end of file diff --git a/AST抽象语法树/9.AST操作之构造节点信息/encode.js b/AST抽象语法树/9.AST操作之构造节点信息/encode.js new file mode 100644 index 0000000..3e62046 --- /dev/null +++ b/AST抽象语法树/9.AST操作之构造节点信息/encode.js @@ -0,0 +1 @@ +var a; \ No newline at end of file diff --git a/AST抽象语法树/README.md b/AST抽象语法树/README.md index b995ad6..1462bfd 100644 --- a/AST抽象语法树/README.md +++ b/AST抽象语法树/README.md @@ -4,3 +4,7 @@ https://blog.csdn.net/weixin_52057903/article/details/129131582 +babel文档 + +https://babeljs.io/docs/babel-types + diff --git a/抖音js逆向学习/抖店精选联盟数据/sql/baiyin/eb_supports_baiyin.sql b/抖音js逆向学习/抖店精选联盟数据/sql/baiyin/eb_supports_baiyin.sql index fc86503..9d2e4ce 100644 --- a/抖音js逆向学习/抖店精选联盟数据/sql/baiyin/eb_supports_baiyin.sql +++ b/抖音js逆向学习/抖店精选联盟数据/sql/baiyin/eb_supports_baiyin.sql @@ -194,7 +194,7 @@ CREATE TABLE `clean_buyin_authorStatData_authorProfile` ( `act_info` varchar(255) DEFAULT '', `deduplication` varchar(100) DEFAULT '' COMMENT '去重字段', `spider_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '爬虫抓取时间', - UNIQUE KEY `task_id` (`deduplication`) USING BTREE, + UNIQUE KEY `account_douyin` (`account_douyin`) USING BTREE, KEY `uid` (`uid`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; @@ -230,8 +230,7 @@ CREATE TABLE `clean_buyin_authorStatData_seekAuthor` ( `author_tag_is_star` smallint(1) DEFAULT '0' COMMENT '是否明星', `deduplication` varchar(100) DEFAULT '' COMMENT '去重字段', `spider_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '爬虫抓取时间', - UNIQUE KEY `task_id` (`deduplication`) USING BTREE, - KEY `author_base_uid` (`author_base_uid`) USING BTREE + UNIQUE KEY `deduplication` (`deduplication`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; @@ -283,4 +282,4 @@ CREATE TABLE `project_buyin_authorStatData` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-07-13 12:09:55 +-- Dump completed on 2023-07-18 16:58:29