Delphi RAD Studio Как читать & ldquo; android.permission.ACCESS_MOCK_LOCATION & rdquo; [Дубликат]

Использование базовой функции R aggregate:

aggregate(value ~ name, dat1, I)

# name           value.1  value.2  value.3  value.4
#1 firstName      0.4145  -0.4747   0.0659   -0.5024
#2 secondName    -0.8259   0.1669  -0.8962    0.1681
65
задан Chrispix 30 July 2011 в 01:14
поделиться

8 ответов

Я провел некоторое расследование и поделился своими результатами здесь, это может быть полезно для других.

Сначала мы можем проверить, включена ли опция MockSetting

public static boolean isMockSettingsON(Context context) {
    // returns true if mock location enabled, false if not enabled.
    if (Settings.Secure.getString(context.getContentResolver(),
                                Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
        return false;
    else
        return true;
}

Second , мы можем проверить, есть ли в устройстве другие приложения, которые используют android.permission.ACCESS_MOCK_LOCATION (Приложения для спуфинга места)

public static boolean areThereMockPermissionApps(Context context) {
    int count = 0;

    PackageManager pm = context.getPackageManager();
    List<ApplicationInfo> packages =
        pm.getInstalledApplications(PackageManager.GET_META_DATA);

    for (ApplicationInfo applicationInfo : packages) {
        try {
            PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName,
                                                        PackageManager.GET_PERMISSIONS);

            // Get Permissions
            String[] requestedPermissions = packageInfo.requestedPermissions;

            if (requestedPermissions != null) {
                for (int i = 0; i < requestedPermissions.length; i++) {
                    if (requestedPermissions[i]
                        .equals("android.permission.ACCESS_MOCK_LOCATION")
                        && !applicationInfo.packageName.equals(context.getPackageName())) {
                        count++;
                    }
                }
            }
        } catch (NameNotFoundException e) {
            Log.e("Got exception " , e.getMessage());
        }
    }

    if (count > 0)
        return true;
    return false;
}

Если оба метода выше, первый и второй являются истинными, тогда есть хорошие шансы это местоположение может быть подделанным или поддельным.

Теперь с помощью API-интерфейса диспетчера местоположений можно избежать спуфинга.

Мы можем удалить поставщика теста, прежде чем запрашивать обновления местоположения как у поставщиков (сеть и GPS)

LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);

try {
    Log.d(TAG ,"Removing Test providers")
    lm.removeTestProvider(LocationManager.GPS_PROVIDER);
} catch (IllegalArgumentException error) {
    Log.d(TAG,"Got exception in removing test  provider");
}

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);

Я видел, что removeTestProvider (~) отлично работает над версией Jelly Bean и далее. Этот API оказался ненадежным до Ice Cream Sandwich.

97
ответ дан Dennis 21 August 2018 в 01:07
поделиться
  • 1
    Спасибо, что поделились, посмотрим. – Chrispix 27 May 2013 в 17:08
  • 2
    Обратите внимание на метод removeTestProvider. Если вы разрешаете менеджеру местоположений работать в фоновом режиме, пользователь может перейти к mock app и перезапустить насмешливое местоположение. Затем ваш менеджер местоположений начнет получать ложные адреса, пока вы не вызовете removeTestProvider еще раз. – Timur_C 17 March 2015 в 18:35
  • 3
    Также ваше приложение должно иметь разрешение android.permission.ACCESS_MOCK_LOCATION для работы removeTestProvider, что, по моему мнению, является самым большим недостатком. – Timur_C 17 March 2015 в 18:41
  • 4
    Спасибо за ответ! просто точка: в Android 6.0 ALLOW_MOCK_LOCATION устарела. И на самом деле нет флажка для определения местоположения. Можно проверить, является ли местоположение фальшивым или неправильным из объекта местоположения: location.isFromMockProvider () – Silwester 20 January 2016 в 14:51
  • 5
    @ Блаккара, я не использовал его в конце концов. Я использовал индивидуальную комбинацию isMockSettingsON(), Location.isFromMockProvider() и areThereMockPermissionApps() с черным списком приложений. Существует множество предустановленных системных приложений с разрешением ACCESS_MOCK_LOCATION, например, на устройствах HTC и Samsung. Белым списком всех законных приложений было бы лучше, но черный список самых популярных приложений для спуфинга приложений хорошо работал в моем случае. И я также проверил, было ли устройство укоренено. – Timur_C 12 May 2016 в 23:11

Этот скрипт работает для всей версии Android, и я нахожу его после многих поисков

LocationManager locMan;
    String[] mockProviders = {LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER};

    try {
        locMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        for (String p : mockProviders) {
            if (p.contentEquals(LocationManager.GPS_PROVIDER))
                locMan.addTestProvider(p, false, false, false, false, true, true, true, 1,
                        android.hardware.SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
            else
                locMan.addTestProvider(p, false, false, false, false, true, true, true, 1,
                        android.hardware.SensorManager.SENSOR_STATUS_ACCURACY_LOW);

            locMan.setTestProviderEnabled(p, true);
            locMan.setTestProviderStatus(p, android.location.LocationProvider.AVAILABLE, Bundle.EMPTY,
                    java.lang.System.currentTimeMillis());
        }
    } catch (Exception ignored) {
        // here you should show dialog which is mean the mock location is not enable
    }
2
ответ дан ali 21 August 2018 в 01:07
поделиться

Спустя пару лет наткнулся на эту тему. В 2016 году большинство устройств Android будут иметь уровень API> = 18 и поэтому должны полагаться на Location.isFromMockProvider (), как указано Fernando .

Я интенсивно экспериментировал с фальшивым / макетным местоположения на разных устройствах и дистрибутивах Android. К сожалению .isFromMockProvider () не на 100% надежнее. Время от времени подделка не будет помечена как макет . Похоже, что это связано с некоторой ошибочной логикой внутреннего слияния в Google Location API.

Я написал подробное сообщение в блоге об этом , если вы хотите узнать больше. Подводя итог, если вы подписаны на обновления местоположения из API местоположения, затем включите поддельное приложение GPS и распечатайте результат каждой команды Location.toString () на консоли, вы увидите что-то вроде этого:

Обратите внимание, что в потоке обновлений местоположения одно местоположение имеет те же координаты, что и другие, но не помечено как макет и имеет гораздо более худшую точность местоположения.

Чтобы исправить эту проблему, я написал класс утилиты, который будет надежно подавлять местоположения Mock во всех современных версиях Android (уровень API 15 и выше):

LocationAssistant - бесплатные обновления местоположения на Android

В принципе, он «недоверяет» немощные местоположения, которые находятся в пределах 1 км от последнего известного макетного местоположения, а также называет их как макет. Он делает это до тех пор, пока не достигнет значительного количества немощных мест. LocationAssistant может не только отбрасывать ложные местоположения, но и освобождает вас от большинства проблем с настройкой и подпиской на обновления местоположения.

Чтобы получать только реальные обновления местоположения (например, подавлять издевки), используйте его следующим образом :

public class MyActivity extends Activity implements LocationAssistant.Listener {

    private LocationAssistant assistant;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // You can specify a different accuracy and interval here.
        // The last parameter (allowMockLocations) must be 'false' to suppress mock locations.  
        assistant = new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false);
    }

    @Override
    protected void onResume() {
        super.onResume();
        assistant.start();
    }

    @Override
    protected void onPause() {
        assistant.stop();
        super.onPause();
    }

    @Override
    public void onNewLocationAvailable(Location location) {
        // No mock locations arriving here
    }

    ...
}

onNewLocationAvailable() теперь будет вызываться только с информацией о реальном местоположении. Есть еще несколько методов слушателя, которые вам нужно реализовать, но в контексте вашего вопроса (как предотвратить спуфинг с GPS) это в основном это.

Конечно, с корневой ОС вы все равно можете найти способы информация о спуфинге, которую невозможно обнаружить обычным приложениям.

21
ответ дан André 21 August 2018 в 01:07
поделиться
  • 1
    Вы должны кратко суммировать связанное сообщение в блоге (где isFromMockProvider не работает). – AjahnCharles 18 July 2016 в 18:52
  • 2
    @CodeConfident - спасибо за замечание! Не уверен, что я должен добавить. Второй абзац моего ответа - это резюме сообщения в блоге. .isFromMockProvider терпит неудачу спорадически и непредсказуемо. В статье я просто более подробно описываю шаги, которые я предпринял, чтобы обнаружить и исправить это. – KlaasNotFound 20 July 2016 в 22:52
  • 3
    Ну, я был вынужден перейти к вашей статье, чтобы понять, что мне кажется, что она противоречит намерению SO. Мое лучшее предложение было бы: (1) вставить свой рис, который показывает хитрое местоположение (не помечено как макет), и (2) быстро заметьте свою логику для их устранения (игнорируйте в пределах 1 км от макета) – AjahnCharles 20 July 2016 в 23:06
  • 4
    Хорошо, понял. Я думаю, что в контексте ОП специфика почему .isFromMockProvider () ненадежна, не слишком актуальна. Но я попытаюсь добавить детали, которые вы упомянули для большей картины. Спасибо за ответ! – KlaasNotFound 20 July 2016 в 23:17
  • 5
    Что делать, если у пользователя нет установленной службы Google Play? – Yuriy Chernyshov 9 August 2016 в 17:59

Кажется, что единственный способ сделать это - предотвратить спуфинг места, предотвращающий MockLocations. С другой стороны, есть некоторые пользователи, которые используют Bluetooth-устройства GPS для получения лучшего сигнала, они не смогут использовать приложение, поскольку они должны использовать макет местоположения.

Для этого я сделал следующее:

// returns true if mock location enabled, false if not enabled.
if (Settings.Secure.getString(getContentResolver(),
       Settings.Secure.ALLOW_MOCK_LOCATION).equals("0")) 
       return false; 
       else return true;
34
ответ дан Chrispix 21 August 2018 в 01:07
поделиться
  • 1
    Однако это не доказательство дурака. Пользователи на ненагруженном устройстве могут по-прежнему устанавливать макет местоположения, в будущем, а затем отключать макет местоположений, а макет местоположения по-прежнему активен. Хуже того, они могут назвать фальшивое местоположение тем же именем поставщика, что и Network / Gps, и это, по-видимому, тянет от этого. – Chrispix 15 January 2012 в 06:10
  • 2
    Кроме того, Fake GPS не требует установки макета местоположения на корневых устройствах. – Paul Lammertsma 7 March 2012 в 15:21
  • 3
    Всегда проверяйте, не установлено ли приложение fake.gps :) – Chrispix 12 March 2012 в 21:38
  • 4
    Вы можете использовать return !x вместо if(x) return false; else return true. – CodesInChaos 12 August 2014 в 14:10
  • 5
    Фактически, Fake-местоположение изменит настройку определения местоположения даже на корневых устройствах. – PageNotFound 19 August 2014 в 14:02

Поскольку API 18, объект Местоположение имеет метод .isFromMockProvider () , поэтому вы можете отфильтровывать поддельные местоположения.

Если вы хотите поддерживать версии до 18, можно использовать что-то вроде этого:

boolean isMock = false;
if (android.os.Build.VERSION.SDK_INT >= 18) {
    isMock = location.isFromMockProvider();
} else {
    isMock = !Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0");
}
27
ответ дан Fernando 21 August 2018 в 01:07
поделиться
  • 1
    Я уверен, что ваше второе выражение обратное (верните true, когда он вернет false). Я думаю, что это должно быть: isMock = !Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"); – AjahnCharles 18 July 2016 в 18:48
  • 2
    Вы правы, спасибо. – Fernando 19 July 2016 в 20:05
  • 3
    Пожалуйста. Спасибо, что опубликовали более современный ответ! На самом деле это правильный ответ на сегодняшний день. – AjahnCharles 20 July 2016 в 22:56
  • 4
    Как мы можем это сделать без «местоположения»? объект для SDK выше 18? – Ajit Sharma 19 January 2017 в 09:11

попробуйте этот код очень просто и полезно

  public boolean isMockLocationEnabled() {
        boolean isMockLocation = false;
        try {
            //if marshmallow
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                AppOpsManager opsManager = (AppOpsManager) getApplicationContext().getSystemService(Context.APP_OPS_SERVICE);
                isMockLocation = (opsManager.checkOp(AppOpsManager.OPSTR_MOCK_LOCATION, android.os.Process.myUid(), BuildConfig.APPLICATION_ID)== AppOpsManager.MODE_ALLOWED);
            } else {
                // in marshmallow this will always return true
                isMockLocation = !android.provider.Settings.Secure.getString(getApplicationContext().getContentResolver(), "mock_location").equals("0");
            }
        } catch (Exception e) {
            return isMockLocation;
        }
        return isMockLocation;
    }
1
ответ дан Mostafa Pirhayati 21 August 2018 в 01:07
поделиться
  • 1
    Это гораздо более эффективная версия метода isMockLocationEnabled выше. – Joset 15 March 2018 в 19:17

Если вам удалось узнать общее местоположение вышек сотовой связи, вы можете проверить, соответствует ли текущая ячейковая башня указанному местоположению (в пределах допустимой погрешности чего-то большого, например, 10 или более миль).

Например, если ваше приложение разблокирует функции только в том случае, если пользователь находится в определенном месте (например, в вашем магазине), вы можете проверить gps, а также сотовые башни. В настоящее время ни одно приложение для спуфинга gps также не обманывает башни сотовых телефонов, поэтому вы можете увидеть, пытается ли кто-то по всей стране просто подтолкнуть их к вашим особым функциям (например, я думаю о приложении Disney Mobile Magic на одном примере).

Так как приложение Llama управляет местоположением по умолчанию, так как проверка идентификаторов ячеек ячеек значительно меньше, чем у gps. Это не полезно для очень конкретных мест, но если дом и работа находятся в нескольких милях от него, он может легко различать два общих местоположения.

Конечно, это потребует от пользователя наличия ячейки сигнал вообще. И вам нужно будет знать все идентификаторы ячеек в этой области - на всех сетевых провайдерах - или вы рискуете ложным отрицанием.

5
ответ дан Stephen Schrauger 21 August 2018 в 01:07
поделиться
  • 1
    Спасибо, это неплохая идея. Возможно, мне придется изучить это. благодаря – Chrispix 9 July 2012 в 20:49

Вы можете добавить дополнительную проверку, основанную на триангуляции башни ячеек или информации о точках доступа Wi-Fi, используя API геолокации Google Maps

Самый простой способ получить информацию о CellTowers

final TelephonyManager telephonyManager = (TelephonyManager) appContext.getSystemService(Context.TELEPHONY_SERVICE);
String networkOperator = telephonyManager.getNetworkOperator();
int mcc = Integer.parseInt(networkOperator.substring(0, 3));
int mnc = Integer.parseInt(networkOperator.substring(3));
String operatorName = telephonyManager.getNetworkOperatorName();
final GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
int cid = cellLocation.getCid();
int lac = cellLocation.getLac();

Вы можете сравнить свои результаты с сайтом

. Чтобы получить информацию о точках доступа Wifi

final WifiManager mWifiManager = (WifiManager) appContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

if (mWifiManager != null && mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {

    // register WiFi scan results receiver
    IntentFilter filter = new IntentFilter();
    filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                List<ScanResult> results = mWifiManager.getScanResults();//<-result list
            }
        };

        appContext.registerReceiver(broadcastReceiver, filter);

        // start WiFi Scan
        mWifiManager.startScan();
}
0
ответ дан yoAlex5 21 August 2018 в 01:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: