Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does some apps(wechat) ignore fake location and then detect the real one?

I have installed a fake location app and set my location different. Then opened Google Maps and Wechat app,

  • Google Maps shows my location as what i set(fake)
  • Wechat app ignores fake location and detects real location (how?)

Then i wanted to prevent wechat analyze my previously received real locations and new fake location.

  • Uninstalled Wechat
  • Restarted my device
  • Set my location as fake
  • Installed Wechat again

But same result, it detects my real location.

I really want to understand how they do this. Any ideas?


What i have tried

  • Gps provider spoof
  • Network provider spoof
  • Fused location provider spoof
  • IP geolocation spoof
  • Gps provider spoof + IP geolocation spoof

UPDATE

Uses GPS even when disabled.

enter image description here

07-02 11:46:15.504 2346-2356/? D/LocationManagerService: request 434a7e28 gps Request[ACCURACY_FINE gps requested=+1s0ms fastest=+1s0ms] from com.tencent.mm(10173)


CONCLUSION

  • You can fake location on older versions of wechat(lower than 6.0)
  • Uses something like BaiduLocationSDK. It's not affected from any mock attempt through LocationManager and Fused provider.
  • I'm not sure but, seems like BaiduLocationSDK uses GPS through hardware level.
like image 497
blackkara Avatar asked May 11 '16 23:05

blackkara


People also ask

How does app detect fake location?

On Android 18 (JellyBean MR2) and above mock locations are detected using Location. isFromMockProvider() for each location. The app can detect that the location came from a mock provider when the API returns true.

How accurate is WeChat location?

When a WeChat user is querying to the server to find nearby people, the exact location of the nearby user is hidden and coarse-grained distance information is provided by the server, such as user A is within 300 m. Based on the reported distance information, the exact location of users cannot be determined directly.

Can you fake location on WeChat?

In theory, the easiest way to fake your location on WeChat is to use the inbuilt feature on the app itself. Users are able to protect their privacy by heading into the app settings and simply changing the primary country from which they're using the app. To do this, you don't need to install any third-party tool.


5 Answers

To check for fake location most applications look for GGA and GSV sentences in the NMEA (National Marine Electronics Association) data received by them. The fake location providers do not send NMEA sentences along with location, so this parameter can be used to
If they haven't received and GGA and GSV sentences in a threshold amount of time, say 100 seconds they red flag the current location provider.
This process is repeated till a valid set of NMEA sentences has been received and then the corresponding location is selected.

To retreive NMEA data LocationManager#addNmeaListener(GpsStatus.NmeaListener listener) is called and then in the listener

void onNmeaReceived(long timestamp, String nmea) {
    Log.d("Nmea Data",nmea);
}

for more info see adding a NmeaListener
the NMEA sentences, GGA and GSV look as follows

GGA - essential fix data which provide 3D location and accuracy data.

Sample : "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47"

Where:
 GGA          Global Positioning System Fix Data
 123519       Fix taken at 12:35:19 UTC
 4807.038,N   Latitude 48 deg 07.038' N
 01131.000,E  Longitude 11 deg 31.000' E
 1            Fix quality: 0 = invalid
                           1 = GPS fix (SPS)
                           2 = DGPS fix
                           3 = PPS fix
                           4 = Real Time Kinematic
                           5 = Float RTK<br/>
                           6 = estimated (dead reckoning) (2.3 feature)
                           7 = Manual input mode>
                           8 = Simulation mode
 08           Number of satellites being tracked
 0.9          Horizontal dilution of position
 545.4,M      Altitude, Meters, above mean sea level
 46.9,M       Height of geoid (mean sea level) above WGS84 ellipsoid
 (empty field) time in seconds since last DGPS update
 (empty field) DGPS station ID number
 *47          the checksum data, always begins with *


GSV - Satellites in View shows data about the satellites that the unit might be able to find based on its viewing mask and almanac data. It also shows current ability to track this data. Note that one GSV sentence only can provide data for up to 4 satellites and thus there may need to be 3 sentences for the full information. It is reasonable for the GSV sentence to contain more satellites than GGA might indicate since GSV may include satellites that are not used as part of the solution. It is not a requirement that the GSV sentences all appear in sequence. To avoid overloading the data bandwidth some receivers may place the various sentences in totally different samples since each sentence identifies which one it is.

Sample:"$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75"

Where:
  GSV          Satellites in view
  2            Number of sentences for full data
  1            sentence 1 of 2
  08           Number of satellites in view

  01           Satellite PRN number
  40           Elevation, degrees
  083          Azimuth, degrees
  46           SNR - higher is better
               for up to 4 satellites per sentence
  *75          the checksum data, always begins with *

Source : NMEAData

like image 72
Sakchham Avatar answered Sep 30 '22 12:09

Sakchham


Some 3rd party location sdk like BaiduLocationSDK doesn't reflect the fake location setup by system.

It's for safety purpose.

like image 20
windkiosk Avatar answered Sep 30 '22 13:09

windkiosk


The reason I was asking the questions in the comments is that I was hoping you tested how Wechat responds to different conditions.

There are a couple of other ways to detect device location which TestProvider shouldn't affect AFAIK. This needs testing but here are some ideas:

  • LocationManager.getLastKnownLocation(String provider) - this allows you to force using for example a GPS provider and get cached data.
  • GPS NMEA listener, and a new one in API 24 - these APIs allow listening for low-level events from GPS hardware using NMEA 0183 protocol.
  • IP address geolocation.
  • You can get country-level geolocation via Telephony Manager.

Edit: added Telephony manager option.

like image 22
Timur_C Avatar answered Sep 30 '22 14:09

Timur_C


@Bona Fide

Then you can remove the TestProvider from the LocationManager and get the actual location.

Even wechat would use this approach before requesting location updates, to avoid providers being spoofed by other applications, like something below

// HERE WECHAT APP
// WECHAT REMOVES THEM IF ANY (just supposition)
locationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
locationManager.removeTestProvider(LocationManager.NETWORK_PROVIDER);

// WECHAT REQUESTING LOCATION UPDATES
// ....

So this approach causes throwing a IllegalArgumentException on the location faker app. Even in that case, i can easily handle this issue and continue spoofing GPS and NETWORK providers again,

// HERE LOCATION FAKER APP
// LOCATION FAKER APP SETS FAKE LOCATIONS 
while (mRunning){
    try {
        locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, gpsLocation);
    } catch (IllegalArgumentException e){
        locationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, false, false, false, false, true, true, 1, 1);
        locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);
    }

   try {
        locationManager.setTestProviderLocation(LocationManager.NETWORK_PROVIDER, networkLocation);
    } catch (IllegalArgumentException e){
        locationManager.addTestProvider(LocationManager.NETWORK_PROVIDER, false, false, false, false, false, true, true, 1, 1);
        locationManager.setTestProviderEnabled(LocationManager.NETWORK_PROVIDER, true);
    }

    gpsLocation.setTime(System.currentTimeMillis());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        gpsLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    }

    networkLocation.setTime(System.currentTimeMillis());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        networkLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    }

    try {
        Thread.sleep(500);
    } catch (Exception e) {}
}

Everything works perfectly but out of WECHAT

like image 21
blackkara Avatar answered Sep 30 '22 14:09

blackkara


Fake locations are possible if ALLOW_MOCK_LOCATION is set and a TestProvider is added to the LocationManager. To get the real location you need to do these two steps:

  • Detect if MockSettings are enabled and whether there are Apps installed how could fake the location.
  • Then you can remove the TestProvider from the LocationManager and get the actual location.

Checkout Jambaaz answer to get an example how this works in code.

Note: To remove an TestProvider you need the Permission android.permission.ACCESS_MOCK_LOCATION and ALLOW_MOCK_LOCATION is now deprecated since API 23. You can now check if the Location is from a TestProvider directly from Location.isFromMockProvider()

like image 23
Bona Fide Avatar answered Sep 30 '22 14:09

Bona Fide