用Xposed框架拦截微信、人人、QQ等LBS应用的当前位置
来源:互联网 发布:北斗星通是大数据吗 编辑:程序博客网 时间:2024/05/16 17:49
最近在参加第八届全国大学生信息安全竞赛,成功杀入决赛。本人负责核心模块的hook,hook的实现还是用开源框架Xposed。其中的一个需求就是保护用户的敏感数据:当前位置信息。前期做了很多尝试都失败了,这里换一种角度思考,顿时眼前一亮。呵呵,不在这里扯淡了,开始进入正题。
LBS应用的定位原理
经常用微信、人人的用户会发现,这一类客户端有个比较有意思的功能,就是在你发状态的时候可以添加自己的位置,可以查找“附近的人”,而且定位得相对比较准确。即使不开启手机的GPS服务,它可以定位,用WiFi它仍然可以定位,用运营商的移动网络它依然可以定位,这个功能是不是很强大?
其实,像微信这一类应用的“找朋友”功能的实现上借助的是“基于位置的服务”(Location Based Service,LBS),它是通过电信移动运营商的无线电通讯网络(如GSM网、CDMA网、WIFI热点)或外部定位方式(如GPS)获取到用户实时所在的地理位置(地理坐标),在GIS(Geographic Information System,地理音讯系统)平台的支持下,为用户提供相应服务的一种功能。
LBS是借助手机基站来实现定位。每座手机基站都有自己的独立编号,手机在开机状态下会同时接收到多座基站的信号,往常打电话时它与只其中信号最佳的一座基站建立通讯衔接,但在需求定位时就会丈量周边3个或更多的基站信号,根据三角定位法,推算出手机所处的位置。
可以把手机基站的覆盖范围想像成一个个以基站为圆心的圆,需要定位时,手机就向周边多座基站发送测量信号,并计算这些测量信号抵达基站所需要的时间,推算出手机距离基站的直线距离,再经过数学运算,手机位置坐标就可由3个基站圆的交点来确定。手机定位的准确度与基站密度、现场环境有很大联系,市区内精度范围大致在200米左右,郊区精度范围大致在1000米~2000米左右,随着技术的不时开展,基站的密度增加。在某有些场所下,手机定位的精度已能到达50米。不过,我个人还是不是很理解这种三点定位的方式,呵呵。
原理部分已经介绍完毕,下面就进入我们的正题,如何拦截你的位置,that is a question……
拦截的思路
其实思路比较简单,既然已经知道LBS定位的原理是借助手机基站来实现的。每座手机基站都有自己的独立编号,手机在开机状态下会同时接收到多座基站的信号,在定位时会就会丈量周边neighbour基站的信号,然后利用三角定位的方式,推算出手机所处的位置。所以这类应用在定位的时候,会尝试读取周围基站的信号,那么我们可以这样思考,我们可以尝试着Hook安卓操作系统中有关该基站、网络定位的部分,将其内容全部置空。然后迫使该类应用只能通过GPS来实现定位,那么,我们可以考虑向相关的GPS接口中传入一个假的经纬度的值就可以实现完美的拦截。研究一下Android操作系统中有个基站、网络、GPS定位的源码[这里推荐几个网站,一个是GrepCode,一个是AndroidXref,这两个网站提供Android操作系统各个版本的源码,很强大,为广大程序员“Read the fucking source code”提供了很大的方便,呵呵]。仔细研究一下,会发现需要拦截的东西确实不多,主要是android.net.wifi.WifiManager类的getScanResults方法、android.telephony.TelephonyManager类的getCellLocation和getNeighboringCellInfo方法、以及android.location.LocationManager类的requestLocationUpdates方法、getGpsStatus方法。
需要多说一句,开发安全方面的应用,缺少不了一款开源神器Xprivacy,这款神器可以实时查看每个应用的调用过程,甚至内部的调用函数,可以为开发者寻找解决方案提供很有价值的参考信息,减少不少阻力。下面给出核心的编码实现,主要是针对微信、人人、QQ等提供LBS服务的应用。效果就是修改自己当前的位置信息,制造一个假的地理位置信息。
编码实现
核心实现的源码如下:
package com.whu.gpshook;import de.robv.android.xposed.*;import de.robv.android.xposed.XC_MethodHook.MethodHookParam;import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;import de.robv.android.xposed.XposedBridge;import android.app.Activity;import android.location.GpsSatellite;import android.location.GpsStatus;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Binder;import android.util.Log;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.Iterator;/** * @author Li Jiansong * @date:2015-7-15 上午10:39:39 * @version : * *借助Xprivacy应用查看各个类的调用过程 *hook com.tencent.mm *android.net.wifi.WifiManager的getScanResults *android.telephony.TelephonyManager的getCellLocation和getNeighboringCellInfo方法 *android.location.LocationManager的requestLocationUpdates方法、getGpsStatus方法 * *北京经纬度:(116.449535,39.862559) * */public class GPSHooker implements IXposedHookLoadPackage{ private final String TAG = "Xposed"; private LoadPackageParam mLpp; private static Share share = new Share(); public void log(String s){ Log.d(TAG, s); XposedBridge.log(s); } //不带参数的方法拦截 private void hook_method(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) { try { XposedHelpers.findAndHookMethod(clazz, methodName, parameterTypesAndCallback); } catch (Exception e) { XposedBridge.log(e); } } //不带参数的方法拦截 private void hook_method(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) { try { XposedHelpers.findAndHookMethod(className, classLoader, methodName, parameterTypesAndCallback); } catch (Exception e) { XposedBridge.log(e); } } //带参数的方法拦截 private void hook_methods(String className, String methodName, XC_MethodHook xmh) { try { Class<?> clazz = Class.forName(className); for (Method method : clazz.getDeclaredMethods()) if (method.getName().equals(methodName) && !Modifier.isAbstract(method.getModifiers()) && Modifier.isPublic(method.getModifiers())) { XposedBridge.hookMethod(method, xmh); } } catch (Exception e) { XposedBridge.log(e); } } @Override public void handleLoadPackage(LoadPackageParam lpp) throws Throwable { // TODO Auto-generated method stub mLpp = lpp; share.reloadX(); HashMap<String, String> gpslist=share.getallX("gps"); XposedBridge.log("----------gps"+gpslist.toString()); if(gpslist.containsKey(mLpp.packageName)) return; XposedBridge.log("-----------没有保护,所以获取是假地址:"+mLpp.packageName); hook_method("android.net.wifi.WifiManager", mLpp.classLoader, "getScanResults", new XC_MethodHook(){ /** * Android提供了基于网络的定位服务和基于卫星的定位服务两种 * android.net.wifi.WifiManager的getScanResults方法 * Return the results of the latest access point scan. * @return the list of access points found in the most recent scan. */ @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // TODO Auto-generated method stub //super.afterHookedMethod(param); param.setResult(null);//return empty ap list, force apps using gps information } }); hook_method("android.telephony.TelephonyManager", mLpp.classLoader, "getCellLocation", new XC_MethodHook(){ /** * android.telephony.TelephonyManager的getCellLocation方法 * Returns the current location of the device. * Return null if current location is not available. */ @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // TODO Auto-generated method stub //super.afterHookedMethod(param); param.setResult(null);//return empty cell id list } }); hook_method("android.telephony.TelephonyManager", mLpp.classLoader, "getNeighboringCellInfo", new XC_MethodHook(){ /** * android.telephony.TelephonyManager类的getNeighboringCellInfo方法 * Returns the neighboring cell information of the device. */ @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // TODO Auto-generated method stub //super.afterHookedMethod(param); param.setResult(null);//// return empty neighboring cell info list } }); hook_methods("android.location.LocationManager", "requestLocationUpdates", new XC_MethodHook() { /** * android.location.LocationManager类的requestLocationUpdates方法 * 其参数有4个: * String provider, long minTime, float minDistance,LocationListener listener * Register for location updates using the named provider, and a pending intent */ @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { if (param.args.length == 4 && (param.args[0] instanceof String)) { //位置监听器,当位置改变时会触发onLocationChanged方法 LocationListener ll = (LocationListener)param.args[3]; Class<?> clazz = LocationListener.class; Method m = null; for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals("onLocationChanged")) { m = method; break; } } try { if (m != null) { // mSettings.reload(); Object[] args = new Object[1]; Location l = new Location(LocationManager.GPS_PROVIDER);// double la = Double.parseDouble(mSettings.getString("latitude", "-10001"));// double lo = Double.parseDouble(mSettings.getString("longitude","-10001")); double la=39.862559;//帝都的经纬度 double lo=116.449535; l.setLatitude(la); l.setLongitude(lo); args[0] = l; //invoke onLocationChanged directly to pass location infomation m.invoke(ll, args); XposedBridge.log("fake location: " + la + ", " + lo); } } catch (Exception e) { XposedBridge.log(e); } } } }); hook_methods("android.location.LocationManager", "getGpsStatus", new XC_MethodHook(){ /** * android.location.LocationManager类的getGpsStatus方法 * 其参数只有1个:GpsStatus status * Retrieves information about the current status of the GPS engine. * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged} * callback to ensure that the data is copied atomically. * */ @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { GpsStatus gss = (GpsStatus)param.getResult(); if (gss == null) return; Class<?> clazz = GpsStatus.class; Method m = null; for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals("setStatus")) { if (method.getParameterTypes().length > 1) { m = method; break; } } } //access the private setStatus function of GpsStatus m.setAccessible(true); //make the apps belive GPS works fine now int svCount = 5; int[] prns = {1, 2, 3, 4, 5}; float[] snrs = {0, 0, 0, 0, 0}; float[] elevations = {0, 0, 0, 0, 0}; float[] azimuths = {0, 0, 0, 0, 0}; int ephemerisMask = 0x1f; int almanacMask = 0x1f; //5 satellites are fixed int usedInFixMask = 0x1f; try { if (m != null) { m.invoke(gss,svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask); param.setResult(gss); } } catch (Exception e) { XposedBridge.log(e); } } }); }}
效果演示
本人的真实地理位置信息是在湖北武汉:
打开微信客户端,查看自己当前位置,可以发现显示的是帝都的位置:
打开人人,查找附近的人,也是在帝都:
工程源码
下载
- 用Xposed框架拦截微信、人人、QQ等LBS应用的当前位置
- JS分享到微博,qq空间,人人,微信等
- 百度代码分享到QQ、微信、人人网等
- 用Xposed框架拦截Android操作系统的短信接收
- 用Xposed框架拦截Android操作系统的短信接收
- 用Xposed框架抓取微信朋友圈数据
- 用Xposed框架抓取微信朋友圈数据
- 用Xposed框架抓取微信朋友圈数据
- xposed框架 微信群发源码
- springmvc项目里第三方登录(百度,QQ,微信,人人,新浪微博等)
- jsp页面分享到QQ空间、微信、微博、人人网等
- jsp页面分享到QQ空间、微信、微博、人人网等
- 使用Xposed拦截应用通知的一直简单实现
- Android 打开外部应用(微博/微信/QQ等)
- Ubuntu安装QQ 微信等手机应用
- Android App打开手机QQ、微信等应用
- 利用Xposed框架修改微信运动计步
- 基于xposed的短信拦截
- 如何解决 “fatal error C1083: ”无法打开包括文件
- Java通过SMS短信平台实现发短信功能
- LINUX select socket编程 TCP
- mapreduce数据倾向
- 几个下载kindle电子书的资源网站
- 用Xposed框架拦截微信、人人、QQ等LBS应用的当前位置
- 股票学习05(开盘的几种状态)
- JBoss调优(二)数据库连接池调优
- Myeclipse集成Maven(图文说明)
- php实现简单多进程的方法
- OID-----利用SNMP获取、走访节点值【程序代码+分析】
- linux socket 阻塞式 TCP
- JBoss调优(三)EJB连接池调优
- 观察者模式