1. 静态分析
使用 IDA 分析可执行文件 IPLocate,在方法列表中搜索 dns
,可以看到有用到 NEDNSSettingsManager
类。
然后在 Strings Table 中搜索 dns
,可以看到有一个关键的 URL: https://anyto-app-dns.irocketx.com/dns-query
。
再继续查找看看有哪个类需要用到这个 URL,最终看到 NEDNSOverHTTPSSettings
类中用到了这个 URL。
通过查看系统 API,可以知道这个 URL 将设置到 NEDNSOverHTTPSSettings
类的 serverURL
属性。
2. 动态追踪
通过静态分析,我们找到了两个关键类:NEDNSSettingsManager
和 NEDNSOverHTTPSSettings
。下面我们使用 Frida 来动态追踪这两个类。
打开 IPLocate App,然后使用 frade-trace
命令追踪 NEDNSSettingsManager
和 NEDNSOverHTTPSSettings
类的所有方法:
frida-trace -U -m "-[NEDNSSettingsManager *]" -m "-[NEDNSOverHTTPSSettings *]" IPLocate
运行上面的命令后 会在当前目录生成名为 __handlers__
的文件夹,其中包含为每个跟踪的函数生成的 JS 文件。可以编辑这些文件来自定义行为。
对于 NEDNSSettingsManager
类,我们主要关注的是 setDnsSettings:
这个方法, 将 setDnsSettings_.js
文件内容替换为以下内容来获取所有的 DNS 配置信息:
defineHandler({
onEnter(log, args, state) {
log(`-[NEDNSSettingsManager setDnsSettings:] called`);
// 将 args[2] 转换为 ObjC 对象以便访问其属性
const dnsSettings = new ObjC.Object(args[2]);
// 打印各个属性值
log(`NEDNSSettings details:`);
log("- className: " + dnsSettings.$className);
log(`- servers: ${dnsSettings.servers()}`);
log(`- searchDomains: ${dnsSettings.searchDomains()}`);
log(`- domainName: ${dnsSettings.domainName()}`);
log(`- matchDomains: ${dnsSettings.matchDomains()}`);
log(`- matchDomainsNoSearch: ${dnsSettings.matchDomainsNoSearch()}`);
},
onLeave(log, retval, state) {},
});
对于 NEDNSOverHTTPSSettings
类,我们主要关注的是 setServerURL:
这个方法, 将 setServerURL_.js
文件内容替换为以下内容:
defineHandler({
onEnter(log, args, state) {
// 打印 setServerURL 方法的参数
const objcObj = new ObjC.Object(args[2]);
log(`-[NEDNSOverHTTPSSettings setServerURL:${objcObj.toString()}]`);
},
onLeave(log, retval, state) {},
});
由于改动了脚本,所以需要先停止本次追踪,关闭App后重新打开,然后再次运行命令:frida-trace -U -m "-[NEDNSSettingsManager *]" -m "-[NEDNSOverHTTPSSettings *]" IPLocate
,在 IPLocate App 打开 DNS 设置,将得到如下的关键日志信息:
3836 ms -[NEDNSOverHTTPSSettings setServerURL:https://anyto-app-dns.irocketx.com/dns-query]
3850 ms -[NEDNSSettingsManager loadFromPreferencesWithCompletionHandler:0x283c0f420]
3866 ms -[NEDNSSettingsManager setDnsSettings:] called
3866 ms NEDNSSettings details:
3866 ms - className: NEDNSOverHTTPSSettings
3866 ms - servers: (
"47.251.43.55"
)
3866 ms - searchDomains: null
3866 ms - domainName: null
3866 ms - matchDomains: null
3866 ms - matchDomainsNoSearch: false
3877 ms | -[NEDNSOverHTTPSSettings copyWithZone:0x0]
3878 ms | | -[NEDNSOverHTTPSSettings serverURL]
3878 ms | | -[NEDNSOverHTTPSSettings setServerURL:https://anyto-app-dns.irocketx.com/dns-query]
3878 ms | | -[NEDNSOverHTTPSSettings identityReference]
3878 ms | | -[NEDNSOverHTTPSSettings setIdentityReference:0x0]
3878 ms | -[NEDNSOverHTTPSSettings .cxx_destruct]
3878 ms -[NEDNSSettingsManager setLocalizedDescription: IPLocate
3879 ms -[NEDNSSettingsManager saveToPreferencesWithCompletionHandler:0x283d46f10]
3879 ms | -[NEDNSOverHTTPSSettings checkValidityAndCollectErrors:0x283d46a30]
3879 ms | | -[NEDNSOverHTTPSSettings serverURL]
3880 ms | | -[NEDNSOverHTTPSSettings serverURL]
3880 ms -[NEDNSOverHTTPSSettings .cxx_destruct]
/* TID 0x1a03 */
3881 ms -[NEDNSOverHTTPSSettings encodeWithCoder:0x2834640c0]
3881 ms | -[NEDNSOverHTTPSSettings serverURL]
3881 ms | -[NEDNSOverHTTPSSettings identityReference]
根据上面的日志分析,可以知道 NEDNSOverHTTPSSettings
类的信息如下:
- 设置了 DNS over HTTPS (DoH) 服务器 URL 为 anyto-app-dns.irocketx.com/dns-query
- 配置了一个 DNS 服务器 IP 地址:47.251.43.55,查询得知这是一个阿里云服务器的地址。
通过上面的日志信息,我们也大概可以生成相应的代码:
- (void)configureDNSSettings {
// 创建 DNS over HTTPS 设置
NEDNSOverHTTPSSettings *dohSettings = [[NEDNSOverHTTPSSettings alloc] initWithServers:@"47.251.43.55"];
dohSettings.serverURL = [NSURL URLWithString:@"https://anyto-app-dns.irocketx.com/dns-query"];
NEDNSSettingsManager *dnsManager = NEDNSSettingsManager.sharedManager;
// 加载当前设置
[dnsManager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
if (error) {
NSLog(@"加载 DNS 设置失败: %@", error);
return;
}
dnsManager.dnsSettings = dohSettings;
dnsManager.localizedDescription = @"IPLocate";
[dnsManager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable saveError) {
if (saveError) {
NSLog(@"保存 DNS 设置失败: %@", saveError);
} else {
NSLog(@"DNS 设置已成功保存");
}
}];
}];
}
运行上面的代码后,DNS 配置会被安装到 iOS 系统,在 系统设置 > 通用 > VPN 与设备管理
中可以看到多了一个 DNS 的配置项。