反爬大神总结了一份AST语法详解

首先我们得知道为什么要了解AST

大家都知道反爬虫中JS是最难的,要想破解JS逆向,就必须要掌握AST语法,目前常用的一些前端插件或者工具 比如:javascript转译,代码压缩,css预处理器,elint,pretiier等功能的实现都是简历在AST的基础之上。

javascript 的编译执行流程

js执行的第一步是读取js 文件中的字符流,然后通过词法分析生成token,之后再通过语法分析生成 AST(Abstract Syntax Tree),最后生成机器码执行。

语法分析

语法分析同时也称之为扫描(scanner),简单的来说就是调用next()方法,一个一个字母的来读取字符,然后和定义好的的Javascript关键字符做比较生成对应的Token。不可分割的最小单元,例如 var 这三个字符,它只能作为一个整体,语义上不能再被分解,因此它是一个 Token。词法分析器里,每个关键字是一个Token ,每个标识符是一个Token,每个操作符是一个 Token,每个标点符号也都是一个 Token。除此之外,还会过滤掉源程序中的注释和空白字符(换行符、空格、制表符等)。
最终,整个代码将被分割进一个tokens列表(或者说一维数组)。

n * n;

[
  {
    type: {
    ... }, value: "n",  loc: {
    ... } },
  {
    type: {
    ... }, value: "*",  loc: {
    ... } },
  {
    type: {
    ... }, value: "n",  loc: {
    ... } },
  ...
]

每一个type 有一组属性来描述该令牌:

{
   
  type: {
   
    label: 'name',
    keyword: undefined,
    beforeExpr: false,
    startsExpr: true,
    rightAssociative: false,
    isLoop: false,
    isAssign: false,
    prefix: false,
    postfix: false,
    binop: null,
    updateContext: null
  },
  ...
}

语法分析

语法分析会将词法分析出来的 Token 转化成有语法含义的抽象语法树结构。同时,验证语法,语法如果有错的话,抛出语法错误。

什么是AST(抽象语法树)

抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

function square(n) {
   
  return n * n;
}

上面这个代码就可以形成一棵树:

FunctionDeclaration:
   id:
     Identifier:
       name: square
   params [1]
     Identifier
       name: n
   body:
     BlockStatement
       body [1]
         ReturnStatement
           argument
             BinaryExpression
               operator: *
               left
                 Identifier
                   name: n
               right
                 Identifier
                   name: n

或是如下所示的 JavaScript Object(对象):

{
   
  type: "FunctionDeclaration",
  id: {
   
    type: "Identifier",
    name: "square"
  },
  params: [{
   
    type: "Identifier",
    name: "n"
  }],
  body: {
   
    type: "BlockStatement",
    body: [{
   
      type: "ReturnStatement",
      argument: {
   
        type: "BinaryExpression",
        operator: "*",
        left: {
   
          type: "Identifier",
          name: "n"
        },
        right: {
   
          type: "Identifier",
          name: "n"
        }
      }
    }]
  }
}

你会留意到 AST 的每一层都拥有相同的结构:

{
   
  type: "FunctionDeclaration",
  id: {
   ...},
  params: [...],
  body: {
   ...}
}
{
   
  type: "Identifier",
  name: ...
}
{
   
  type: "BinaryExpression",
  operator: ...,
  left: {
   ...},
  right: {
   ...}
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值