由于 iOS 系统的网络请求走的是系统代理,所以我们需要设置 iOS 系统的代理服务器来实现全局代理。
- 首先,我们需要导入 MobileDevice.framework 和 libimobiledevice.dylib 两个库,用来连接 iOS 设备并执行操作。
/*
#cgo LDFLAGS: -framework MobileDevice -limobiledevice
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "libimobiledevice/libimobiledevice.h"
#include "libimobiledevice/lockdown.h"
void print_error(char *msg, int code);
void print_lockdownd_error(const char *msg, lockdownd_error_t err);
void print_error(char *msg, int code) {
fprintf(stderr, "%s failed: %d\n", msg, code);
}
void print_lockdownd_error(const char *msg, lockdownd_error_t err) {
fprintf(stderr, "%s: %d\n", msg, err);
}
*/
import "C"
- 连接 iOS 设备
func Connect() (C.lockdownd_client_t, error) {
var client C.lockdownd_client_t
var device C.idevice_t
var err C.int
// 初始化 idevice
err = C.idevice_new(&device, nil)
if err != C.IDEVICE_E_SUCCESS {
return nil, fmt.Errorf("Failed to create device, error %d", err)
}
// 初始化 client
err = C.lockdownd_client_new_with_handshake(device, &client, "golang")
if err != C.LOCKDOWN_E_SUCCESS {
C.idevice_free(device)
return nil, fmt.Errorf("Failed to create client, error %d", err)
}
return client, nil
}
- 设置代理服务器
func SetProxyServer(client C.lockdownd_client_t, proxy string) error {
var err C.lockdownd_error_t
var dict C.plist_t
// 创建 plist
dict = C.plist_new_dict()
if dict == nil {
return errors.New("Failed to create plist")
}
// 添加本地化语言信息
err = C.lockdownd_set_value(client, nil, "com.apple.international", dict)
if err != C.LOCKDOWN_E_SUCCESS {
C.plist_free(dict)
return fmt.Errorf("Failed to set com.apple.international, error %d", err)
}
// 添加全局代理信息
var proxyDict C.plist_t
proxyDict = C.plist_new_dict()
if proxyDict == nil {
C.plist_free(dict)
return errors.New("Failed to create proxyDict")
}
C.plist_dict_insert_item(proxyDict, "HTTPEnable", C.plist_new_bool(1))
C.plist_dict_insert_item(proxyDict, "HTTPSEnable", C.plist_new_bool(1))
C.plist_dict_insert_item(proxyDict, "HTTPProxy", C.plist_new_string(C.CString(proxy)))
C.plist_dict_insert_item(proxyDict, "HTTPSPort", C.plist_new_int(8888))
C.plist_dict_insert_item(proxyDict, "HTTPPort", C.plist_new_int(8888))
C.plist_dict_insert_item(proxyDict, "ProxyAutoConfigEnable", C.plist_new_bool(0))
C.plist_dict_insert_item(proxyDict, "ProxyAutoConfigURLString", C.plist_new_string(C.CString("")))
C.plist_dict_insert_item(proxyDict, "ExcludeSimpleHostnames", C.plist_new_bool(0))
C.plist_dict_insert_item(proxyDict, "FTPEnable", C.plist_new_bool(0))
C.plist_dict_insert_item(proxyDict, "GopherEnable", C.plist_new_bool(0))
C.plist_dict_insert_item(dict, "HTTPProxy", proxyDict)
C.plist_dict_insert_item(dict, "HTTPSEnable", C.plist_new_bool(1))
C.plist_dict_insert_item(dict, "HTTPEnable", C.plist_new_bool(1))
C.plist_dict_insert_item(dict, "HTTPSProxy", proxyDict)
// 发送 plist 到设备
err = C.lockdownd_set_value(client, nil, "com.apple.network.proxy", dict)
if err != C.LOCKDOWN_E_SUCCESS {
C.plist_free(dict)
return fmt.Errorf("Failed to set com.apple.network.proxy, error %d", err)
}
C.plist_free(dict)
return nil
}
- 调用函数设置代理服务器
func main() {
client, err := Connect()
if err != nil {
log.Fatal(err)
}
defer C.idevice_free(client.device)
defer C.lockdownd_client_free(client)
err = SetProxyServer(client, "127.0.0.1:8888")
if err != nil {
log.Fatal(err)
}
}