Фиктивный адрес. Как подменить геолокацию на Android, чтобы обманывать приложения

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

Идея родилась у меня в процессе написания статьи «Мониторим мониторинг. Что внутри у приложения для изоляции на дому» — именно тогда я обнаружил возможность менять поставщика координат в операционной системе, что открывает для пользователей много интересных возможностей.

С точки зрения юзера все очень просто: нужно лишь установить специальное приложение, затем включить в настройках режим разработчика и выбрать установленное приложение в качестве поставщика фиктивного местоположения. Таких программ великое множество — от простеньких до довольно развесистых, умеющих не только подменять координаты на заданные, но и менять их по расписанию или проигрывать заранее записанные треки, чтобы имитировать движение телефона по какому-то маршруту. В общем, вбивай запрос «Fake GPS» и выбирай по вкусу.

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

Я же захотел разобраться, как именно работает этот механизм, и создать собственное приложение для спуфинга. А начал я с того, что посмотрел, как этот алгоритм реализован в одном из бесплатных приложений. Не читать же документацию, верно?

Реверсим FakeGPS

В качестве подопытного кролика было взято приложение FakeGPS 5.0.0. Внешне приложение представляет собой карту, на которой можно установить маркер в произвольную точку и с помощью кнопок «Старт» и «Стоп» запускать или останавливать трансляцию координат выбранной точки.

Вооружившись JEB Decompiler, открываем и смотрим. Первое, что бросается в глаза, — это наличие в манифесте пермишена android.permission.ACCESS_MOCK_LOCATION.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="com.android.vending.BILLING" />

В основной активити ничего интересного не обнаружено, обычная инициализация и настройка, но есть сервис с говорящим названием FakeGPSService.

Попытаемся прорваться сквозь дебри обфускации и посмотреть, что в нем есть интересного.

В методе onCreate имеется такой код:

this.f = "gps";
this.d = (LocationManager)this.getSystemService("location");
try {
  if(this.d == null) {
    goto label_46;
  }
  this.d.removeTestProvider(this.f);
  goto label_46;
} catch(IllegalArgumentException | NullPointerException unused_ex) {
  goto label_46;
}

label_46:
if(this.d != null) {
  this.d.addTestProvider(this.f, false, false, false, false, true, false, false, 0, 5);
  this.d.setTestProviderEnabled(this.f, true);
}

Если проще, то инициализируем LocationManager значением this.getSystemService("location"), затем удаляем тестового провайдера "gps" функцией removeTestProvider и добавляем заново с помощью функции addTestProvider, не забывая после этого включить его функцией setTestProviderEnabled("gps", true). Всё, тестовый провайдер добавлен и включен. А далее при изменении пользователем координат создаем и устанавливаем новое местоположение в функции onEventMainThread:

// Создаем
long v1 = System.currentTimeMillis();
Location v3 = new Location("");
v3.setProvider("gps");
v3.setLatitude(arg10.latitude);
v3.setLongitude(arg10.longitude);
v3.setAltitude(((double)FakeGPSService.p));
v3.setBearing(((float)FakeGPSService.q));
v3.setTime(v1);
v3.setAccuracy(((float)FakeGPSService.o));
v3.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());

// И устанавливаем
try {
  this.d.setTestProviderLocation(this.f, v3);
  Log.d("GpsMockProvider", v3.toString());
} catch(IllegalArgumentException unused_ex) {
}

Вроде бы все более-менее ясно, можно приступать к написанию своего провайдера фиктивных местоположений.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


Комментарии (20)

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

    • 0d8bc7, слишком тонко троллите. Ну и что что в приложении Навигатора будут неправильно определяться координаты вашей машины, ну и что что в приложении аптеки не будет показан правильно адрес ближайшей к вам аптеки..
      Просто запретить приложению доступ к координатам - не вариант. Настоящие пацаны, чтоб почувствовать себя крутыми, должны обязательно разрешить, но подменить их!

      • В случае с тем же "социальным мониторингом" запретить - действительно не вариант. Ну запретишь ты, ну и вкатают тебе 4 тыщи в день, и иди обжалуй потом. И таких ситуаций куча - водители, курьеры...

      • Это не троллинг.
        Если ПОЛЬЗОВАТЕЛЮ нужно, чтобы конкретное приложение имело доступ к реальным данным — пусть имеет. Девайсы, приложения и прочее существуют для удовлетворения потребностей пользователей, а не наоборот.
        Запретить доступ — не вариант, т.к. приложение просто узнает об этом и может вести себя не так, как если бы доступ был. Хотя в случае с частью приложений всё может быть и нормально, неизвестно, как будут обстоять дела в случае с каким-то произвольным приложением — это риск, а следовательно, в целом поставка фейковых данных представляется более надёжным решением.

        • Сорри, не учёл, что поставщик-то фейковых данные предоставляет данные всем приложениям, а не только тем, которым нужно. Наверное. Ну, тут нормальный выход из ситуации состоит как раз в развитии этой темы в целом, при котором, может быть, когда-нибудь в ОС добавят эти возможности без необходимости использовать костыли.
          Ну и, к сожалению, вынужден констатировать, что Навигатору из вашего примера придётся страдать из-за того что на одном с ним устройстве установлен какой-нибудь "мониторинг" (поставщик данных же один, если я ничего не напутал, вот были бы они разные для разных приложений, было бы другое дело) ¯\_(ツ)_/¯

          • Можно создавать провайдера с произвольным именем, например MyFakeProvider, а потом с помощью apktool подправить то приложение, которое надо обмануть, чтобы оно работало не со стандартным провайдером gps, а с нашим MyFakeProvider. Тогда все, кроме этого приложения, будут получать реальные координаты.

          • Но тогда может возникнуть проблема с подписью или ещё с чем то, если обманываемое приложение проверяет свою целостность.

          • Но можно и проверку целостности вырезать:-) короче говоря, все зависит от желания и конкретной ситуации.

    • Насчёт фейковой камеры не слыхал, но подозреваю, что тут понадобится рут, и весьма вероятно, что решение будет сильно привязано к конкретной модели и версии прошивки. Но мысль интересная... А по поводу микрофона - можно взять штекер 3,5 и замкнуть определенные контакты через сопротивление (100 ом, вроде, но точно не помню), воткнуть его в телефон и телефон будет думать, что подключен внешний микрофон, его собственный при этом отключится. Когда надо позвонить - штекер вынимается, после звонка вставляется назад.

      • Хм... А что, просто до безобразия, а главное - работает :-) Кстати, вспомнился лайф-хак с камерами для ноутбуков: заклеить чёрной изолентой, ну, или синей - она обычна всегда 100%-й вариант :-)

  • Ни разу не видел, и у меня их тоже нет, в настройках телефона возможность разрешить устанавливать фиктивное местоположение. Режим разработчика включён. С какой версии Андроид такое разрешает?

  • Тут вот одна проблема остается. Галочка фиктивных локаций в настройках. Может ли установленное приложение видеть, что этот режим у телефона включен? Как видят рут доступ например. И заведомо понимать, что обманывают.

      • То есть невозможно внедрить в телефон нужное гео без включенной галочки Mock Location?

        • Ну слово "невозможно" надо использовать аккуратно, поэтому скажу иначе: мне такие способы неизвестны. И да, отследить это можно. Данная функция нужна для разработчиков,тестировать приложения.

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

  • Дочитал статью, но все это осуществить не сумею. Обращаюсь к автору, не могли бы Вы мне в личку скинуть уже готовое приложение?

Похожие материалы