hook 对象属性

一.     我们首先要明白我们为什么要hook 对象的属性

就是在我们js逆向的过程中需要补环境 (补环境的过程中我们想要知道脚本中对,对象中对哪个属性进行了操作,从而我们就能知道应该要补哪个属性)

二. 下面我们简单讲解一下原理,(让小白能更好的理解)不做难的操作

需要小白先去对js对象有一定的学习

首先我们要从对象属性的描述符入手(每一个对象的属性他都会有一个描述符,这个描述符其实也是一个对象)(知道的朋友直接看下面实现原理

1.属性的类型
[[Configurable]] :表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特
性,以及是否可以把它改为访问器属性。默认情况下,所有直接定义在对象上的属性的这个特
性都是 true ,如前面的例子所示。
[[Enumerable]] :表示属性是否可以通过 for-in 循环返回。默认情况下,所有直接定义在对
象上的属性的这个特性都是 true ,如前面的例子所示。
[[Writable]] :表示属性的值是否可以被修改。默认情况下,所有直接定义在对象上的属性的
这个特性都是 true ,如前面的例子所示。
[[Value]] :包含属性实际的值。这就是前面提到的那个读取和写入属性值的位置。这个特性
的默认值为 undefined
在像前面例子中那样将属性显式添加到对象之后, [[Configurable]] [[Enumerable]]
[[Writable]] 都会被设置为 true ,而 [[Value]] 特性会被设置为指定的值
2. 访问器属性
访问器属性不包含数据值。相反,它们包含一个获取( getter )函数和一个设置( setter )函数,不
过这两个函数不是必需的。在读取访问器属性时,会调用获取函数,这个函数的责任就是返回一个有效
的值。在写入访问器属性时,会调用设置函数并传入新值,这个函数必须决定对数据做出什么修改。访
问器属性有 4 个特性描述它们的行为。
[[Configurable]] :表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特
性,以及是否可以把它改为数据属性。默认情况下,所有直接定义在对象上的属性的这个特性
都是 true
[[Enumerable]] :表示属性是否可以通过 for-in 循环返回。默认情况下,所有直接定义在对
象上的属性的这个特性都是 true
[[Get]] :获取函数,在读取属性时调用。默认值为 undefined
[[Set]] :设置函数,在写入属性时调用。默认值为 undefined

2. 给对象设置属性描述符的方法访问器属性是不能直接定义的,必须使用 Object.defineProperty()

这个方法需要传入三个参数 

参数1 传入一个对象(要给哪一个对象设置)

参数2  属性名称  (要给对象中哪个属性设置)

参数3  传入一个对象 (这个对象里面是属性描述符)

下面是一个例子

let book = { 
 year_: 2017, 
 edition: 1 
}; 
Object.defineProperty(book, "year", { 
 get() { 
 return this.year_; 
 }, 
 set(newValue) { 
 if (newValue > 2017) { 
 this.year_ = newValue; 
 this.edition += newValue - 2017; 
 } 
 } 
}); 
book.year = 2018; 
console.log(book.edition);
在这个例子中,对象 book 有两个默认属性: year_ edition year_ 中的下划线常用来表示该
属性并不希望在对象方法的外部被访问。另一个属性 year 被定义为一个访问器属性,其中获取函数简
单地返回 year_ 的值,而设置函数会做一些计算以决定正确的版本( edition )。因此,把 year 属性修改
2018 会导致 year_ 变成 2018 edition 变成 2 。这是访问器属性的典型使用场景,即设置一个属性
值会导致一些其他变化发生。
获取函数和设置函数不一定都要定义。只定义获取函数意味着属性是只读的,尝试修改属性会被忽
略。在严格模式下,尝试写入只定义了获取函数的属性会抛出错误。类似地,只有一个设置函数的属性
是不能读取的,非严格模式下读取会返回 undefined ,严格模式下会抛出错误。
在不支持 Object.defineProperty() 的浏览器中没有办法修改 [[Configurable]] [[Enumerable]]

二.  实现原理

对一个对象的一个属性的hook 的简单原理 

//假如我们有一个person对象里面有一个name属性 当然我们目前只hook一个属性,后面会讲解一个对象多个属性的hook
person={
    name:"张三"
}
//hook 时机要在对象加载完之后
//我们要hook person name 属性 先要拿一个变量存起来
my_name=person.name
Object.defineProperty(person,"name",{
    get:function (){
        //这个方法实在对象获取属性时触发
        console.log("person对象name 属性被获取",my_name)
       return my_name
    },
    set:function (val){
        //这个属性在设置值的时候触发
        console.log("perosn 对象name属性被 设置",val)
        my_name=val


    }
})


console.log(person.name)//在属性被调用之前hook
person.name="李斯"
console.log(person.name)

person对象name 属性被获取 张三
张三
perosn 对象name属性被 设置 李斯
person对象name 属性被获取 李斯
李斯

 

  • 32
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值