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

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

В 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.

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

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

В методе 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) {
}

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

Пишем код

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

Итак, запускаем Android Studio и создаем проект с пустой активити.

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

Добавляем в манифест android.permission.ACCESS_MOCK_LOCATION, после чего «Студия» начинает ругаться, что это разрешение доступно только системным приложениям, да еще может быть добавлено только в тестовый манифест. Тут можно не заморачиваться, а просто понажимать кнопки Alt+Shift+Enter и Alt-Enter, следуя подсказкам, и «Студия» сама все сделает за нас. Затем добавляем на стартовую активити две кнопки.

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical">
  <Button
    android:id="@+id/btnDelGPS"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="DelGPS"
    android:text="Удалить провайдер GPS" />
  <Button
    android:id="@+id/btnAddGPS"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="AddGPS"
    android:text="Добавить провайдер GPS" />     
</LinearLayout>

И добавляем соответствующий код.

public class MainActivity extends Activity {
  LocationManager mLocationManager;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Инициализируем LocationManager
    mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  }
  public void AddGPS(View view) {
    // Добавляем тестовый провайдер
    mLocationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, false,
      false, false, true, true,
      true, android.location.Criteria.POWER_LOW, android.location.Criteria.ACCURACY_FINE);

    // Включаем тестовый провайдер
    mLocationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);

    // Задаем фиктивную точку
    Location newLocation = new Location(LocationManager.GPS_PROVIDER);
    newLocation.setLatitude(55.75578);
    newLocation.setLongitude(37.61786);
    newLocation.setTime(System.currentTimeMillis());
    newLocation.setAccuracy(25);
    newLocation.setElapsedRealtimeNanos(System.nanoTime());
    mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, newLocation);
  }
  public void DelGPS(View view) {
    // Удаляем наш тестовый провайдер
    mLocationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
  }
}

Компилируем и устанавливаем. Затем идем в настройки разработчика на телефоне, выбираем наше приложение в качестве поставщика фиктивных местоположений, трясущимися от волнения (как же, мы же только что написали собственный поставщик местоположений!) руками запускаем наше приложение и жмем кнопку «Добавить провайдер GPS».

Читайте также:  В Лондоне началась траурная процессия с гробом Елизаветы II
Фиктивный адрес. Как подменить геолокацию на Android, чтобы обманывать приложения 14
Фиктивный адрес. Как подменить геолокацию на Android, чтобы обманывать приложения 15
Фиктивный адрес. Как подменить геолокацию на Android, чтобы обманывать приложения 16
Фиктивный адрес. Как подменить геолокацию на Android, чтобы обманывать приложения 17

Ничего не происходит. Ничего, собственно, и не должно происходить.

Если приложение запускается не первый раз, то возможно падение из-за того, что тестовый провайдер с таким именем уже создан. Тогда надо повторно запустить приложение и удалить провайдер кнопкой «Удалить провайдер GPS», а затем создать его заново кнопкой «Добавить провайдер GPS».

Я намеренно не стал добавлять обработку таких ошибок, чтобы не засорять код, мы же пишем макет, а не финальную версию. Впрочем, можешь присылать пулл-реквесты, ссылка на GitHub будет в конце статьи

Тестируем

Сворачиваем приложение и приступаем к тестам. Запускаем «Яндекс Карты» и попадаем точно на Красную площадь, в нулевой километр, как и было задумано. Ура, получилось!

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

Ну, почти получилось. Если попробовать запустить Google Maps, почему-то мы попадаем на площадь Комсомола в городе Урюпинске. Вернее, понятно, почему попадаем, непонятно, почему не работает наш TestProvider.

Скажу честно, ответ на этот вопрос я искал несколько дней, но все оказалось довольно просто — надо отключить в настройках телефона геолокацию Google. Эта настройка позволяет не заморачиваться с выбором провайдера: телефон сам решает, из какого источника брать координаты. Начинает с самых точных, то есть GPS, затем, если спутниковое позиционирование недоступно, переходит к базовым станциям, затем по сетям Wi-Fi, а затем якобы даже использует акселерометр, чтобы найти себя в пространстве.

Итак, пробуем — отключаем геолокацию Google и запускаем «Карты».

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

Сработало, мы снова на Красной площади.

Итак, этот способ позволяет подменять реальные координаты GPS фиктивными, но хотелось бы решить задачу полностью — подменять местоположение начисто, без всяких скидок. Что интересно, наш подопытный кролик FakeGPS работает корректно независимо от настроек геолокации Google. Что ж, будем ковырять дальше.

Исправляем ошибки

Присмотревшись к сервису FakeGPSService чуть более внимательно, я заметил, что там еще используется некий GoogleApiClient. Признаюсь, при первичном анализе я с ходу решил, что он нужен для рекламы, и не стал больше обращать на него внимание. А еще там есть вот эти два метода:

LocationServices.FusedLocationApi.setMockMode()
LocationServices.FusedLocationApi.setMockLocation()

Кажется, это то, что нужно. Погуглив документацию (от нее все же не уйти!), выясняем, что FusedLocationApi немножко устарел и вместо него рекомендуется использовать FusedLocationProviderClient.

Что же, попробуем. Добавляем в раздел dependencies файла build.gradle такую строчку:

implementation 'com.google.android.gms:play-services-location:17.0.0'

Интересно, что после добавления этой строчки объем приложения вырастает с 11 Кбайт до 1 Мбайта с хвостиком.

В конец функции AddGPS дописываем пару строк.

LocationServices.getFusedLocationProviderClient(this).setMockMode(true);
LocationServices.getFusedLocationProviderClient(this).setMockLocation(newLocation);

Компилируем и запускаем — теперь нормально работает и в Google Maps с включенной геолокацией, и в «Яндекс Картах». Победа!

Источник

1

Автор публикации

не в сети 3 дня

Андрей Маргулис

548
С организацией DDoS атак завязал.
Выкладываю новости технологий и интересные статьи с темной стороны интернета.
31 год
День рождения: 14 Мая 1991
Комментарии: 548Публикации: 2727Регистрация: 12-12-2015
Понравилась статья? Поделиться с друзьями:
РЭНБИ - Россия
Авторизация
*
*
Регистрация
*
*
*
*
Ваш день рождения * :
Число, месяц и год:
Отображать дату:
Генерация пароля
/