它不用VPN,但你也不许用:我如何绕过雅迪的VPN检测
内容提要
雅迪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和内核层修改数据才能绕过。