Releases: pxx917144686/Surge_iOS
Releases · pxx917144686/Surge_iOS
5.14.4版本 被反制~
被 Surge 阻击了~ 反制了!
修复“已知问题” Script Hub & Sub Store
每次修改一点点!小改怡情、大改伤身~
- 0.5.0 解决:Surge 模块功能 403 异常问题,显示不了问题。
- 0.5.1 解决:模块加载不了 script hub 问题。
- 0.5.2 解决:模块加载不了 sub-store 问题。
- 0.5.3 解决:模块功能!测试:Script Hub & Sub Store 可以正常使用~
- 0.5.4 解决:整体稳定性 补充 几个钩子~
/*
解释:
首次打开 Surge :显示第一个 免责声明 弹窗。
点击“不同意”优雅退出动画~
点击“已同意”应显示第二个弹窗。
第二个弹窗 :
点击“源代码”应优雅退出应用并跳转链接。
点击“下一步”应显示第三个弹窗。
第三个弹窗 :
点击“👍”或“👎” 优雅退出动画~
点击“👎”应跳转官方支付链接。
再次启动应用时,6 小时内不应显示弹窗。
超过 6 小时 :再次启动 Surge 时,重新显示第一个弹窗。
*/
修复“已知问题” 模块 Sub Store 加载不出来问题
修复“已知问题” 模块 Script Hub 加载不出来问题
Surge++ 修复“已知问题” ——> Surge 全部版本
Surge 函数 关键入口
简单的解释:
Surge(5.8.3 以上版本)可能在以下几个方面与旧版本存在差异
1、模块与规则刷新
- 函数名称和调用链更加分散,不再集中在单个
Profile模块中,而是分布在多个视图控制器(如SGUTVConfiguration、SGUEditRuleset、SGUEditHTTPAPIAccess)
2、License 校验与网络响应
- 新增了对
403响应的处理和对license数据的更加细化的解析、验证,导致旧版本拦截和伪造响应的hook代码失效。
3、UI 及跨设备联动(Ponte)
- 针对
tvOS平台,增加了专门的配置刷新和设备联动函数(例如updatePonteProxyCell),需要重新hook才能修改相应数据。
4、大量 runtime 调用
- 新版 Surge 内部更多采用了动态调用方式(使用
_objc_msgSend$前缀的函数), hook时,需要精确匹配新版的符号和地址。
5、问题
- 同样的
hook代码在5.9.0以下版本,能够正常生效! - 可能新版 Surge 修改了内部数据结构、函数命名以及调用逻辑,导致原有
hook无法生效,出现403拦截或者空白模块加载的情况。
一、与刷新相关
-[StartViewController configurationDidChange] (0x100005F58)
// 处理全局配置变化,触发界面更新。
-[SGUCardViewController configurationDidChange] (0x100053250)
// 触发卡片视图的配置更新,刷新展示的内容。
-[SGUStartV5ViewController configurationDidChange] (0x1000DFBA0)
// 在 Surge V5 APP 打开过程中,当配置发生变化时调用,用于整体状态刷新。
-[SGUAppDelegate configurationDidChange] (0x1000F0EC4)
// 应用代理在配置变化时做出响应,协调全局更新。
-[SGUProxySelectViewController configurationDidChange] (0x10007D8F4)
// 代理选择界面配置变化时刷新显示,可能与代理服务器列表或选中状态有关。
_objc_msgSend$configurationDidChange (0x1004279A0)
// 内部大量调用“配置更新”相关的 runtime 函数,调用频繁,说明 Surge 在模块更新时会对配置数据做较多处理。
二、与授权相关
-[SGULicenseBindCloudViewController licenseResponse] (0x100009A44)
// 处理从云端返回的 license 响应,更新授权信息。
-[SGULicenseViewController reloadCells] (0x1000616D4)
// 刷新 License 显示界面,对过期时间、状态、计划等信息进行展示。
_objc_msgSend$licenseResponse (0x1004324C0)
// 说明内部有专门处理 license 响应的调用链,可能用于校验和数据更新。
-[SGUTVProfileSyncer effectiveSettingsModel:modules:ponteType:ponteName:ponteProxy:pontePort:error:] (0x100107E24)
// 整合 tvOS 下的设置数据,包含模块信息、Ponte 参数等,此处通常需要 hook 来修改返回的数据,从而达到绕过某些授权校验。三、模块与规则 相关~
-[SGUProfileManager isProfileAbilitiesActivated:showAlert:] (0x100020A84)
// 检查用户 Profile 功能激活情况,并根据需要弹出提示框。可能是授权、功能开关有关。
-[SGUProfileListViewController reloadCells] (0x100023828)
// 用于刷新 Profile 列表,加载用户 Profile 数据。在旧版本中该函数常被作为 hook 点,但新版 Surge 可能已经拆分并迁移到更多独立模块中。
-[SGULogicalRuleViewController subRuleMode] (0x1000854E8)
// 返回当前规则集的子规则模式,决定 UI 如何呈现规则细节。
-[SGUEditRulesetViewController reloadCells] (0x1000B43B8)
// 负责规则集编辑界面的刷新。
-[SGUEditRulesetViewController subRuleMode] (0x1000B4F08)
// 判断是否启用子规则模式。
-[EditRuleViewController subRuleMode] (0x10010538C)
// 规则是否处于子规则状态,可能与 UI 显示相关。
-[SGModuleSection modules] (0x100236FB4)
_objc_msgSend$modules (0x100433CE0)
// 返回当前模块数据,hook 这类函数可以用于修改模块列表或状态,从而绕过模块校验或加载错误问题。
_objc_msgSend$updateModuleCell (0x1004481A0)
_objc_msgSend$updatePonteProxyCell (0x100448280)
// 这两个函数分别用于更新模块单元格和跨设备联动(Ponte)的单元格。四、网络请求与状态提示 相关
-[SGUEditHTTPAPIAccessViewController reloadCells] (0x1000B9ADC)
// 负责刷新 HTTP API 访问配置界面。
-[EditExternalAccessViewController reloadCells] (0x1000B92B4)
// 刷新外部访问设置的界面。
-[EditHTTPSViewController reloadCells] (0x1001ABD84)
// 处理 HTTPS 相关的配置页面刷新。
-[IPClientModeInputTableViewController reloadCells] (0x10010FFEC)
// IP 客户端模式下刷新输入配置。
-[SGUTunnelManager configurationChanged] (0x1001DE8FC)
// VPN 隧道配置发生改变时调用,可能用于重新建立或调整连接。
+[_objc_msgSend$configurationWithPointSize:weight:] (0x100427A40)
// 主要与 UI 控件(例如按钮、图标)的外观配置有关。
UIButton 相关的 _objc_msgSend$configurationAbC… (0x10041F6B0, 0x10041F6BC)
// 与 Surge 内部 UI 控件样式调整、图标设置有关。五、其他关键
#### 大量以 _objc_msgSend$ 开头的符号(如 _objc_msgSend$reloadCells、_objc_msgSend$showAlert、_objc_msgSend$subRuleMode 等)
// 表示 Surge 内部大量通过 runtime 动态调用各模块函数添加:Roothide越狱
| 类型 | 定义 | 文件系统权限 | 插件兼容性 | 适用场景 |
|---|---|---|---|---|
| Rootful 越狱 | 传统有根越狱,可完全访问 /System 分区,属于“全功能越狱” |
拥有 root 权限,可直接写入 /System,可替换系统文件以及修改关键系统组件 |
兼容几乎所有旧的越狱插件(如依赖 MobileSubstrate 的经典插件) | 对系统进行深度定制、修改系统文件、替换系统核心模块、安装各种高级插件 |
| Roothide 越狱 | 一种介于 rootful 与 rootless 之间的特殊变种越狱,部分隐藏了 root 权限,可一定程度改写系统分区 |
理论上用户态无法直接写入 /System,但可借助 Roothide 自身机制进行有限的系统更改 |
对旧插件有一定兼容性,但仍需适配;可绕过部分安全检测(如银行 App 等) | 对系统进行有限度的修改,兼容部分旧插件同时不易被检测,保持相对“无越狱”外观 |
| Rootless 越狱 | 无根越狱,不允许对 /System 分区直接写入,修改都在 /var/jb/ 等目录中完成 |
无法获取 root 权限,系统分区保持只读,所有改动存放在隔离目录 |
仅兼容已适配 rootless 结构的插件 | 更安全、更稳定的越狱方式,不影响系统完整性,适合不需要深度修改系统、只想安装新式插件或规避检测的用户 |
移除下面代码! 点击 策略组 会闪退~ 👇 懒得优化代码、分析原因~
修复已知错误: TrollFools注入 —> Surge的授权管理内容无效
SGULicenseViewController Hook 代码优化说明
修改前后对比
| 优化点 | 修改前 | 修改后 | 优化效果 |
|---|---|---|---|
| 确保 Hook 可靠执行 | 无 +load 方法 |
objc<br>+ (void)load {<br> NSLog(@"[Surge Hook] SGULicenseViewController 被 Hook");<br>}<br> |
避免 Hook 失效 |
| 增强 handleResponse 记录 | objc<br>- (void)handleResponse:(NSDictionary *)response {<br> %orig(response);<br>}<br> |
objc<br>- (void)handleResponse:(NSDictionary *)response {<br> NSLog(@"[Surge Hook] handleResponse 被调用: %@", response);<br> %orig(response);<br>}<br> |
便于调试 Hook 执行 |
| 增强 handleAsyncResponse 记录 | objc<br>- (void)handleAsyncResponse:(NSDictionary *)response {<br> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{<br> %orig(response);<br> });<br>}<br> |
objc<br>- (void)handleAsyncResponse:(NSDictionary *)response {<br> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{<br> NSLog(@"[Surge Hook] handleAsyncResponse 被调用: %@", response);<br> %orig(response);<br> });<br>}<br> |
确保异步 Hook 可追踪 |
| _response 变量获取优化 | objc<br>NSDictionary *response = object_getIvar(self, class_getInstanceVariable([self class], "_response"));<br>if (!response) {<br> %orig;<br> return;<br>}<br> |
objc<br>NSDictionary *response = object_getIvar(self, class_getInstanceVariable([self class], "_response"));<br>if (!response) {<br> NSLog(@"[Surge Hook] _response 为空,调用原始方法");<br> %orig;<br> return;<br>}<br> |
避免 _response 为空导致 Hook 失败 |
| License 数据伪造优化 | objc<br>NSMutableDictionary *mutableResponse = [response mutableCopy];<br>NSMutableDictionary *license = [mutableResponse[@"license"] mutableCopy];<br>if (!license) {<br> license = [NSMutableDictionary dictionary];<br>}<br> |
objc<br>NSMutableDictionary *mutableResponse = [response mutableCopy];<br>NSMutableDictionary *license = [mutableResponse[@"license"] mutableCopy] ?: [NSMutableDictionary dictionary];<br> |
减少 nil 赋值错误 |
| UI 刷新逻辑优化 | objc<br>[self.view setNeedsDisplay];<br>%orig;<br> |
objc<br>NSLog(@"[Surge Hook] _response 变量已修改: %@", mutableResponse);<br>dispatch_async(dispatch_get_main_queue(), ^{<br> [self.view setNeedsDisplay];<br>});<br>%orig;<br> |
防止 UI 刷新在后台线程执行,避免 UI 崩溃 |
简单总结
- 增强 Hook 可靠性,确保 Hook 执行不会失败。
- 改进调试能力,增加
NSLog记录 Hook 过程,便于追踪 Hook 逻辑。 - 优化 UI 刷新逻辑,防止 UI 刷新在后台线程执行,避免崩溃。
- 简化代码逻辑,减少
nil赋值问题,提高代码可读性。


































