mirror of
https://github.com/xweiba/location-spoofer.git
synced 2026-09-22 06:40:44 +08:00
- iOS 虚拟定位工具,基于本地 HTTP 代理 MITM 方案 - MapKit 原生地图体验,支持搜索、收藏、实时定位 - 完整的设置引导流程(证书安装、WiFi 代理配置、环境验证) - 支持 iOS 15+,SwiftUI 构建
127 lines
4.8 KiB
Swift
127 lines
4.8 KiB
Swift
import Foundation
|
|
import Darwin
|
|
|
|
struct CertificateAuthority: Equatable {
|
|
let certPEM: String
|
|
let keyPEM: String
|
|
}
|
|
|
|
enum CoreBridgeError: LocalizedError {
|
|
case generationFailed
|
|
case serverStartFailed
|
|
|
|
var errorDescription: String? {
|
|
switch self {
|
|
case .generationFailed: return "无法生成本地证书"
|
|
case .serverStartFailed: return "无法启动本地证书服务"
|
|
}
|
|
}
|
|
}
|
|
|
|
enum CoreBridge {
|
|
static func generateCertificateAuthority() throws -> CertificateAuthority {
|
|
RuntimeLogger.info("APP", "Core.CA", "调用 Go Core 生成 CA")
|
|
let result = wloccore_generateca()
|
|
guard let certPointer = result.r0, let keyPointer = result.r1 else {
|
|
flushLogs(category: "CA")
|
|
throw CoreBridgeError.generationFailed
|
|
}
|
|
defer { free(certPointer); free(keyPointer) }
|
|
RuntimeLogger.info("APP", "Core.CA", "Go Core CA 生成成功")
|
|
flushLogs(category: "CA")
|
|
return CertificateAuthority(certPEM: String(cString: certPointer), keyPEM: String(cString: keyPointer))
|
|
}
|
|
|
|
/// 调用 Go Core 做一次模拟 wloc 响应改写测试,验证定位数据是否会被改成目标坐标。
|
|
static func testWlocPatch(lat: Double, lon: Double, accuracy: Int) -> String {
|
|
guard let ptr = wloccore_testpatch(CDouble(lat), CDouble(lon), CInt(accuracy)) else {
|
|
return "error: null result"
|
|
}
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
|
|
/// 构造接近真实设备格式的 wloc 请求体(多个 WiFi AP + 蜂窝基站)。
|
|
static func testWlocRequestData() -> Data {
|
|
guard let ptr = wloccore_testrequesthex() else { return Data([0x0a, 0x02, 0x08, 0x01]) }
|
|
defer { free(ptr) }
|
|
let hex = String(cString: ptr)
|
|
var data = Data()
|
|
var idx = hex.startIndex
|
|
while idx < hex.endIndex {
|
|
let end = hex.index(idx, offsetBy: 2, limitedBy: hex.endIndex) ?? hex.endIndex
|
|
if let b = UInt8(hex[idx..<end], radix: 16) { data.append(b) }
|
|
idx = end
|
|
}
|
|
return data
|
|
}
|
|
|
|
static func flushLogs(category: String) {
|
|
guard let pointer = wloccore_drainlogs() else { return }
|
|
defer { free(pointer) }
|
|
String(cString: pointer).split(separator: "\n").forEach {
|
|
RuntimeLogger.info("CORE", category, String($0))
|
|
}
|
|
}
|
|
|
|
static func refreshVerifyToken() -> String {
|
|
guard let ptr = wloccore_refreshverifytoken() else { return "" }
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
}
|
|
|
|
final class LocalCertificateServer {
|
|
private var handle: UInt = 0
|
|
private(set) var downloadURL: URL?
|
|
private(set) var probeURL: URL?
|
|
private(set) var leafHash = ""
|
|
|
|
deinit { stop() }
|
|
|
|
func start(authority: CertificateAuthority) throws {
|
|
if handle != 0 {
|
|
RuntimeLogger.debug("APP", "Certificate.server", "本地证书服务已在运行")
|
|
return
|
|
}
|
|
RuntimeLogger.info("APP", "Certificate.server", "调用 Go Core 启动本地证书服务")
|
|
let newHandle: UInt = authority.certPEM.withCString { certPointer in
|
|
authority.keyPEM.withCString { keyPointer in
|
|
UInt(wloccore_startcertserver(UnsafeMutablePointer(mutating: certPointer), UnsafeMutablePointer(mutating: keyPointer)))
|
|
}
|
|
}
|
|
guard newHandle != 0 else {
|
|
CoreBridge.flushLogs(category: "CertificateServer")
|
|
throw CoreBridgeError.serverStartFailed
|
|
}
|
|
let httpPort = Int(wloccore_certserver_httpport(newHandle))
|
|
let httpsPort = Int(wloccore_certserver_httpsport(newHandle))
|
|
guard httpPort > 0, httpsPort > 0, let hashPointer = wloccore_certserver_leafsha256(newHandle) else {
|
|
_ = wloccore_stopcertserver(newHandle)
|
|
throw CoreBridgeError.serverStartFailed
|
|
}
|
|
defer { free(hashPointer) }
|
|
handle = newHandle
|
|
downloadURL = URL(string: "http://127.0.0.1:\(httpPort)/ca.cer")
|
|
probeURL = URL(string: "https://127.0.0.1:\(httpsPort)/health")
|
|
leafHash = String(cString: hashPointer)
|
|
RuntimeLogger.info("APP", "Certificate.server", "本地证书服务启动成功", details: [
|
|
"httpPort": String(httpPort),
|
|
"httpsPort": String(httpsPort),
|
|
"leafHash": leafHash
|
|
])
|
|
CoreBridge.flushLogs(category: "CertificateServer")
|
|
}
|
|
|
|
func stop() {
|
|
guard handle != 0 else { return }
|
|
let result = wloccore_stopcertserver(handle)
|
|
RuntimeLogger.info("APP", "Certificate.server", "停止本地证书服务", details: ["result": String(result)])
|
|
CoreBridge.flushLogs(category: "CertificateServer")
|
|
handle = 0
|
|
downloadURL = nil
|
|
probeURL = nil
|
|
leafHash = ""
|
|
}
|
|
}
|