{"id":20183222,"url":"https://github.com/zhifengle/js-hook","last_synced_at":"2025-04-10T05:24:18.240Z","repository":{"id":140132293,"uuid":"499081132","full_name":"zhifengle/js-hook","owner":"zhifengle","description":"解析 JavaScript 的 AST，添加自定义的钩子","archived":false,"fork":false,"pushed_at":"2024-04-11T08:38:50.000Z","size":548,"stargazers_count":11,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T06:45:26.332Z","etag":null,"topics":["crawler","js-reverse"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zhifengle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-06-02T09:56:13.000Z","updated_at":"2025-03-10T13:31:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"c7212289-29ba-43b5-bbe0-4d61ed8bd94f","html_url":"https://github.com/zhifengle/js-hook","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhifengle%2Fjs-hook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhifengle%2Fjs-hook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhifengle%2Fjs-hook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhifengle%2Fjs-hook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhifengle","download_url":"https://codeload.github.com/zhifengle/js-hook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161772,"owners_count":21057647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crawler","js-reverse"],"created_at":"2024-11-14T02:44:27.149Z","updated_at":"2025-04-10T05:24:18.218Z","avatar_url":"https://github.com/zhifengle.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# js-hook\n\n解析 JavaScript 的 AST，添加自定义的钩子。\n\n逻辑和思路参考 [JSREI/ast-hook-for-js-RE: 浏览器内存漫游解决方案（探索中...）](https://github.com/JSREI/ast-hook-for-js-RE)\n\n出于学习的目的，用 TypeScript 按照自己的理解重写了一遍。\n\n主要改动\n\n- 使用 [avwo/whistle](https://github.com/avwo/whistle) 作为拦截代理\n  1. [alibaba/anyproxy](https://github.com/alibaba/anyproxy) 好像没人维护了\n  2. whistle 的规则功能比较灵活，可以按需配置要处理的 JS 的文件。比如不需要处理 jquery 文件，就设置规则排除。规则参考看下文。\n  3. whistle 能够避免和代理软件冲突\n- 调整的资源的缓存方式，资源缓存在用户目录下面的 `.cache/js-hook-cache`。按照域名和资源路径保存。\n- 支持 Web Worker\n- 添加构建和变量配置\n\nTODO\n\n- [x] 针对 `eval expressions` 的处理。\n  - 这里指的是 eval Function, setTimeout, setInterval\n  - 参考链接: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_eval_expressions\n- [ ] 优化速度，使用 Rust 版本的 babel: `swc`。直接使用 `@swc/core` 或者用 Rust 实现\n  - 可能会鸽。\n- [ ] 保存 hook 数据的历史记录，对比前后两次的调用。\n\n## 使用\n\n安装 [avwo/whistle](https://github.com/avwo/whistle). whistle 的配置请参考官方文档\n\n项目使用 [pnpm](https://pnpm.io/) 管理依赖。 [安装文档](https://pnpm.io/installation)\n\n```bash\npnpm install\n# 构建项目，然后将本项目里面的 whistle.hook-server 插件 link 到全局的依赖。方便 whistle 读取\n# 同时运行 packages/server 服务\npnpm run start\n```\n完成 whistle 的安装和配置代理 `127.0.0.1:8899`，并在本地运行本项目。\n\n打开 http://127.0.0.1:8899/#rules 配置规则\n\n以 cn.bing.com 为例子，规则如下\n\n```conf\ncn.bing.com hook-server://hook\n```\n\n规则配置完成后，浏览器打开 https://cn.bing.com ，F12 打开开发者工具。控制台现在能使用 search('xxx') 了\n\n具体原理就是：访问 cn.bing.com，会访问中间代理 `127.0.0.1:8899`，如果配置了 `cn.bing.com hook-server://hook`\n中间代理响应请求时，会执行本项目的 hook-server 注入 JS 代码。\n\n\u003e [!IMPORTANT]  \n\u003e 然后打开 whistle 的规则配置页面 http://127.0.0.1:8899/#rules 配置好 hook-server 规则。才能正常使用\n\n具体设置，参考下面的 [whistle 的规则参考](#whistle-rules)\n\n## packages/core\n\n解析 AST，添加变量赋值，函数参数，对象属性值初始化等的钩子。\n\n其中 `browser` 是需要在浏览器端运行的依赖和自定义拦截。\n\n## packages/server\n\n提供一个接口，当检测浏览器端有 `eval expressions` 时，调用这个接口，返回添加钩子的结果\n\n## packages/whistle.hook-server\n\n目前内置了四种规则 `hook` `hook-js` `hook-no-cache` `hook-js-no-cache`。\n\n- `hook`: 解析修改 JavaScript 文件。在 HTML 文件的头部插入运行依赖.\n- `hook-js`: 解析修改 JavaScript 文件并在每一个 JS 文件头部插入运行依赖\n- `hook-no-cache`: 同 `hook`，只是没有缓存解析后的 JS 文件。\n- `hook-js-no-cache`: 同 `hook`，只是没有缓存解析后的 JS 文件。\n\n### whistle-rules\n\nwhistle 的规则参考\n\n```conf\n# 需要 SwitchyOmega 的规则配置 \u003c-loopback\u003e。设置参考 packages/demos 部分的说明\nlocalhost hook-server://hook excludeFilter:///jquery/\n# 使用正则排除链接里面包含 jquery 的文件\n# 这里自定义的 m.com 域名。需要利用 Nginx。设置参考最下面\nm.com hook-server://hook excludeFilter:///jquery/\n\n# 统计脚本返回 404；\nhttps://hm.baidu.com statusCode://404\n# 返回 404；这些都是反调试的脚本\n/match.yuanrenxue.com\\/static\\/match\\/safety\\/.*.js/ statusCode://404\nmatch.yuanrenxue.com hook-server://hook-js excludeFilter:///jquery/\n# 在 cn.bing.com 上添加 hook\ncn.bing.com hook-server://hook\n```\n\n## packages/demos\n\n本地测试用的例子\n\n运行 `npm run demos`，配置好 `whistle` 。\n打开 http://localhost:3000/hook-test 测试。\nF12 打开控制台。输入 `search('testEval')` 搜索\n\n\u003e [!note]  \n\u003e SwitchyOmega 配置\n\u003e 具体见 [#2](https://github.com/zhifengle/js-hook/issues/2)\n\n![chrome-localhost-test screenshot](screenshots/chrome-localhost-test.png 'chrome-localhost-test screenshot')\n\n也可以利用的 Nginx 设置本地域名进行反向代理\n\n```conf\n# Nginx 配置\nserver {\n    listen       80;\n    server_name  m.com;\n    location / {\n      proxy_pass       http://localhost:3000;\n    }\n}\n```\n\n配置好 Nginx 后 http://m.com/hook-test 测试。\n\n![chrome-test screenshot](screenshots/chrome-test.png 'chrome-test screenshot')\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhifengle%2Fjs-hook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhifengle%2Fjs-hook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhifengle%2Fjs-hook/lists"}