文章总结: 本文介绍利用JSHook技术优雅去除ProxmoxVirtualEnvironment(PVE)无订阅提示弹窗的实战方法。通过分析PVE前端代码定位弹窗函数Ext.Msg.show,编写油猴脚本在特定标题时拦截弹窗调用,并解决脚本注入时机问题。相较于直接修改源码,该方法具有版本兼容性强、维护成本低的优势,并提供了完整可用的代码实现。 综合评分: 82 文章分类: WEB安全,逆向分析,安全工具,实战经验,应用安全
JS逆向实战:优雅去除 PVE “无效订阅”提示
原创
LLLibra146 LLLibra146
LLLibra146
2025年8月8日 08:01 北京
在小说阅读器读本章
去阅读
大家好,好久不见了,今天分享一种利用 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 完全开源免费,它的商业模式是提供增值服务,如果不订阅也不会影响任何功能的使用。对于个人用户而言,免费的无订阅模式已足够使用,其主要区别在于更新源的稳定性——无订阅源可能包含未充分测试的更新,不建议用于生产环境。
image-20250807214052171
目前我使用 2000 多块的硬件跑了 2 年+也挺稳定的,除非有更新否则不用关机,完全满足我的需求。
尽管功能不受影响,但使用无订阅源会在每次登录成功后弹出一个“无有效订阅”的提示框。有时该弹窗的“确定”按钮甚至无法点击,必须刷新页面才能关闭,这在日常使用很是烦人。
传统解决方案是直接修改 PVE 的前端 JS 源码,但这种方式的缺点在于,一旦 PVE 面板更新,就需要重新修改,操作较为繁琐。因此,我采用 JS 逆向的思路,通过编写油猴(Tampermonkey)脚本来 Hook 关键函数,从而一劳永逸地屏蔽该弹窗。
寻找 hook 点
image-20250807220716721
要 hook 弹窗,首先要找到弹窗的地方,这里可以直接参考网上其他人的方法,使用关键字 data.status 来搜索,基本上第一个结果就是我们要找的地方。
image-20250807221832486
image-20250807220849422
或者可以完整的执行一遍登录的流程,查看所有的接口请求,根据关键字找到 URL,然后搜索 URL 也可以找到弹窗的地方。
hook 弹窗
找到 hook 点以后,就要思考如何让弹窗无法弹出来,先分析一下代码。
image-20250807222020657
首先请求使用了一个工具函数 Proxmox.Utils.API2Request 发出,这里是第一个 hook 点,可以判断 URL 是否是特定的 URL,然后直接忽略请求,也就不会执行请求的 callback 代码了。继续往下看,弹窗是由另一个工具函数 Ext.Msg.show 弹出来的,这里是第二个 hook 点,可以 hook 弹窗的工具函数,让它在某个 title 的时候不执行。
继续往下看,请求成功以后会执行一个 orig_cmd 方法,为了不影响正常的调用流程,我这里选择的第二个 hook 点,在弹窗的时候判断是否是无订阅的弹窗,然后让其不再执行。
hook 代码
新建一个油猴脚本,写入以下代码:
// ==UserScript==
// @name PVE 移除订阅按钮
// @namespace http://tampermonkey.net/
// @version 2025-08-06
// @description try to take over the world!
// @author You
// @match https://xxxxx:8006/
// @icon https://www.google.com/s2/favicons?sz=64&domain=233.27
// @grant none
// @run-at document-idle
// ==/UserScript==
(function () {
'use strict';
console.log('loaded!');
let s = Ext.Msg.show;
Ext.Msg.show = function (a) {
if (a.title === '无有效订阅') {
console.log('return!')
return;
} else {
s(a);
}
}
})();
代码很简单就不多解释了,别忘了添加:// @run-at document-idle,它的作用是让油猴脚本在页面加载完成后再注入,因为过早的注入可能工具函数还没有初始化完成,会导致注入失败。
hook 尝试
image-20250807222756063
刷新页面会发现报错了,提示没有找到 show 属性,油猴注入的时机已经很晚了,在页面加载后才执行,为什么还会报错呢?猜测可能是因为有些代码不是立马就初始化的,可能使用了 settimeout 之类的方案使得初始化被延迟执行了。
分析具体的执行逻辑比较麻烦,我这里选择一个比较简单的方案,同样使用 settimeout 延迟执行,因为我测试了一下在页面加载完成后手动执行 hook 脚本是可以正常执行的。
修改后的代码(此代码会丢失 this,最新代码详见评论区):
(function () {
'use strict';
setTimeout(function () {console.log('loaded!');
let s = Ext.Msg.show;
Ext.Msg.show = function (a) {
if (a.title === '无有效订阅') {
console.log('return!')
return;
} else {
s(a);
}
}},2000)
})();
刷新页面重新测试。
image-20250807225651735
image-20250807225754448
可以看到,控制台成功打印了加载信息,登录后的弹窗也不再出现。至此,问题完美解决!
总结
以上就是本次利用 JS Hook 去除 PVE 订阅提示的全过程。相较于直接修改源码,这种方式无疑更加灵活和持久,感兴趣的小伙伴可以自己试一下。
我创建了一个逆向交流群,想要进群的小伙伴可以在后台点击“联系我”菜单或者扫码,添加微信并且备注“交流群”,我会拉你进群。
推荐阅读:
AST 技巧:还原逗号表达式
AST 技巧:压缩变量定义
JS调试技巧:避免控制台卡死的日志断点使用技巧
0基础1分钟解密任何HTTPS加密流量
JS调试技巧:如何让时间和随机数“听你指挥”?升级版!
AST 技巧:模版(template)的高级用法
如何在浏览器中使用 AST 实时反混淆?(附AST模版可直接使用)
AST 使用技巧:如何快速分析混淆代码结构
在 JS逆向时如何 hook 属性?
如何 “正确” hook JS方法
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:LLLibra146 LLLibra146 LLLibra146《JS逆向实战:优雅去除 PVE “无效订阅”提示》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论