它不用VPN,但你也不许用:我如何绕过雅迪的VPN检测

💡 原文英文,约1400词,阅读约需5分钟。
📝

内容提要

雅迪App检测到VPN即退出,但其流量并不经过VPN。由于360加固阻止进程内Hook,作者通过内存导出DEX分析,确认其检查全网VPN状态。最终利用VPN Hide在system_server层过滤Binder网络数据,并用内核模块隐藏tun0接口,成功绕过检测。

🔎

延伸解读

检测逻辑:为何绕过VPN设置无效

雅迪App并不检查自身流量是否经过VPN,而是检查手机整体是否存在VPN连接。文章确认其UID为10450,不在VPN覆盖列表或分应用代理列表中,流量始终直连。因此,在VPN客户端中将雅迪设为绕过并不会消除警告,因为它检测的是全网VPN状态,而非自身路由。

绕过方案:为何必须同时处理Java与内核层

由于360加固阻止进程内Hook,作者采用VPN Hide在system_server层过滤Binder数据,移除NetworkCapabilities等中的VPN信息;同时使用内核模块隐藏tun0接口,拦截ioctl、getifaddrs和netlink查询。统计显示156次拦截中130次为原生ioctl接口查询,仅靠Java层无法覆盖,因此内核层隐藏是必要的。

方案边界与风险

VPN Hide仅处理手机本地可查询的VPN特征,不隐藏root,也不应对Play Integrity。服务端检查如DNS泄漏、IP黑名单、TLS指纹等超出其能力范围。内核模块虽无需刷写内核,但会改变运行中内核行为,兼容性问题可能导致系统崩溃,卸载后需重启才能完全恢复。

与WPS案例的对比

WPS检查的是是否安装root管理器,且无加固保护,因此用HMA隐藏包名即可。雅迪检查的是手机是否有VPN,且受360加固和反Hook保护,进程内Hook会被检测并导致退出。两者检测目标和防护强度不同,导致修复位置从应用层上升到system_server和内核层。

❓

Q&A

雅迪App为什么检测到VPN就退出?

雅迪App会检查手机是否开启了VPN,一旦检测到就显示“检测到VPN环境,请调整网络”并退出。即使雅迪自身的流量并不经过VPN,它也会进行这项检查。

为什么不能直接在雅迪App进程内Hook绕过检测?

雅迪App使用了360加固,会阻止进程内Hook。尝试用LSPosed模块Hook检测方法时,加固在初始化阶段就发现并导致App反复退出,无法进入业务代码。Frida也因版本兼容问题无法运行。

如何获取雅迪App的业务代码进行分析?

由于静态解包只能得到壳代码,作者让App在运行时自行解密,然后从内存中导出业务DEX文件,从而读取到实际代码。

VPN Hide是如何在系统层面隐藏VPN的?

VPN Hide在Java层通过LSPosed模块Hook system_server,在Binder的writeToParcel处过滤掉NetworkCapabilities、NetworkInfo和LinkProperties中的VPN信息;在Native层通过内核模块(kmod)隐藏tun接口,过滤ioctl、getifaddrs和netlink路由转储,使原生代码也无法发现VPN。

使用VPN Hide绕过雅迪检测后效果如何?

重启加载内核模块后,在NekoBox连接状态下,雅迪App连续两次冷启动都直接进入车辆主页,没有VPN警告,也没有退出。统计页面显示43秒内记录了156次拦截,其中大部分是原生ioctl网络接口查询。

VPN Hide能隐藏Root或绕过服务器端检测吗?

不能。VPN Hide只处理手机上可查询的VPN特征,不隐藏Root,也不处理Play Integrity。对于DNS泄漏、IP黑名单、TLS指纹等服务器端检查,它无能为力。

雅迪和WPS的检测方式有什么不同?

WPS检查是否安装了Root管理器,没有加固,检测在应用层,用HMA隐藏包名即可绕过;雅迪检查手机是否有VPN,有加固和反Hook,需要在system_server和内核层修改数据才能绕过。

🏷️

标签

➡️

继续阅读