В 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 комментариев

  1. Аватар

    0d8bc7

    09.07.2020 в 13:45

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

    • Аватар

      Novosedoff

      09.07.2020 в 19:43

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

      • Аватар

        Mazay

        09.07.2020 в 20:58

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

      • Аватар

        0d8bc7

        10.07.2020 в 00:13

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

        • Аватар

          0d8bc7

          10.07.2020 в 05:00

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

          • Аватар

            Mazay

            10.07.2020 в 07:02

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

            • Аватар

              Mazay

              10.07.2020 в 07:03

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

              • Аватар

                Mazay

                10.07.2020 в 07:05

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

    • Аватар

      Mazay

      10.07.2020 в 06:59

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

      • Аватар

        Laglag

        12.07.2020 в 12:57

        генеально спасибо!!!!!!

      • Аватар

        Lex.Mikachev

        12.07.2020 в 18:10

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

  2. Аватар

    m2s2TNgqFNu4kvD5M

    14.07.2020 в 10:58

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

  3. Аватар

    viktor_cortez

    20.07.2020 в 21:33

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

  4. Аватар

    dlok975

    25.08.2020 в 14:21

    интересно, а gps трекера такого типа https://wust.in.ua/ustanovka-gps-trekera-kiev тоже можно аналогично хакнуть?

  5. Аватар

    Bogdan99

    10.09.2020 в 14:54

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

Оставить мнение