李恒道 发表于 2022-6-10 23:24:19

[油猴脚本开发指南]油猴的本质以及document的处理(二)

# 开篇
我们继续看N、M、I函数
# N函数
我们先看一下代码
```javascript
e=>{
    e.__evaluate || (U(e, he({
      __evaluate: he({
            value: e.evaluate,
            enumerable: !1,
            configurable: !1
      })
    })),
    e.evaluate = function(e, t, o, r, s) {
      let a;
      if (n && k("env: document.evaluate " + e),
      t || (t = this),
      "undefined" != typeof XPathResult) {
            let i = e
            , c = null;
            try {
                a = this.__evaluate(i, t, o, r, s)
            } catch (e) {
                c = e
            }
            let l, d = !1;
            try {
                d = d || !!a.snapshotLength
            } catch (e) {}
            try {
                d = d || !!a.singleNodeValue
            } catch (e) {}
            if (d || "." == (l = W(e, 0, 1)) || h(t))
                n && k("env: queried document for " + i);
            else {
                n && k("env: query added elem for " + i),
                i = ("/" == l ? "." : "./") + e;
                try {
                  a = this.__evaluate(i, t, o, r, s)
                } catch (e) {}
            }
            if (n && k("env: query returned ", a, c),
            !d && c)
                throw c
      } else
            n && k("env: XPathResult == undefined, but selectNodes via ", e),
            a = t.selectNodes(e);
      return a
    }
    ,
    Ue.push(()=>{
      e.evaluate = e.__evaluate
    }
    ))
}
```
一行一行读
```
e.__evaluate || (U(e, he({
    __evaluate: he({
      value: e.evaluate,
      enumerable: !1,
      configurable: !1
    })
}))
```
首先判断是否存在__evaluate
如果不存在则执行后面的代码
首先定义一个对象
```
{
    __evaluate: he({
      value: e.evaluate,
      enumerable: !1,
      configurable: !1
    })
}
```
我们往he传入了一个对象
我们看一下he是什么
```
e=>s({
      __proto__: null
    }, e)
```
s函数是一个assign函数

![图片.png](data/attachment/forum/202206/10/231615jc9qsqicxwdddcqc.png)
可以看出he是将属性合并到一个空对象上
```
he({
    __evaluate: he({
      value: e.evaluate,
      enumerable: !1,
      configurable: !1
    })
})
```
将我们刚才合成的对象放到了__evaluate对象上
然后调用U函数
![图片.png](data/attachment/forum/202206/10/231831hktjx96ka4jaxjkk.png)
U函数是一个defineProperties函数
可以知道我们做了往document定义了一个__evaluate属性
其实际值是evaluate
然后对document.evaluate进行了赋值
并在其内部调用了a = this.__evaluate(i, t, o, r, s)
也就是我们之前赋值的属性
这里可以看到了做了一定的处理
具体我们就不提了
      Ue.push(()=>{
            e.evaluate = e.__evaluate
      }
然后调用了Ue函数
我们看看Ue函数

![图片.png](data/attachment/forum/202206/10/232223ky5dxsp9smyo2yyk.png)
我们看一下Ue的push函数
![图片.png](data/attachment/forum/202206/10/232243basa6vyfv67ahpav.png)
大致可以看到生成一个id然后往objs上进行赋值,并设置上属性等
# N函数总结
我们对evlaute进行了定义以及劫持处理
# 结语
太长了
他妈的再撒一次花
页: [1]
查看完整版本: [油猴脚本开发指南]油猴的本质以及document的处理(二)