> 文章列表 > 【js逆向】hook大全

【js逆向】hook大全

【js逆向】hook大全

▒ 目录 ▒

    • 🛫 导读
      • 需求
    • 1️⃣ 普通函数
    • 2️⃣ 对象方法(Class.prototype)
    • 3️⃣ 对象属性(Object.defineProperty)
    • 4️⃣ Proxy
    • 5️⃣ 批量hook示例
    • 🛬 文章小结
    • 📖 参考资料

🛫 导读

需求

除了通过chrome devtool提供的各种方案分析js以外,其实js本身就是一个编程语言,我们可以根据编程语言的逻辑,进行各种hook来方便分析代码和逻辑(可以想象成C++、java等hook)。
今天就通过js语法特性,对js的hook进行分类实践。

ps小肩膀的课程,关于js逆向是很全面的了,大家可以在bilibili上看视频教程,也可以看其书籍《反爬虫AST原理与还原混淆实战》进行系统学习。

ps2:不少库都是用了hook的概念,比较有名的网络请求库ajax、axios,其自身提供hook基址,是不错的参考。除此之外,vue等大型的框架也大量使用的了hook。

1️⃣ 普通函数

js作为动态一种弱语言,直接将函数赋值即可覆盖原有逻辑,也是最简单的hook。示例如下:

window.alertMy = window.alert
window.alert = function(s) {console.log('Alert: ' + s);if (false) { // 自定义判断条件window.alertMy(s)}
}

2️⃣ 对象方法(Class.prototype)

对象的静态方法,可以当做普通函数进行hook。
对象的非静态方法,需要考虑上下文content,也就是对象的指针this。所以不能像普通函数一样直接赋值,不过js提供了原型prototype模型,我们以localStorage.getItem为例,代码如下:

var getItemMy = Storage.prototype.getItem
Storage.prototype.getItem = (key) => {console.log('Storage.prototype.getItem', key)return getItemMy.call(localStorage, key)
}
localStorage.getItem('AEGIS_ID')

执行效果如下:
【js逆向】hook大全

3️⃣ 对象属性(Object.defineProperty)

对于对象属性,js提供了方法Object.defineProperty,该方法可以拦截并修改对象属性。我们以document.domain为例,做如下修改:

Object.defineProperty(document, 'domain', {// 改为可修改属性!!!configurable: true,enumerable: true,get: function() {return this._domain || location.host;},set: function(value) {this._domain = value;}
});

效果如下:
【js逆向】hook大全

不过document.domain的这种方法只影响使用Javascript获取的数据,不会影响浏览器发送请求时带上的浏览器标识。
事实上,有多很多系统对象都是不允许使用Object.defineProperty修改的,例如:window.locationnavigator.userAgent等。

4️⃣ Proxy

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
由于Proxy是一个比较新的概念,所以只有高版本浏览器才支持该功能。
【js逆向】hook大全

我们依然以localStorage.getItem为例进行演示,需要注意的是,最后将localStorage.getItem = proxy1。代码如下:

const proxy1 = new Proxy(localStorage.getItem, {// 1.目标对象// 2.目标对象的上下文对象(this)// 3.目标对象的参数数组apply(target, object, args) {console.log(target, object, args)return target.call(object,...args);}
})
// 需要将方法设置为
localStorage.getItem = proxy1
localStorage.getItem('AEGIS_ID')

效果如下:
【js逆向】hook大全

5️⃣ 批量hook示例

js逆向过程,往往需要对各种关键函数进行hook,下面是找到的油猴脚本,直接复制后在控制台运行即可,可以在变量var source中增加自己关注的函数进行监控。

以函数JSON.stringify为例,说明下面脚本流程。

  • let item = source[i]; // 获取某项(字符串),即"JSON.stringify"
  • let realCtx = getRealCtx(ctx, item); // 获取函数所在的对象(类),即JSON
  • let realName = getRealName(item); // 获取函数名,即"stringify"
  • let originFunc = realCtx[realName]; // 获取函数,即JSON.stringify
  • hook(realCtx, realName, level, originFunc); // 执行hook,即将JSON.stringify赋值给自己定义的一个函数,内部调用originFunc实现原有逻辑
// ==UserScript==
// @name         HOOK ALL end
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  day day up!
// @author       FY
// @include      *
// @grant        none
// @run-at       document-end
// ==/UserScript==(function() {'use strict';var source = ['DeCode','EnCode','decodeData','base64decode','md5','decode','btoa','MD5','RSA','AES','CryptoJS','encrypt','strdecode',"encode",'decodeURIComponent','_t','JSON.stringify','String.fromCharCode','fromCharCode'];console.log("开始测试是否有解密函数");let realCtx, realName;function getRealCtx(ctx, funcName) {let parts = funcName.split(".");let realCtx = ctx;for(let i = 0; i < parts.length - 1; i++) {realCtx = realCtx[parts[i]];}return realCtx;}function getRealName(funcName) {let parts = funcName.split(".");return parts[parts.length - 1];}function hook(ctx, funcName, level, originFunc) {ctx[funcName] = function(a){console.log("level:" + level + " function:" + funcName,a);console.log(originFunc.toString());console.log(originFunc.toString);debugger;return originFunc(a);};}function test(ctx, level) {for(let i = 0; i < source.length; i++) {let item = source[i];let realCtx = getRealCtx(ctx, item);let realName = getRealName(item);let originFunc = realCtx[realName];hook(realCtx, realName, level, originFunc);}}test(window, 1);
})();

🛬 文章小结

上面各种方案中,Proxy可以实现各种hook,可以说是一劳永逸的方案。而且代码耦合性更低,实现hook更简单明了。
js逆向依托于浏览器,技术点特别多,我们需要基于现有知识储备,不断探索新的方案,从而实现目标。

📖 参考资料

  • JavaScript常用的Hook脚本 https://www.cnblogs.com/xiaoweigege/p/14954648.html
  • 爬虫从入门到精通(11) | JS逆向hook详解 https://blog.csdn.net/qq_40558166/article/details/123525365
  • js逆向:无所不能的 hook 钩子函数 https://blog.csdn.net/qq_36078992/article/details/114484218
  • 浅谈Javascript中的Hook技术 https://cloud.tencent.com/developer/article/1639578
  • 刚学的油猴脚本hook住js https://www.jianshu.com/p/1bf123b3c8bf
  • 爬虫从入门到精通(11) | JS逆向hook详解 https://blog.csdn.net/qq_40558166/article/details/123525365

ps:文章中内容仅用于技术交流,请勿用于违规违法行为。