release: PaopaoLocationSpoofer v1.0.0

- iOS 虚拟定位工具,基于本地 HTTP 代理 MITM 方案
- MapKit 原生地图体验,支持搜索、收藏、实时定位
- 完整的设置引导流程(证书安装、WiFi 代理配置、环境验证)
- 支持 iOS 15+,SwiftUI 构建
This commit is contained in:
xweiba
2026-08-05 15:45:24 +08:00
commit c8aba2be78
75 changed files with 7339 additions and 0 deletions
+225
View File
@@ -0,0 +1,225 @@
package main
/*
#cgo CFLAGS: -DGOOS_ios -DNDEBUG
#include <stdlib.h>
#include <stdint.h>
*/
import "C"
import (
"bytes"
"encoding/binary"
"fmt"
"math"
"net"
"net/http"
"runtime/cgo"
"strconv"
)
//export wloccore_init
func wloccore_init() {}
//export wloccore_hello
func wloccore_hello() {}
//export wloccore_version
func wloccore_version() *C.char {
return C.CString("0.1.0")
}
//export wloccore_generateca
func wloccore_generateca() (r0, r1 *C.char) {
logEvent("generateca started")
cert, key, err := generateCA()
if err != nil {
logEvent("generateca failed: " + err.Error())
return nil, nil
}
logEvent("generateca completed")
return C.CString(string(cert)), C.CString(string(key))
}
//export wloccore_startproxy
func wloccore_startproxy(certData, keyData *C.char, lat, lon C.double, enabled C.int, accuracy C.int) C.uintptr_t {
if certData == nil || keyData == nil {
return 0
}
srv, err := startProxy(
[]byte(C.GoString(certData)),
[]byte(C.GoString(keyData)),
float64(lat),
float64(lon),
enabled != 0,
int(accuracy),
)
if err != nil {
logEvent("startproxy failed: " + err.Error())
return 0
}
return C.uintptr_t(cgo.NewHandle(srv))
}
//export wloccore_stopproxy
func wloccore_stopproxy(h C.uintptr_t) C.int {
logEvent("stopproxy requested")
handle := cgo.Handle(h)
srv, ok := handle.Value().(*http.Server)
handle.Delete()
if !ok {
logEvent("stopproxy failed: invalid handle")
return 1
}
if err := stopProxy(srv); err != nil {
logEvent("stopproxy failed: " + err.Error())
return 2
}
logEvent("stopproxy completed")
return 0
}
//export wloccore_setcoords
func wloccore_setcoords(lat, lon C.double, enabled C.int, accuracy C.int) {
stateMu.Lock()
currentLat = float64(lat)
currentLon = float64(lon)
currentEnabled = enabled != 0
currentAccuracy = int(accuracy)
stateMu.Unlock()
logEvent("setcoords enabled=" + strconv.FormatBool(enabled != 0) + " lat=" + strconv.FormatFloat(float64(lat), 'f', 6, 64) + " lon=" + strconv.FormatFloat(float64(lon), 'f', 6, 64) + " accuracy=" + strconv.Itoa(int(accuracy)))
}
//export wloccore_getcoords
func wloccore_getcoords() (lat, lon C.double, enabled C.int) {
stateMu.Lock()
defer stateMu.Unlock()
lat = C.double(currentLat)
lon = C.double(currentLon)
enabled = 0
if currentEnabled {
enabled = 1
}
return lat, lon, enabled
}
//export wloccore_drainlogs
func wloccore_drainlogs() *C.char {
s := drainLogs()
if s == "" {
return nil
}
return C.CString(s)
}
//export wloccore_startcertserver
func wloccore_startcertserver(certData, keyData *C.char) C.uintptr_t {
if certData == nil || keyData == nil {
return 0
}
logEvent("start certificate server requested")
server, err := startCertificateServer([]byte(C.GoString(certData)), []byte(C.GoString(keyData)))
if err != nil {
logEvent("start certificate server failed: " + err.Error())
return 0
}
logEvent("certificate server started http=" + server.DownloadURL() + " probe=" + server.ProbeURL())
return C.uintptr_t(cgo.NewHandle(server))
}
func certificateServerForHandle(h C.uintptr_t) (*certificateServer, cgo.Handle, bool) {
if h == 0 {
return nil, 0, false
}
handle := cgo.Handle(h)
server, ok := handle.Value().(*certificateServer)
return server, handle, ok
}
//export wloccore_certserver_httpport
func wloccore_certserver_httpport(h C.uintptr_t) C.int {
server, _, ok := certificateServerForHandle(h)
if !ok {
return 0
}
return C.int(server.httpLn.Addr().(*net.TCPAddr).Port)
}
//export wloccore_certserver_httpsport
func wloccore_certserver_httpsport(h C.uintptr_t) C.int {
server, _, ok := certificateServerForHandle(h)
if !ok {
return 0
}
return C.int(server.httpsLn.Addr().(*net.TCPAddr).Port)
}
//export wloccore_certserver_leafsha256
func wloccore_certserver_leafsha256(h C.uintptr_t) *C.char {
server, _, ok := certificateServerForHandle(h)
if !ok {
return nil
}
return C.CString(server.LeafSHA256())
}
//export wloccore_stopcertserver
func wloccore_stopcertserver(h C.uintptr_t) C.int {
server, handle, ok := certificateServerForHandle(h)
if !ok {
return 1
}
handle.Delete()
if err := server.Close(); err != nil {
return 2
}
return 0
}
//export wloccore_testpatch
func wloccore_testpatch(lat, lon C.double, accuracy C.int) *C.char {
c := wlocCoords{Latitude: float64(lat), Longitude: float64(lon), Accuracy: int(accuracy)}
original := makeTestWlocBody()
patched, stats, err := patchWlocBody(original, c)
if err != nil {
return C.CString("error: " + err.Error())
}
if stats.Locations == 0 {
return C.CString("error: no location entries found")
}
if len(patched) < 10 {
return C.CString("error: patched body too short")
}
newLen := int(binary.BigEndian.Uint16(patched[8:10]))
if newLen <= 0 || 10+newLen > len(patched) {
return C.CString("error: invalid patched length")
}
newPayload := patched[10 : 10+newLen]
wantLat := append(writeTag(1, wireVarint), writeVarint(uint64(int64(math.Round(c.Latitude*1e8))))...)
wantLon := append(writeTag(2, wireVarint), writeVarint(uint64(int64(math.Round(c.Longitude*1e8))))...)
if !bytes.Contains(newPayload, wantLat) {
return C.CString("error: patched latitude mismatch")
}
if !bytes.Contains(newPayload, wantLon) {
return C.CString("error: patched longitude mismatch")
}
return C.CString(fmt.Sprintf("ok: lat=%f lon=%f wifi=%d cell=%d locations=%d", c.Latitude, c.Longitude, stats.WiFi, stats.Cell, stats.Locations))
}
//export wloccore_testrequesthex
func wloccore_testrequesthex() *C.char {
return C.CString(fmt.Sprintf("%x", makeTestWlocRequest()))
}
//export wloccore_refreshverifytoken
func wloccore_refreshverifytoken() *C.char {
return C.CString(refreshVerifyToken())
}
//export wloccore_checkverifytoken
func wloccore_checkverifytoken(token *C.char) C.int {
if checkVerifyToken(C.GoString(token)) {
return 1
}
return 0
}