在 JS逆向时如何 hook 属性?
大家好,昨天讲过了如何 hook JS 中的方法,今天来讲讲如何 hook JS 中的属性。
cookie
在 JS 逆向时,比较常用的属性我第一想到的就是 cookie 了,cookie 有读取和写入两个动作,部分反爬方案就是在访问的时候先返回一个加密后的 JS,JS 会计算一个 cookie 然后重定向到首页,并且带上刚才计算出来的 cookie。如果 cookie 有效则正常显示页面,否则提示失败。下面就以 cookie 来举例,讲一下如何 hook cookie。
hook 属性
在 hook cookie 之前,先来讲一下在 JS 中如何 hook 属性。hook 属性和 hook 方法有点不一样,方法可以被重写,但是属性不行。要 hook 属性,就离不开一个方法,它就是:Object.defineProperty
。
这里只展示部分使用方式,更多内容请大家查看官方文档。
hook 属性原理
hook 属性的原理其实就是重新定义属性,使用 Object.defineProperty
可以到达这个目的。
对象中存在的属性描述符有两种主要类型:数据描述符和访问器描述符。数据描述符是一个具有可写或不可写值的属性。访问器描述符是由 getter/setter
函数对描述的属性。描述符只能是这两种类型之一,不能同时为两者。在 hook 中,访问器描述符用的比较多,因为一般 hook 都是针对设置或者访问操作进行 hook。
看文档有点枯燥,来看一个案例:
1 | const o = {}; // 创建一个新对象 |
定义一个 o
对象,然后使用 Object.defineProperty
方法重新定义 o
对象的 b
属性,并且配置访问器属性描述符,在对应的位置打印日志。可以看到在首次访问的时候,value
的值为 undefined
,设置值后可以正常获取到 b
属性的值,并且在获取和设置的时候也可以正常打印日志。
数据描述符在 hook 中用的比较少,我这里就不多解释了,大家可以自行查看文档。
hook cookie
原理讲完了,现在使用刚才学到的知识来 hook 一下 cookie 试试。
在 hook cookie 之前,要先知道 cookie 是如何使用的,查一下 MDN 的文档:
尝试设置 cookie:
可以正常的打印出 cookie,说明访问和获取 cookie 的用法是没错的。
下面来尝试 hook cookie 的读取和设置操作,使用以下代码:
1 | let _cookie = document.cookie; |
先保存之前的 cookie 值,然后在设置 cookie 的时候覆盖原有的值,并且在获取 cookie 值的时候返回 cookie 即可。
为什么这里设置了两个 cookie,但是只获取到了一个呢?上面也说过了,cookie 是一个变量,第二次设置的 cookie 覆盖了第一次的值,所以只获取到了一个。
使用一个变量值来模拟 cookie 的设置和获取,实际的 cookie 设置和获取是比较复杂的,使用单个的变量无法完全模拟 cookie 的行为,但是加上 debugger
语句用来查找 cookie 的设置和获取动作的调用位置已经足够了。
打印堆栈
如果不想使用 debugger
语句,则可以使用 new Error().stack
来获取调用堆栈,一样可以知道各个方法的调用关系。
这样就可以在不打断点的情况下,获取到 cookie 的调用位置了。
总结
以上内容使用 cookie 作为示例演示了 hook 对象属性的方法,对于其他对象的其他属性,都可以使用这种方法来实现 hook,具体如何操作就留给大家去实战了。
注:以上内容根据我当前所了解的知识整理而成,如有疏漏或错误请大家指出,谢谢大家。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!