改机 - 从源码着手任意修改GPS地理位置

需求:随意修改定位

android在改机过程中,经常会遇到随意修改位置GPS的需求。

修改GPS的方式有很多种:

xposed hook

MockLocation

修改源码

以上三种方式都能修改gps随意修改gps坐标,各有优缺点:xposed隐藏不好,容易被发现;MockLocation容易在开发者模式和gps provider被识别;改源码,编译麻烦,而且不一定有源码;前两种方式具有普适性,改源码费时费力,局限性比较强;

秉承明知山有虎,偏向虎上行的心态,尝试阅读以下android的源码,并且修改gps部分的代码;

具体原理:切断hal层和framework之间的通讯,模仿硬件向framework通知硬件信息

样例:android 8.0

1. gps jni callbackstruct GnssCallback : public IGnssCallback {

Return gnssLocationCb(

const android::hardware::gnss::V1_0::GnssLocation& location) override; // gps位置变化回调函数

Return gnssStatusCb(const IGnssCallback::GnssStatusValue status) override; // gps状态变化回调函数

Return gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override; // 卫星状态变化回调函数

Return gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;

Return gnssSetCapabilitesCb(uint32_t capabilities) override;

Return gnssAcquireWakelockCb() override;

Return gnssReleaseWakelockCb() override;

Return gnssRequestTimeCb() override;

Return gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;

static GnssSvInfo sGnssSvList[static_cast(

android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];

static size_t sGnssSvListSize;

static const char* sNmeaString;

static size_t sNmeaStringLength;

};

// 省略......

Return GnssCallback::gnssLocationCbImpl(const T& location) {

JNIEnv* env = getJniEnv();

jobject jLocation = translateGnssLocation(env, location);

env->CallVoidMethod(mCallbacksObj,

method_reportLocation, // frameworks

boolToJbool(hasLatLong(location)),

jLocation);

checkAndClearExceptionFromCallback(env, __FUNCTION__);

env->DeleteLocalRef(jLocation);

return Void();

}

// 省略......

method_reportLocation = env->GetMethodID(clazz, "reportLocation",

"(ZLandroid/location/Location;)V");

GnssCallback的作用就是在gps模块位置、状态、精度等信息变化后,通知上层应用的回调函数类。

2. framework

可以发现,在gps硬件模块拿到新的位置时,通知framework调用java的函数是reportLocation, 源码如下:

/*

* @hasLatLong: 地理位置是否合法

* @loction: 地理位置

*/

private void reportLocation(boolean hasLatLong, Location location) {

if (location.hasSpeed()) {

mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;

}

if (mItarSpeedLimitExceeded) {

Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +

" GPS/GNSS Navigation output blocked.");

mGnssMetrics.logReceivedLocationStatus(false);

return;

}

if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());

synchronized (mLocation) {

mLocation = location;

// It would be nice to push the elapsed real-time timestamp

// further down the stack, but this is still useful

mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());

mLocation.setExtras(mLocationExtras);

try {

mILocationManager.reportLocation(mLocation, false);

} catch (RemoteException e) {

Log.e(TAG, "RemoteException calling reportLocation");

}

}

mGnssMetrics.logReceivedLocationStatus(hasLatLong);

if (hasLatLong) {

if (location.hasAccuracy()) {

mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());

}

if (mTimeToFirstFix > 0) {

int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);

mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);

}

}

mLastFixTime = SystemClock.elapsedRealtime();

// report time to first fix

if (mTimeToFirstFix == 0 && hasLatLong) {

mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime);

if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);

mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);

// notify status listeners

mListenerHelper.onFirstFix(mTimeToFirstFix);

}

if (mSingleShot) {

stopNavigating();

}

if (mStarted && mStatus != LocationProvider.AVAILABLE) {

// we want to time out if we do not receive a fix

// within the time out and we are requesting infrequent fixes

if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {

mAlarmManager.cancel(mTimeoutIntent);

}

// send an intent to notify that the GPS is receiving fixes.

Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);

intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);

mContext.sendBroadcastAsUser(intent, UserHandle.ALL);

updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);

}

if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&

mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {

if (DEBUG) Log.d(TAG, "got fix, hibernating");

hibernate();

}

}

自此,刨除hal层,android系统就获取到了一个地理位置。原理了解后,就可以动手修改源码了。

3. 切断hal层调用

GnssLocationProvider.cpp

#include

// ....... 省略

Return GnssCallback::gnssLocationCbImpl(const T& location) {

// 定义一个系统开关,可以自由控制

char property[PROP_VALUE_MAX];

int len = __system_property_get("gps.location.custom", property);

if(len > 0) {

if(strcmp(property, "1") == 0) return Void();

}

// ...... 省略

}

4. 在framework中添加一个public函数

LocationManager.java

// ...... 省略

public void reportCustomLocation(Location location) {

mService.reportLocation(true, location);

}

5. 编译rommake update-api # 在LocationManager中添加了新的接口

make -j32 # 炫耀一下我32核的的机器

5. 在APK中使用

MainActivity.java

// ...... 省略

Button btn = findViewById(R.id.test_btn);

btn.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

try {

Location l = new Location("gps");

l.setLatitude(41.055962);

l.setLongitude(110.307711);

l.setAccuracy(2.0f);

l.setTime(System.currentTimeMillis());

l.setElapsedRealtimeNanos(System.currentTimeMillis());

l.setAccuracy(1.0f);

locationManager.reportCustomLocation(l);

Location lo = locationManager.getLastKnownLocation(provider);

Log.d(TAG, lo.toString());

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

最后于 2020-6-29 11:04

被neocanable编辑

,原因: markdown 好像不太好用

android 修改gps坐标,[原创] 改机 - 从源码着手任意修改GPS地理位置相关推荐

  1. java 修改gps,改机 - 从源码着手任意修改GPS地理位置

    改机 - 从源码着手任意修改GPS地理位置 需求:随意修改定位 android在改机过程中,经常会遇到随意修改位置GPS的需求. 修改GPS的方式有很多种: xposed hook MockLocat ...

  2. 不翻qiang搞定Android Studio Google库加载不下来的问题 打包生成apk android studio 3.2打灰机程序源码带详细注释

    1.Google库加载不下来的问题 其实我们可以给dl.google.com设置个代理,然后库都能正常加载下来了.步骤如下: 打开站长工具网站,http://ping.chinaz.com/dl.go ...

  3. 【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )

    文章目录 一. libwebp 源码下载 二. libwebp 源码编译脚本修改 三. libwebp 函数库编译 四.参考资料 一. libwebp 源码下载 Google 提供了一系列的 WebP ...

  4. Android源码中添加 修改应用

    第一部分:添加一个新的应用 1. 在和系统相同版本的SDK目录下开发自己的android应用 2. 把开发的android工程放到源码的packages/apps/目录下 3. 在工程目录下添加And ...

  5. android 随手记 170多个示例demo源码

    下载地址:http://pan.baidu.com/s/101PEN 2012-10-1513:03   2,098,836     AdXmpp(Openfire+asmack+spark) .zi ...

  6. 戴眼镜检测和识别3:Android实现戴眼镜检测和识别(含源码,可实时检测)

    Android实现戴眼镜检测和识别(含源码,可实时检测) 目录 Android实现戴眼镜检测和识别(含源码,可实时检测) 1.戴眼镜检测和识别方法 2.戴眼镜人脸检测 3.戴眼镜识别模型训练 4.戴眼 ...

  7. Android图片爬虫,看妹纸神器项目源码,ListView单张图片查看

    Android图片爬虫,看妹纸神器项目源码 刚自学完安卓,国庆7七天花了6天纯手写入门级app,从集成图片爬虫到整个项目结束真是一步一个坑. 整个项目没有用框架,都是手写纯属练手,项目中主要用到的技术 ...

  8. (仿微信Android)IM聊天+抢红包+直播+朋友圈源码发布了

    (仿微信Android)IM聊天+抢红包+直播+朋友圈源码发布了 功能概览: IM聊天 单聊/群聊/聊天室--基于环信sdk 红包功能: 1.一对一红包 2.群红包(抢红包.答题红包.专属红包) 3. ...

  9. 神器如 dnSpy,无需源码也能修改 .NET 程序

    dnSpy 是 0xd4d 开发的 .NET 程序调试神器. 说它是神器真的毫不为过!它能在完全没有源码的情况下即时调试程序,甚至还能修改程序!本文讲向大家介绍如何使用 dnSpy 修改 .NET 程 ...

  10. 【Android项目】本地FM收音机开发及源码简析

    [Android项目]本地FM收音机开发及源码简析 目录 1.概述 2.收音机的基本原理 3.收音机其他信息 RDS功能 4.Android开发FM收音机源码解析 5.App层如何设计本地FM应用 6 ...

最新文章

  1. 阿里商业白皮书:每个企业都要变成一个数据公司
  2. VSFTP之不能登录
  3. 3.4 matlab用for语句实现循环结构
  4. android o 小米note 3,小米 Note 3 MIUI 10 安卓 8.0 内测开启
  5. C++实现AOE网中的关键路径算法(邻接表存储)
  6. 程序设计与算法----分治之归并排序
  7. javaScripct入门教程
  8. Silverlight3.0教程下载
  9. iphone上开发即时聊天工具
  10. 半部秘籍--分类、回归、集成与无监督
  11. 秀米排版 × ModStart,提升富文本排版效率
  12. swing 绝对布局 窗口事件 鼠标事件 键盘事件 上传头像流程
  13. 什么是软件维护?在软件已经交付使用后,为了改正错误或满足新需求而修改软件的过程。它有哪几种类型?
  14. npm(了解)+Babel转码器+模块化+webpack打包
  15. AGV调度:路径规划
  16. 情感识别相关数据集总结
  17. 前端知识总结之基础知识
  18. OS-实现一个RR调度算法
  19. Unity使用AssetDatabase.CreateAsset报错:Couldn't create asset file!
  20. IT类电子图书下载站点合集

热门文章

  1. dnf mysql密码多少_CentOS7 使用 dnf 安装 mysql
  2. MonkeyTest
  3. COGS 2507. 零食店
  4. 表上作业法-运输问题(Java)
  5. 被封杀4年的看片神器终于解禁了,要跟百度网盘抢生意?
  6. ajaxSubmit异步提交
  7. 解决ajaxSubmit无法传递自动回填和下拉框的数据
  8. echarts实现平面3D柱状图
  9. bt种子增加服务器,bt发布-BT种子怎么发布?服务器地址、发布者网址应怎么填写? 爱问知识人...
  10. vite:15个插件推荐