修改 iOS 应用的 GPS 定位

背景

Pokemon GO 不仅锁 IP,还锁 GPS,所以想要在国内玩不仅要翻墙还要伪造 GPS

原理

基本原理就是对 APP 里关于定位的函数做一个钩子,修改返回的 GPS 数值。参考 这里

步骤

  1. 首先要自己写一个 HOOK 的动态库,这里 有一个现成的。编译生成 LocationFaker.dylib,然后再 unzip 解压已经去壳的 Pokémon GO.ipa

    1
    2
    unzip Pokémon\\ GO.ipa
    cd Payload
    然后把 yololibLocationFaker.dylib 放到 Payload 后执行:
    1
    2
    ./yololib pokemongo.app/pokemongo LocationFaker.dylib
    cp LocationFaker.dylib pokemongo.app/
    可以通过如下命令查看是否已经注入成功:
    1
    2
    3
    # otool 类似 nm 工具
    → otool -l pokemongo.app/pokemongo grep aker
    name @executable\_path/LocationFaker.dylib (offset 24)

  2. 然后用 iOS App Signerpokemongo.app 重新签名: file

  3. 签名后会在 Payload 目录下生成 pokemongo.ipa 文件,然后用数据线链接电脑和手机,用下面的命令将ipa安装到手机上:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    → ideviceinstaller -i pokemongo.ipa
    WARNING: could not locate iTunesMetadata.plist in archive!
    Copying 'pokemongo.ipa' to device... DONE.
    Installing 'com.blockabc.test'
    - CreatingStagingDirectory (5%)
    - ExtractingPackage (15%)
    - InspectingPackage (20%)
    - TakingInstallLock (20%)
    - PreflightingApplication (30%)
    - Error occurred: DeviceNotSupportedByThinning
    发现报DeviceNotSupportedByThinning错,原因是该应用是我在越狱的 iPhone 6 Plus 上下载砸壳的,只支持 iPhone 6 Plus,于是手动修改Info.plist
    1
    vi pokemongo.app/Info.plist
    这里 找到 iPhone X 的设备型号对应名称,并添加到 UISupportedDevices 下面: file 然后继续尝试安装到手机上:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    → ideviceinstaller -i pokemongo.ipa
    WARNING: could not locate iTunesMetadata.plist in archive!
    Copying 'pokemongo.ipa' to device... DONE.
    Installing 'com.blockabc.deers'
    - CreatingStagingDirectory (5%)
    - ExtractingPackage (15%)
    - InspectingPackage (20%)
    - TakingInstallLock (20%)
    - PreflightingApplication (30%)
    - InstallingEmbeddedProfile (30%)
    - VerifyingApplication (40%)
    - Error occurred: WatchKitAppBundleIDNotPrefixed
    发现又报错应用里的 Watch 模块签名错误,因为 Pokemon 类似 WeChat 是多 target 的 APP,所以其中的 Watch 项目是用的不同的签名,索性直接删掉 Watch 目录:
    1
    rm -rf pokemongo.app/Watch
    然后再重新走一遍第 2 步的签名流程后,再次尝试安装到手机上,终于成功:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    → ideviceinstaller -i pokemongo.ipa
    WARNING: could not locate iTunesMetadata.plist in archive!
    Copying 'pokemongo.ipa' to device... DONE.
    Installing 'com.blockabc.deers'
    - CreatingStagingDirectory (5%)
    - ExtractingPackage (15%)
    - InspectingPackage (20%)
    - TakingInstallLock (20%)
    - PreflightingApplication (30%)
    - InstallingEmbeddedProfile (30%)
    - VerifyingApplication (40%)
    - CreatingContainer (50%)
    - InstallingApplication (60%)
    - PostflightingApplication (70%)
    - SandboxingApplication (80%)
    - GeneratingApplicationMap (90%)
    - Complete

后记

可惜帐号登录时一直报错:Unable to authenticate。起初以为是帐号被封,后来用新申请的帐号依旧报这个错。

然后怀疑是动态库写错了,或者没有生效。然后为了验证动态库是否注入成功,用同样的方法注入到微信中,然后发现其实是生效并成功了的: file

再次猜测可能是因为在 iPhone 6 Plus 上砸的壳,在 iPhone X 上用不了,于是将修改了定位的 pokemon 也安装到 iPhone 6 Plus 上,结果依旧同样的问题登录不了。


试图搞懂原因,需要抓包看下请求交互,抓包环境比较特殊,既要翻墙又要 https 代理。于是想了一个方案:本地设 charles 代理连电脑,然后 charles 转发请求到 shadowsockets 连 VPS。详细步骤见 这里,需要注意下 External Proxy Setting: file

唯一存疑的是在向 pokemon 官方一个站点发起 CONNECT 请求时因为超时才最终导致了 Unable to authenticate 错误

然而无论本机还是 VPS 直接 telnet 该站点都是可以通的,所以暂时还不知道什么原因导致的超时。关于 CONNECT 是什么需要看下 这篇文章