首页
论坛
课程
招聘
[原创] 改机 - 从源码着手任意修改GPS地理位置
2020-6-28 13:18 6872

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

2020-6-28 13:18
6872

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

需求:随意修改定位

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

 

修改GPS的方式有很多种:

  1. xposed hook
  2. MockLocation
  3. 修改源码

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

 

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

 

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

 

样例:android 8.0

1. gps jni callback
struct GnssCallback : public IGnssCallback {
    Return<void> gnssLocationCb(
          const android::hardware::gnss::V1_0::GnssLocation& location) override; // gps位置变化回调函数
    Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override; // gps状态变化回调函数
    Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override; // 卫星状态变化回调函数
    Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
    Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
    Return<void> gnssAcquireWakelockCb() override;
    Return<void> gnssReleaseWakelockCb() override;
    Return<void> gnssRequestTimeCb() override;
    Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;

    static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
            android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
    static size_t sGnssSvListSize;

    static const char* sNmeaString;
    static size_t sNmeaStringLength;
};
// 省略......
Return<void> 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 <sys/system_properties.h>
// ....... 省略
Return<void> 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. 编译rom
make 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();
                }
            }
        });
}

[看雪官方]走出瓶颈,《安卓高级研修班(网课)》月薪三万[秋季班],12月1日开班,仅剩2位名额!

最后于 2020-6-29 11:04 被neocanable编辑 ,原因: markdown 好像不太好用
收藏
点赞1
打赏
分享
最新回复 (33)
雪    币: 6116
活跃值: 活跃值 (264)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
万剑归宗 活跃值 1 2020-6-28 15:28
2
0
真就得改安卓源码重新编译才行吗
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-6-28 15:34
3
0
@万剑归宗,其实也不是非这样改,替换一些so也能达到这个效果
雪    币: 1111
活跃值: 活跃值 (116)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
我是一只马鹿 活跃值 2020-6-28 17:38
4
0
添加新api,你用/** @Hide */就不需要update-api了
雪    币: 7
活跃值: 活跃值 (228)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zoukaiping 活跃值 2020-6-28 19:06
5
0
试过高德,百度没有?
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-6-28 19:40
6
0
@zoukaiping 高德和百度的顺带要伪造一下cell和wifi,就可以了,主流地图都ok
雪    币: 256
活跃值: 活跃值 (167)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ZwCopyAll 活跃值 2020-6-28 20:59
7
0
mark 
雪    币: 3443
活跃值: 活跃值 (184)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
战马 活跃值 2020-6-30 14:58
8
0
不能直接hook so吗
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-6-30 15:24
9
0
@战马,有源码,还是改源码简单,hook的话可以做
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-6-30 17:05
10
0
现在都是网络定位,修改GPS定位没什么用。钉钉打卡就是例子。
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-1 11:19
11
0
tDasm 现在都是网络定位,修改GPS定位没什么用。钉钉打卡就是例子。
看基站数据和wifi数据了,wifi和基站配合上gps,还是过去大部分检测的
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-1 11:57
12
0
neocanable 看基站数据和wifi数据了,wifi和基站配合上gps,还是过去大部分检测的
网络定位是不一定需要开GPS的。关键是网络定位目前没有什么伪装办法。
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-1 12:03
13
0
tDasm 网络定位是不一定需要开GPS的。关键是网络定位目前没有什么伪装办法。
网络定位是可以伪装的,我测试过,在各大地图app都可以伪装过去

gps只是个辅助,gps跟网络定位match不上,不是一眼假了么?
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-1 12:08
14
0
tDasm 网络定位是不一定需要开GPS的。关键是网络定位目前没有什么伪装办法。
网络定位我测试的时候,还测出过,最准的是大厂是百度
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-1 12:38
15
0
neocanable 网络定位我测试的时候,还测出过,最准的是大厂是百度
你先分析一下钉钉定位再说话。钉钉定位根本不需要开Gps
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-1 13:44
16
0
tDasm 你先分析一下钉钉定位再说话。钉钉定位根本不需要开Gps
人在北京,现在钉钉在上海...
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-1 14:37
17
0
neocanable 人在北京,现在钉钉在上海...

那你拿出来测试看能不能打卡。希望不是假象。打卡就会暴露伪装。(或者简单写一下你的钉钉网络定位分析代码,我一看就知道真假)


最后于 2020-7-1 14:41 被tDasm编辑 ,原因:
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-2 05:58
18
0
neocanable 人在北京,现在钉钉在上海...
你应该说,人在月球……
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-2 10:10
19
0
tDasm 你应该说,人在月球……
网络定位 = ip + wifi + cell
校验: ip + wifi + cell == gps
ip: vpn
wifi和cell数据可以采集的到
如果数据ok,在火星都可以。

你的嘲讽里有股脚臭味儿,多洗洗手,再来打字,谢谢
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-2 11:17
20
0
neocanable 网络定位 = ip + wifi + cell 校验: ip + wifi + cell == gps ip: vpn wifi和cell数据可以采集的到 如果数据ok,在火星都可以。 ...
吹牛不脸红?你根本就没实现。
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-2 12:06
21
0
tDasm 吹牛不脸红?你根本就没实现。
你这种回复非常拉仇恨
非常“安全圈”
实现没实现我自己清楚,你什么想法你自己清楚

有时间多翻翻代码,少抬杠,少摸鱼
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-2 13:04
22
0
neocanable 你这种回复非常拉仇恨 非常“安全圈” 实现没实现我自己清楚,你什么想法你自己清楚 有时间多翻翻代码,少抬杠,少摸鱼
你吹牛可以,别人还不能揭露?这是什么道理?揭穿你就是抬杆?是骡子是马出来遛一圈就知道。
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-2 13:32
23
0
tDasm 你吹牛可以,别人还不能揭露?这是什么道理?揭穿你就是抬杆?是骡子是马出来遛一圈就知道。
我为什么跟你这种人抬杠-_-!
雪    币: 6613
活跃值: 活跃值 (277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2020-7-2 14:35
24
0
neocanable 我为什么跟你这种人抬杠-_-!
就是要揭露你,因为我的眼睛容不了砂子。
gps定位伪装网路上一大把文章,修改源码和xposed hook原理上一样的,还好意思抄出来丢人。
雪    币: 682
活跃值: 活跃值 (333)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
neocanable 活跃值 2020-7-2 17:26
25
1
tDasm 就是要揭露你,因为我的眼睛容不了砂子。 gps定位伪装网路上一大把文章,修改源码和xposed hook原理上一样的,还好意思抄出来丢人。
好好读读代码再出来丢人来
游客
登录 | 注册 方可回帖
返回