Android定位偽造-實戰足不出戶暢玩pokemon go
本文旨在技術探討故本文不提供工具,正常玩家請勿模仿,游戲中虛擬位置有封號風險
0x00 安卓定位方式歸類
要偽造定位首先要摸清定位到底是如何實現的,首先從廣義上來區分安卓的定位方式實際上就gps和network兩種。但是network網絡定位過于抽象,到底是移動網絡基站定位,還是寬帶ip定位還是wifi定位了,于是我又做了如下細分。
細分定位方式如下:
- GPS定位:通過衛星定位,精度高耗電也高定位速度慢。但是需要搜索到三顆星以上才可以定位,室內的大多無法使用。
- 網絡定位:多指wifi/寬帶ip定位,其實也包括移動網絡也就是第三點。
- 基站定位:通過運營商的基站三角定位,定位精度低功耗低。
-
混合定位:結合上面多種方式,AGPS定位。
-
第三方SDK: 百度地圖/高德地圖/谷歌地圖,本質上還是使用上面4種方式。
通常位置信息權重排序 :gps > wifi > 基站 ,實際上還和信號強度,以及軟件算法等多種因素有關。
功耗排序 : gps > 基站 > wifi
0x01位置欺騙可行方案
針對上述定位方式可以假想如下方案進行欺騙。
1.硬件放射gps信號欺騙。 成本較高,需要諸如hackrf這樣的硬件設備。我工位在窗戶邊真實gps信號十分強,所以我偽造的信號就像對弱了導致整個方案成功率變低。具體操作可以參考下文。
http://drops.wooyun.org/tips/10580
2.android位置模擬。這種方式需要打開gps定位并且進入開發者模式開啟位置模擬,這個方案較易操作。但是很多app對這種行為作了檢測,例如pokemon go在檢測到 位置模擬 后便會提示 Failed to detect location
3.hook系統調用,篡改location返回值,需要root權限。這個是我最終采用到方案。這個方案的優點是比較穩定,被檢測到異常的概率比較小。既可以正常人肉跑動玩游戲,也可以偷懶利用pc上的插件點擊鼠標滿地圖抓小精靈。
07-14 12:30:40.573 2657-3291/? D/pokemongoH﹕ location = -35.19044856,149.0560237 07-14 12:30:40.573 2657-3291/? D/pokemongoH﹕ getLatitude Result : -35.19044856 07-14 12:30:40.583 2657-3291/? D/pokemongoH﹕ getLongitude Result : 149.0560237
4.模擬器提供位置模擬功能,ARM模擬器運行緩慢,x86模擬機雖然快但是兼容性差。命令行指定坐標 :
telnet localhost 5554 geo fix <longitude value> <latitude value>```
這類操作因為需要在模擬器中進行,所以體驗和兼容性要差很多。
5.篡改軟件上傳的ip/wifi信息,實際操作難度較大。
0x02分析pokemon go APP
- 在android平臺要玩此游戲需要 google play 框架,如果你手機是國行的肯定不會帶此框架,必須root后才能安裝。我所使用的nexus 5是自帶的。
- 既然要使用google play的服務那在gfw的保護就必須得自備梯子了,我選擇的是showsocks,vps在香港。
- 安裝app, https://apkpure.com/pok%C3%A9mon-go/com.nianticlabs.pokemongo .
- 任天堂是一直不太care國服的,這次迫于服務器宕機的壓力Pokemon go更是對大陸地區進行鎖區操作。當你千辛萬苦完成上述兩個步驟后進行進入游戲會發現地圖上沒有任何小精靈和補給站以及道館。所以這個時候就需要使用到本文講解的技術 定位偽造 了。
先觀察下網上公開的Pokemon go鎖區圖,從下圖可以看出東三省和新疆部分地區是不在鎖區范圍可以正常游戲的。為什么這樣,我個人猜測有這樣兩個原因
- 這個長方形的鎖區范圍從開發角度易于實現
- 游戲運營初期策略較為寬松寧放過不誤殺。
為了測試Pokemon Go的定位方式,我做了如下操作。
1.設置系統使用 wlan和移動網絡定位 會提示 GPS signal not found ,當設置 僅gps定位 和 gps/wlan/移動網絡確定位置 的時候可以正常游戲
2.監控 location provider
07-14 12:30:22.573 2657-2657/? D/pokemongoH﹕ HOOK IT 07-14 12:30:40.553 2657-3291/? D/pokemongoH﹕ location provider is : gps 07-14 12:30:40.563 2657-3291/? D/pokemongoH﹕ location provider is : network
3.逆向app,在逆向過程中未發現調用getCellLocation/getBSSID方法,但是發現其有調用getLastKnownLocation。下文會描述這些方法的用處。
結論:pokemon go采用混合定位其中gps定位為主,network定位為輔且gps定位可以獨立工作network定位無法獨立工作。
0x03偽造gps插件開發
上文已經簡單分析了安卓定位的方式以及pokemon go采用的定位方案,在hook系統api前腰先對這些api簡單了解下。
需要關注的api:類以及方法如下
Class: android.location.Location Method: public double getLatitude () //獲取緯度,北緯為正數,南緯為負數。 public double getLongitude () //獲取經度 Class: android.location.LocationManager Method: public Location getLastLocation () public Location getLastKnownLocation (String provider) //通過provider獲取location Class: android.telephony.TelephonyManager Method: public CellLocation getCellLocation () //通過GSM獲取location android.net.wifi.WifiInfo public String getBSSID () //獲取wifi的bssid
通過分析定位代碼和android api可以發現不管采用何種定位方式,歸根到底還是要從loaction中取出經緯度,也就是你的位置信息。所以這個類中的getLatitude/getLongitude方法就是hook的關鍵點。
現在已知開服區域:美國/澳大利亞/英國/日本。我選擇將自己的坐標偏移到澳大利亞的堪培拉。
其實網上很多偽造位置的軟件,但是網上的軟件有三處不足:
1.可能有后門或者廣告
2.可能出現開飛機的現象(游戲中短時間大范圍變化坐標)后被封號。
3.可diy性差。
如果坐標寫死,那么游戲依然是不能正常玩的,所以我是做了個偏移,就相當于另一個地方有個影子同步在動一樣。偏移量通過一個文件來計算,文件寫入的是需要偏移到的地址,這樣也方便與pc上的adb交互。如果炎炎夏日不想離開空調又想抓小精靈就只能再做個pc端控制偏移的插件來。
電腦控制端控制插件四個按鈕.
addlon: longitude + 0.0005
sublon: longitude - 0.0005
addlat: latitude + 0.0005
sunlat: latitude - 0.0005
最后效果如下。PS:平時抓精靈多建議關掉AR,這樣更流暢抓的成功率高一些。
待開發功能:
- 多角度移動,如果有多點觸控其實沒必要。
- 自動跑步,檢測到小精靈的時候停下 (自動加減坐標,監控到震動即停止跑步)
- pc端地圖同步,人物坐標同步。
- ...
0x04 問我ios怎么辦
如果是ios用戶看到這里已是十分不易,所以附送一個ios pokemon go類似玩法:
https://github.com/kahopoon/Pokemon-Go-Controller