JS逆向实战:优雅去除 PVE “无效订阅”提示
大家好,好久不见了,今天分享一种利用 JS Hook 技术去除 Proxmox Virtual Environment (PVE) “无效订阅”弹窗的方法。相较于直接修改源码,此方案更为优雅,可避免因 PVE 版本更新导致修改失效的问题。
PVE
首先,为不熟悉 PVE 的小伙伴简单介绍一下:
PVE(Proxmox Virtual Environment)是一个开源的服务器虚拟化管理平台。它基于Debian Linux,集成了KVM(Kernel-based Virtual Machine)用于虚拟机管理和LXC(Linux Containers)用于容器管理。PVE允许你在同一台物理服务器上运行多个独立的操作系统实例,无论是Windows、Linux虚拟机还是轻量级容器。它提供了一个直观的Web界面,方便用户创建、配置、监控和管理这些虚拟资源,是构建私有云或虚拟化环境的理想选择。
为什么会有这个需求呢?因为我之前在家里搭了一个 PVE 服务端,开了一堆虚拟机和容器,顺便也可以把它当做 nas 来使用,开几个 smb 文件夹,还是很香的。
PVE 完全开源免费,它的商业模式是提供增值服务,如果不订阅也不会影响任何功能的使用。对于个人用户而言,免费的无订阅模式已足够使用,其主要区别在于更新源的稳定性——无订阅源可能包含未充分测试的更新,不建议用于生产环境。
目前我使用 2000 多块的硬件跑了 2 年+也挺稳定的,除非有更新否则不用关机,完全满足我的需求。
尽管功能不受影响,但使用无订阅源会在每次登录成功后弹出一个“无有效订阅”的提示框。有时该弹窗的“确定”按钮甚至无法点击,必须刷新页面才能关闭,这在日常使用很是烦人。
传统解决方案是直接修改 PVE 的前端 JS 源码,但这种方式的缺点在于,一旦 PVE 面板更新,就需要重新修改,操作较为繁琐。因此,我采用 JS 逆向的思路,通过编写油猴(Tampermonkey)脚本来 Hook 关键函数,从而一劳永逸地屏蔽该弹窗。
寻找 hook 点
要 hook 弹窗,首先要找到弹窗的地方,这里可以直接参考网上其他人的方法,使用关键字 data.status
来搜索,基本上第一个结果就是我们要找的地方。
或者可以完整的执行一遍登录的流程,查看所有的接口请求,根据关键字找到 URL,然后搜索 URL 也可以找到弹窗的地方。
hook 弹窗
找到 hook 点以后,就要思考如何让弹窗无法弹出来,先分析一下代码。
首先请求使用了一个工具函数 Proxmox.Utils.API2Request
发出,这里是第一个 hook 点,可以判断 URL 是否是特定的 URL,然后直接忽略请求,也就不会执行请求的 callback
代码了。继续往下看,弹窗是由另一个工具函数 Ext.Msg.show
弹出来的,这里是第二个 hook 点,可以 hook 弹窗的工具函数,让它在某个 title
的时候不执行。
继续往下看,请求成功以后会执行一个 orig_cmd
方法,为了不影响正常的调用流程,我这里选择的第二个 hook 点,在弹窗的时候判断是否是无订阅的弹窗,然后让其不再执行。
hook 代码
新建一个油猴脚本,写入以下代码:
1 | // ==UserScript== |
代码很简单就不多解释了,别忘了添加:// @run-at document-idle
,它的作用是让油猴脚本在页面加载完成后再注入,因为过早的注入可能工具函数还没有初始化完成,会导致注入失败。
hook 尝试
刷新页面会发现报错了,提示没有找到 show
属性,油猴注入的时机已经很晚了,在页面加载后才执行,为什么还会报错呢?猜测可能是因为有些代码不是立马就初始化的,可能使用了 settimeout
之类的方案使得初始化被延迟执行了。
分析具体的执行逻辑比较麻烦,我这里选择一个比较简单的方案,同样使用 settimeout
延迟执行,因为我测试了一下在页面加载完成后手动执行 hook 脚本是可以正常执行的。
修改后的代码:
1 | (function () { |
刷新页面重新测试。
可以看到,控制台成功打印了加载信息,登录后的弹窗也不再出现。至此,问题完美解决!
总结
以上就是本次利用 JS Hook 去除 PVE 订阅提示的全过程。相较于直接修改源码,这种方式无疑更加灵活和持久,感兴趣的小伙伴可以自己试一下。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!