Активация FCC на Дронах DJI — твик

Активация FCC на Дронах DJI — твик Мультикоптеры

Описание

DJI ограничивает радио частоты и мощность радио сигнала, чтобы соответствовать местным правилам.
Этот хак позволяет снять эти ограничения. Например, для Mavic Mini CE в России появится диапазон 5.8 GHz (WiFi каналы 149 — 165) и мощность передатчика возрастёт.
После этого хака можно пользоваться дроном как обычно.

План действий:

  1. Шаг 1. С помощью Fake GPS дрон решит, что он находится в США или Боливии и включит оба диапазона и макс. мощность;
  2. Шаг 2. Изменим в пульте настройку, чтобы дрон не переключился обратно в ограниченный режим.

Как определить что режим fcc работает

Чтобы понять, что Твик сработал и режим FCC активирован, необходимо зайди в меню «настройки->передача».

Здесь мы увидим пункт частота и чуть ниже будет график с уровнем сигнала. Если выбор частоты активен, значит скорее всего FCC тоже активирован. Далее смотрим на график. Если две полосы с ~1 km и ~4 km выше меток -90 и -100 соответственно — значит поздравляем, у вас активирован FCC. Скриншот приложен ниже.

Смотрите про коптеры:  Как работает роботизированная коробка передач — ДРАЙВ

Если выбор частоты не активен и полосы ниже метов -90 и -100, значит это CE режим. Скриншот для понимания приложен чуть ниже.

Что понадобится для хака

  • DJI Mavic Mini дрон и пульт
  • мобильник с Android*
  • компьютер со свежим браузером
  • USB шнур подключить пульт к компьютеру

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

⚠️как правильно запускать dji fly plus (соблюдаем последовательность)

❗️На андроиде перед установкой приложения Plus удаляем официальную Dji Fly

  1. Дрон выключен
  2. Запускаем DJI Fly Plus
  3. Ждем сообщения «Колдуем/Magic» после синхронизации приложения
  4. Включаем пульт и ждем соединения пульта и приложения.
  5. Включаем дрон.
  6. Дожидаемся фиксирования сигнала GPS и установки точки возврата домой. Приложение сообщит голосом что домашняя точка обновлена.
  7. Проверяем активацию FCC и 5.8. Для этого идем в настройки и открываем вкладку передача.
  8. Летим!

Alternate config/parameters data structure

We need to build a data structure, and some methods for accessing and updating this data that will be used by all of the other methods. Why? As a longer term goal, it would be good to publish our own NIB files for IOS and equivalent for Android that will allow update of this data.

Dh разблокировал nfz и высоту для дронов dji ! – вопросы – однодневки

Current problems with the certificates by AwesomeAM

Posted on 2023-08-14 15:47:57

Hey there,
that was a wild ride.
We must urge you to STAY OFFLINE with the hack! As long as you only used DJI FLY/DJI GO in flight mode all is fine, if you happened to have it online it could be that the certificate cannot be activated anymore!

Here is the explanation why:
It seems that dji did not like our certificates and issued EVERY customer a new UID, this killed ALL certificates (even legitimate ones!).
We are currently working on a solution. We have a “manual” solution ready for most of the drones but we are searching for a better way to get all drones online again!

We are extremely sorry that this happened but that is the thing with such hacks, they are fought by the vendor.

We hope to have one for you in the next coming days, please give us some time to work it out in a nice way smile_good.gif

As for now we disabled the buying of new licenses, we think it is the right thing to do! Be sure we will fix this, give us some days time and we are very confident that we get all drones hacked again. Our current drone here (has an activated certificate again, we just need to find a way to get this automated in the app!)

So long! Thank your for your support!

Текущие проблемы с сертификатами автор AwesomeAM

Опубликовано 2023-08-14 15:47:57

Эй там,
это была дикая поездка.
Мы должны настоятельно призвать вас оставаться в АВТОНОМНОМ режиме с помощью этого взлома! До тех пор, пока вы используете DJI FLY/DJI GO только в режиме полета, все в порядке, но если он случайно оказался у вас онлайн, то сертификат больше не может быть активирован!

Вот объяснение почему:
Похоже, что dji не понравились наши сертификаты и выдала КАЖДОМУ клиенту новый UID, это убило ВСЕ сертификаты (даже законные!).
В настоящее время мы работаем над решением этой проблемы. У нас есть “ручное” решение, готовое для большинства дронов, но мы ищем лучший способ снова подключить все дроны к Сети!

Мы очень сожалеем, что это произошло, но в том-то и дело, что с такими взломами борется продавец.

Мы надеемся, что у вас будет один из них в ближайшие дни, пожалуйста, дайте нам немного времени, чтобы решить его по-хорошему smile_good.gif

Что касается сейчас покупки новых лицензий, то мы считаем, что это правильно! Будьте уверены, что мы исправим это, дайте нам несколько дней времени, и мы очень уверены, что мы снова взломаем все дроны. Наш текущий дрон здесь (имеет активированный сертификат снова, нам просто нужно найти способ автоматизировать это в приложении!)

Так долго! Спасибо вам за вашу поддержку!

Удалил компрометированный сертификат, установил новый , всё равно не работает… 

§

SergSSA, Извините, а что там курить нужно?

Просто по шагам, ставим асист 2 с ним ставятся дрова, проверяем прошивку, какая подходит для снятия НФЗ – это 100 прошивка, у нас стоит 670 на ней стоит защита от отката, следовательно я не могу откатится и воспользоваться данным сертификатом для снятия ограничений.

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

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

Сообщение отредактировал Plavchikovich: 18 Август 2023 – 05:18

§

SergSSA, Извините, а что там курить нужно?

Просто по шагам, ставим асист 2 с ним ставятся дрова, проверяем прошивку, какая подходит для снятия НФЗ – это 100 прошивка, у нас стоит 670 на ней стоит защита от отката, следовательно я не могу откатится и воспользоваться данным сертификатом для снятия ограничений.

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

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

Сообщение отредактировал Plavchikovich: 18 Август 2023 – 05:18

§

DiP,

А вот здесь лайк тебе, дружище !


А посмеялся я с сообщения, в котором аэропорт Якутска чуть ли не как Хитроу какой-нибудь преподносят. Даже в моем Владивостоке, крупнейшем аэропорте на ДВ, траффик более чем скромный по сравнению хотя бы с московским авиаузлом. Это было так трудно понять?

Прежде чем писать херню, достаточно погуглить.

Смотрите смешные цифры из годового отчёта за 2020 г., где в связи с пандемией пассажиропоток резко снизился. Самому было интересно.

Одних только самролётовылетов (без внутренних рейсов внутри республики) 7072, т.е. ок. 20-ти в сутки. По расписанию – сегодня 29 самолёторейсов (без внутренних). Это всё – без транзитных рейсов, малой авиации и вертолётов, а так же международныехаправлений в Корею, Китай, Вьетнам и Таиланд, в т.ч. транзитных.

Аэропорт «Якутск» используется в качестве запасного аэродрома и для технической посадки – дозаправки, технического обслуживания на кроссполярных, трансполярных и транссибирских международных воздушных трассах, а также в качестве международного полигона для испытаний воздушных судов в условиях экстремально низких температур, является запасным аэродромом для авиакомпании Global Aviation Consalting (США), член Ассоциации «Аэропорты гражданской авиации».

Между прочим, даже Боинги 777 там садятся !

Disable menu:

Set needed options to true

Comment line that enables interaction

Change from:

to:

Fake gps location

С этим приложением сымитируем, будто мы находимся в США или Боливии.
Делать это нужно дома, под крышей, чтобы дрон не поймал спутники GPS.

Установим Android приложение
Fake GPS Location
из Google Play.


Надо включить режим Разработчика в телефоне. В меню Настройки, О телефоне, найдите “Build number” или “версия MIUI”
и коснитесь этот пункт 7 раз. Должно появиться сообщение «Теперь вы Разработчик».

Теперь надо зайти в меню Разработчика, в Расширенных настройках найти «Приложение местоположения»и выбрать там Fake GPS Locaion.

Откроем приложение Fake GPS Location и на карты установим точку где-то в США или Боливии и нажмём кнопку с треугольником.
Теперь телефон станет полагать, что находится в том месте на карте. Это можно проверить в любом приложении, где показывается текущее положение, например, Яндекс Картах.

Faq – часто задаваемые вопросы

Для DJI Mini SE этот хак подходит?
Да. Пульт там тот же, что и у DJI Mavic Mini: модель MR1SD25. Но не подойдёт описанная в видео процедура.

Зато можно хакнуть с помощью iPhone. Хорошие люди записали подробное видео с инструкцией.
iPhone понадобится только раз, для применения хака. Летать потом можно с любым телефоном.
Для DJI Mini 2 этот хак подходит?
Нет. Хак только для пульта MR1SD25, который используется с дронами DJI Mavic Mini и Mini SE.
Можно ли после этого обновлять DJI Fly App?
Можно. Старая версия 1.1.2 была нужна только раз, в Шаге 1. После примения хака надо удалить старую версию. Установить и пользоваться самой свежей версией DJI Fly App с Google Play или сайта DJI. Пользоваться дроном как всегда.
Как этот хак работает?
Всё делает фокус с Fake GPS: дрон начинает думать, что он в США или Боливии и включает радио на полную. В других странах, по сравнению с ними, мощность и допустимые радио частоты ограничены. Кнопка на странице отправляет в пульт последовательность байтов, которые запрещают пульту в дальнейшем изменять настройки радио. Это не влияет на определение дроном своего местоположения. Он не улетит в Боливию )
Подробнее, технически, как работает этот хак?
Он изменяет единственную настройку: с disable_country=0 на disable_country=1 в файле конфигурации wifi.conf в пульте.
Специальная последовательность байтов отправленая в серийный порт через USB устанавливает эту настройку. Гуглите “DJI DUML” и “0x55 sequences”.

Байты, чтобы залочить страну:
0x55 0x0e 0x04 0x66 0x2a 0x1b 0x07 0x27 0x40 0x06 0xfb 0x02 0xac 0x35

Байты, чтобы вернуть заводскую настройку:

0x55 0x0e 0x04 0x66 0x2a 0x1b 0x25 0xf9 0x40 0x06 0xfb 0x03 0x9c 0x37

Frida hook library


The details below is a collection of Frida hooks, which we can use for our aircraft. New hooks will be added progressively. There are some tasks that need to be thought about so that we can make this scalable:

Hooking standard methods

Our work at the moment is focussed on IOS. As a general rule of thumb, we should where possible use the “swizzle” method of hooking. In the near future, this type of hook method will be able to be run on a modified app launched from Springboard. This is pending a patch from the author, but we know that this is a requirement. Not sure yet what standards if any are required for Android to ensure any protection is not tripped up.

Installation how-to

See: How to install the Patched DJI GO4 App on iPad or iPhone

Key features:

  1. Enables FCC on all devices and 5.8 on supported devices (changing country code to US)
  2. Enables BOOST, 32ch
  3. Disables Firmware checking
  4. Forces frequency to 2.3G or 2.5G

Tested on DJI Mavic Pro and DJI Inspire 2

Prettywoman

As part of this work, I looked at how to “standardise” our hooks, since they all appeared to be based on a couple of patterns. Below, you will find source and a CSV file for “PrettyWoman”. This app name was picked by Jezzab because “PrettyWoman – She was a hooker”.

Anyway. Naming conventions aside. How does it work? There is a shell script that parses a CSV file that contains configuration information for a list of hooks that will be created in the output.

Prettywoman.csv

Below is a CSV config file for PrettyWoman.sh. This file has the following fields:

PrettyWoman.csv
jsobject,AFSecurityPolicy,setSSLPinningMode,-,0,[*] SSL Pinning BYPASSED, [*] SSL Pinning not used this time,0
jsfunction,DJIAccountManager,checkIsAdminUser,-,1,[*] Flight Records admin user ENABLED,[*] Flight Records admin user already enabled,0
jsfunction,DJIAppSettings,canUseIllegalChannels,-,1,[*] Illegal Channels config (32) ENABLED,[*] Illegal Channels config (32) already enabled,0
jsfunction,DJIRadioLogic,canUseIllegalChannels,-,1,[*] Illegal Channels SDR (32) ENABLED,[*] Illegal Channels SDR(32) already enabled,0
jsfunction,DJIAppSettings,sdr_force_fcc,-,1,[*] Forced FCC Mode ACTIVATED,[*] Forced FCC mode already active,0
jsfunction,DJITermsNotificationController,shouldShowTerms,-,0,[*] Terms and conditions BYPASSED,[*] Terms and conditions already accepted,0
jsfunction,DJIAppForceUpdateManager,hasChecked,-,1,[*] Upgrade Check: DISABLED,[*] Upgrade Check: Already checked,0
jsfunction,DJIUpgradeNotifyViewModel,notifyHidden,-,1,[*] Upgrade Notification DISABLLED,[*] Upgrade Notification already disabled,0
jsfunctioniffcc,DJIProductManager,currentProductCode, ,13,[*] Changed product code to MAVIC,,1
jsfunction,DJILImitDBUpdateLogic,needUpdateType,-,0,[*] Removing NFZ DB Update Message,,0

Prettywoman.sh

PrettyWoman.sh
#!/bin/bash
 
function iosheader {cat<<EOF
//
// DJI GO 4 - Frida Tweaks
//
 
if (ObjC.available) {
 
EOF}
 
function iosfooter {cat<<EOF
}
EOF}
 
function functionheader {cat<<EOF
 
  //
  // ${1}
  //
 
EOF}function jsobject {
 
cat<<EOF
  var ${1} = ObjC.classes.${1};
  var ${3} = ${1}['${2} ${3}:'];
  var ${3}Impl = ${3}.implementation;
  ${3}.implementation = ObjC.implement(${3}, function (handle, selector, originalResult) {
    ${3}Impl(handle, selector, ${4});
    if ( originalResult != ${4} ) {
      if ( ${7} == 0 || ${CLASS}${METHOD}SeenReplace == 0 ) {
        console.log("${5}");
        ${CLASS}${METHOD}SeenReplace = 1;
      }
    } else {
      if ( ${7} == 0 || ${CLASS}${METHOD}SeenHit == 0 ) {
        console.log("${6}");
        ${CLASS}${METHOD}SeenHit = 1;
      }
    }
  });
EOF}
 
function jsfunction {cat<<EOF
  var ${1} = ObjC.classes.${1};
  var ${3} = ${1}['${2} ${3}'];
  var ${3}Impl = ${3}.implementation;
  ${3}.implementation = ObjC.implement(${3}, function (handle, selector) {
    var originalResult = ${3}Impl(handle, selector);
    if ( originalResult != ${4} ) {
      if ( ${7} == 0 || ${CLASS}${METHOD}SeenReplace == 0 ) {
        console.log("${5}");
        ${CLASS}${METHOD}SeenReplace = 1;
      }
    } else {
      if ( ${7} == 0 || ${CLASS}${METHOD}SeenHit == 0 ) {
        console.log("${6}");
        ${CLASS}${METHOD}SeenHit = 1;
      }
    }
    return ${4};
  });
EOF}
 
 
function jsfunctioniffcc {cat<<EOF
  var ${1} = ObjC.classes.${1};
  var ${3} = ${1}['${2} ${3}'];
  var ${3}Impl = ${3}.implementation;
  ${3}.implementation = ObjC.implement(${3}, function (handle, selector) {
    var originalResult = ${3}Impl(handle, selector);
    if ( originalResult != ${4} ) {
      if ( ${7} == 0 || ${CLASS}${METHOD}SeenReplace == 0 ) {
        console.log("${5}");
        ${CLASS}${METHOD}SeenReplace = 1;
      }
    }
 
    if( DJIAppSettingssdr_force_fccSeenReplace == 0 ) {
      return ${4}; //mavic
    } else {
      return originalResult;
    }
  });
EOF}
 
 
function defines {cat<<EOF
//
// Create variables that we can use for "one shot" rules
//
EOF
 
whileread X
do#TEMPLATE=`echo $X | cut -d "," -f 1`CLASS=`echo$X|cut-d","-f2`METHOD=`echo$X|cut-d","-f3`PLUSMINUS=`echo$X|cut-d","-f4`#REPLACE=`echo $X | cut -d "," -f 5`#LOGHIT=`echo $X | cut -d "," -f 6`#LOGCHANGED=`echo $X | cut -d "," -f 7`#ONESHOT=`echo $X | cut -d "," -f 8`
 
	echo"${CLASS}${METHOD}SeenHit=0;"echo"${CLASS}${METHOD}SeenReplace=0;"
 
done< PrettyWoman.csv
}
 
function mainloop {whileread X
doTEMPLATE=`echo$X|cut-d","-f1`CLASS=`echo$X|cut-d","-f2`METHOD=`echo$X|cut-d","-f3`PLUSMINUS=`echo$X|cut-d","-f4`REPLACE=`echo$X|cut-d","-f5`LOGHIT=`echo$X|cut-d","-f6`LOGCHANGED=`echo$X|cut-d","-f7`ONESHOT=`echo$X|cut-d","-f8`
 
        functionheader "${CLASS}${METHOD}${TEMPLATE}"${TEMPLATE}${CLASS}${PLUSMINUS}${METHOD}${REPLACE}"${LOGHIT}""${LOGCHANGED}""0${ONESHOT}"done< PrettyWoman.csv
}
 
iosheader
defines
mainloop
iosfooter

Roadmap:

  1. Disable NFZ Checking
  2. Disable Quiz pop-up

Template hook

We should look at creating a few template hooks. So far, we have a simple bool replacement template that we have used in three cases successfully. But, what about other more complex requirements. What if we need to read parameters etc? The author of Frida has advised:

oleavr: method arguments follow self and sel (the first two implicit arguments). you can use var self = new ObjC.Object(handle); then you can access the instance variables of self through self.$ivars depending on whether you want to access method arguments or instance variables (or other things on the instance)

We’ll dig into this more later when/if we need to access parameter data etc.

Tweak.js

This code was generated by PrettyWoman.sh – using the CSV file above. Feel free to just use this set of hooks for your tweaking pleasure.

Tweak.js
//// DJI GO 4 - Frida Tweaks//
 
if(ObjC.available){
 
//// Create variables that we can use for "one shot" rules//
AFSecurityPolicysetSSLPinningModeSeenHit=0;
AFSecurityPolicysetSSLPinningModeSeenReplace=0;
DJIAccountManagercheckIsAdminUserSeenHit=0;
DJIAccountManagercheckIsAdminUserSeenReplace=0;
DJIAppSettingscanUseIllegalChannelsSeenHit=0;
DJIAppSettingscanUseIllegalChannelsSeenReplace=0;
DJIRadioLogiccanUseIllegalChannelsSeenHit=0;
DJIRadioLogiccanUseIllegalChannelsSeenReplace=0;
DJIAppSettingssdr_force_fccSeenHit=0;
DJIAppSettingssdr_force_fccSeenReplace=0;
DJITermsNotificationControllershouldShowTermsSeenHit=0;
DJITermsNotificationControllershouldShowTermsSeenReplace=0;
DJIAppForceUpdateManagerhasCheckedSeenHit=0;
DJIAppForceUpdateManagerhasCheckedSeenReplace=0;
DJIUpgradeNotifyViewModelnotifyHiddenSeenHit=0;
DJIUpgradeNotifyViewModelnotifyHiddenSeenReplace=0;
DJIProductManagercurrentProductCodeSeenHit=0;
DJIProductManagercurrentProductCodeSeenReplace=0;
 
  //// AFSecurityPolicy setSSLPinningMode jsobject//
 
  var AFSecurityPolicy = ObjC.classes.AFSecurityPolicy;
  var setSSLPinningMode = AFSecurityPolicy['- setSSLPinningMode:'];
  var setSSLPinningModeImpl = setSSLPinningMode.implementation;
  setSSLPinningMode.implementation= ObjC.implement(setSSLPinningMode, function (handle, selector, originalResult){
    setSSLPinningModeImpl(handle, selector, 0);if( originalResult !=0){if( 00 ==0|| AFSecurityPolicysetSSLPinningModeSeenReplace ==0){
        console.log("[*] SSL Pinning BYPASSED");
        AFSecurityPolicysetSSLPinningModeSeenReplace =1;}}else{if( 00 ==0|| AFSecurityPolicysetSSLPinningModeSeenHit ==0){
        console.log(" [*] SSL Pinning not used this time");
        AFSecurityPolicysetSSLPinningModeSeenHit =1;}}});
 
  //// DJIAccountManager checkIsAdminUser jsfunction//
 
  var DJIAccountManager = ObjC.classes.DJIAccountManager;
  var checkIsAdminUser = DJIAccountManager['- checkIsAdminUser'];
  var checkIsAdminUserImpl = checkIsAdminUser.implementation;
  checkIsAdminUser.implementation= ObjC.implement(checkIsAdminUser, function (handle, selector){
    var originalResult = checkIsAdminUserImpl(handle, selector);if( originalResult !=1){if( 00 ==0|| DJIAccountManagercheckIsAdminUserSeenReplace ==0){
        console.log("[*] Flight Records admin user ENABLED");
        DJIAccountManagercheckIsAdminUserSeenReplace =1;}}else{if( 00 ==0|| DJIAccountManagercheckIsAdminUserSeenHit ==0){
        console.log("[*] Flight Records admin user already enabled");
        DJIAccountManagercheckIsAdminUserSeenHit =1;}}return1;});
 
  //// DJIAppSettings canUseIllegalChannels jsfunction//
 
  var DJIAppSettings = ObjC.classes.DJIAppSettings;
  var canUseIllegalChannels = DJIAppSettings['- canUseIllegalChannels'];
  var canUseIllegalChannelsImpl = canUseIllegalChannels.implementation;
  canUseIllegalChannels.implementation= ObjC.implement(canUseIllegalChannels, function (handle, selector){
    var originalResult = canUseIllegalChannelsImpl(handle, selector);if( originalResult !=1){if( 00 ==0|| DJIAppSettingscanUseIllegalChannelsSeenReplace ==0){
        console.log("[*] Illegal Channels config (32) ENABLED");
        DJIAppSettingscanUseIllegalChannelsSeenReplace =1;}}else{if( 00 ==0|| DJIAppSettingscanUseIllegalChannelsSeenHit ==0){
        console.log("[*] Illegal Channels config (32) already enabled");
        DJIAppSettingscanUseIllegalChannelsSeenHit =1;}}return1;});
 
  //// DJIRadioLogic canUseIllegalChannels jsfunction//
 
  var DJIRadioLogic = ObjC.classes.DJIRadioLogic;
  var canUseIllegalChannels = DJIRadioLogic['- canUseIllegalChannels'];
  var canUseIllegalChannelsImpl = canUseIllegalChannels.implementation;
  canUseIllegalChannels.implementation= ObjC.implement(canUseIllegalChannels, function (handle, selector){
    var originalResult = canUseIllegalChannelsImpl(handle, selector);if( originalResult !=1){if( 00 ==0|| DJIRadioLogiccanUseIllegalChannelsSeenReplace ==0){
        console.log("[*] Illegal Channels SDR (32) ENABLED");
        DJIRadioLogiccanUseIllegalChannelsSeenReplace =1;}}else{if( 00 ==0|| DJIRadioLogiccanUseIllegalChannelsSeenHit ==0){
        console.log("[*] Illegal Channels SDR(32) already enabled");
        DJIRadioLogiccanUseIllegalChannelsSeenHit =1;}}return1;});
 
  //// DJIAppSettings sdr_force_fcc jsfunction//
 
  var DJIAppSettings = ObjC.classes.DJIAppSettings;
  var sdr_force_fcc = DJIAppSettings['- sdr_force_fcc'];
  var sdr_force_fccImpl = sdr_force_fcc.implementation;
  sdr_force_fcc.implementation= ObjC.implement(sdr_force_fcc, function (handle, selector){
    var originalResult = sdr_force_fccImpl(handle, selector);if( originalResult !=1){if( 00 ==0|| DJIAppSettingssdr_force_fccSeenReplace ==0){
        console.log("[*] Forced FCC Mode ACTIVATED");
        DJIAppSettingssdr_force_fccSeenReplace =1;}}else{if( 00 ==0|| DJIAppSettingssdr_force_fccSeenHit ==0){
        console.log("[*] Forced FCC mode already active");
        DJIAppSettingssdr_force_fccSeenHit =1;}}return1;});
 
  //// DJITermsNotificationController shouldShowTerms jsfunction//
 
  var DJITermsNotificationController = ObjC.classes.DJITermsNotificationController;
  var shouldShowTerms = DJITermsNotificationController['- shouldShowTerms'];
  var shouldShowTermsImpl = shouldShowTerms.implementation;
  shouldShowTerms.implementation= ObjC.implement(shouldShowTerms, function (handle, selector){
    var originalResult = shouldShowTermsImpl(handle, selector);if( originalResult !=0){if( 00 ==0|| DJITermsNotificationControllershouldShowTermsSeenReplace ==0){
        console.log("[*] Terms and conditions BYPASSED");
        DJITermsNotificationControllershouldShowTermsSeenReplace =1;}}else{if( 00 ==0|| DJITermsNotificationControllershouldShowTermsSeenHit ==0){
        console.log("[*] Terms and conditions already accepted");
        DJITermsNotificationControllershouldShowTermsSeenHit =1;}}return0;});
 
  //// DJIAppForceUpdateManager hasChecked jsfunction//
 
  var DJIAppForceUpdateManager = ObjC.classes.DJIAppForceUpdateManager;
  var hasChecked = DJIAppForceUpdateManager['- hasChecked'];
  var hasCheckedImpl = hasChecked.implementation;
  hasChecked.implementation= ObjC.implement(hasChecked, function (handle, selector){
    var originalResult = hasCheckedImpl(handle, selector);if( originalResult !=1){if( 00 ==0|| DJIAppForceUpdateManagerhasCheckedSeenReplace ==0){
        console.log("[*] Upgrade Check: DISABLED");
        DJIAppForceUpdateManagerhasCheckedSeenReplace =1;}}else{if( 00 ==0|| DJIAppForceUpdateManagerhasCheckedSeenHit ==0){
        console.log("[*] Upgrade Check: Already checked");
        DJIAppForceUpdateManagerhasCheckedSeenHit =1;}}return1;});
 
  //// DJIUpgradeNotifyViewModel notifyHidden jsfunction//
 
  var DJIUpgradeNotifyViewModel = ObjC.classes.DJIUpgradeNotifyViewModel;
  var notifyHidden = DJIUpgradeNotifyViewModel['- notifyHidden'];
  var notifyHiddenImpl = notifyHidden.implementation;
  notifyHidden.implementation= ObjC.implement(notifyHidden, function (handle, selector){
    var originalResult = notifyHiddenImpl(handle, selector);if( originalResult !=1){if( 00 ==0|| DJIUpgradeNotifyViewModelnotifyHiddenSeenReplace ==0){
        console.log("[*] Upgrade Notification DISABLLED");
        DJIUpgradeNotifyViewModelnotifyHiddenSeenReplace =1;}}else{if( 00 ==0|| DJIUpgradeNotifyViewModelnotifyHiddenSeenHit ==0){
        console.log("[*] Upgrade Notification already disabled");
        DJIUpgradeNotifyViewModelnotifyHiddenSeenHit =1;}}return1;});
 
  //// DJIProductManager currentProductCode jsfunctioniffcc//
 
  var DJIProductManager = ObjC.classes.DJIProductManager;
  var currentProductCode = DJIProductManager['  currentProductCode'];
  var currentProductCodeImpl = currentProductCode.implementation;
  currentProductCode.implementation= ObjC.implement(currentProductCode, function (handle, selector){
    var originalResult = currentProductCodeImpl(handle, selector);if( originalResult !=13){if( 01 ==0|| DJIProductManagercurrentProductCodeSeenReplace ==0){
        console.log("[*] Changed product code to MAVIC");
        DJIProductManagercurrentProductCodeSeenReplace =1;}}
 
    if( DJIAppSettingssdr_force_fccSeenReplace ==0){return13;//mavic}else{return originalResult;}});
 
  //// DJILImitDBUpdateLogic needUpdateType jsfunction//
 
  var DJILImitDBUpdateLogic = ObjC.classes.DJILImitDBUpdateLogic;
  var needUpdateType = DJILImitDBUpdateLogic['- needUpdateType'];
  var needUpdateTypeImpl = needUpdateType.implementation;
  needUpdateType.implementation= ObjC.implement(needUpdateType, function (handle, selector){
    var originalResult = needUpdateTypeImpl(handle, selector);if( originalResult !=0){if( 00 ==0|| DJILImitDBUpdateLogicneedUpdateTypeSeenReplace ==0){
        console.log("[*] Removing NFZ DB Update Message");
        DJILImitDBUpdateLogicneedUpdateTypeSeenReplace =1;}}else{if( 00 ==0|| DJILImitDBUpdateLogicneedUpdateTypeSeenHit ==0){
        console.log("");
        DJILImitDBUpdateLogicneedUpdateTypeSeenHit =1;}}return0;});}

Благодарности

Идея хака и «волшебные» байты: русскоязычный Telegram чат @mavicminirus

Видео

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

Включаем дрон

Подключите пульт к телефону, включите пульт и запустите DJI Fly App 1.1.2
Включите дрон.
Дождитесь, чтобы дрон соединился с пультом.

В приложении должно появиться сообщение типа

    Идёт сброс настроек беспроводного подключения,
    чтобы соответствовать местным правилам.
    Попробуйте подключиться позднее.

Это значит, что всё идёт как надо.
Нажмите меню три точки справа сверху и зайдите во вкладку «Передача»

Там должно быть видно частоту 5.8 GHz и в графике должны появиться WiFi каналы 1..13 и 149..165.
Теперь осталось зафиксировать этот режим, чтобы он не соскочил.

Выключите дрон, пульт и отключите пульт от телефона.

Как откатить хак

Чтобы вернуть ваш пульт в его «заводское» состояние:

  1. Подключите пульт к этому компу USB-кабелем
  2. Включите пульт
  3. Нажмите кнопку ниже и выберите в списке серийный порт вашего пульта (“Gadget Serial v2_4”):

План действий

  1. в браузере включить «экспериментальные возможности» (Experimental features)
  2. подключить пульт к компу кабелем
  3. включить пульт
  4. нажать кнопку ниже
  5. в появившемся меню выбрать пульт

После хака

  1. Отключите (и можно вообще удалить) приложение Fake GPS Location
  2. Удалить старую версию DJI Fly App 1.1.2
  3. Установите свежую версию DJI Fly App из Google Play или с сайта DJI

Предупреждение

Это эксперимент исключительно в образовательных целях.

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

Преимущества твика

При использовании твика пилот получает раскрывает все возможности дрона. Это обеспечивает:

  • Стабильный сигнал в режиме FCC с активацией частоты 5.8 ГГц.
  • Максимальную дальность полета
  • Возможность полетов без точного направления контроллера на дрон при полетах вокруг себя.
  • Возможность управления дроном из автомобиля. Актуально в зимнее время года.
  • Спокойствие и концентрацию на съемках, а не на качестве сигнала.

Минусов использования твика нет. Отзывы о работе DJI Fly Plus мы собираем на странице с отзывами.

Про режимы fcc и ce

FCC — это федеральная комиссия радиосвязи в США. Ею регламентирована мощность излучения различных электронных устройств. Для простоты взята аббревиатура стандарта этой организации. По стандарту максимальная мощность излучения ограничена 400 мВт. (<=26 дБм).

CE режим назван по аббревиатуре, которая расшифровывается как «Европейское соответствие». Увы, разрешенная мощность сигнала в режиме CE сильно ниже.

FCС режим активирует работу дрона на максимально возможной мощности до 400 мВт. Это обеспечит стабильную связь и предельную дальность полета.

Режим FCC по умолчанию активен в небольшом списке стран (США, Боливия и др.). В большей части земного шара коптеры работают на пониженной мощности.

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

К счастью, для обхода ограничений был найден легкий и безболезненный способ — твик, о нем дальше в статье. Установить твик вы можете перейдя по данной ссылке или в телеграмме. Попробовав режим максимальной мощности, возвращаться в режим ограниченной мощности нет никакого желания. При первом полете в FCC создается ощущение полета на совершенно другом, более «прокаченном» дроне.

Прокачаем браузер

Чтобы работать с серийным портом, сейчас потребуется включить Экспериментальные возможности. Скопируйте ниже строку, соответствующую вашему браузеру и вставьте её в адресную строку:

chrome://flags/#enable-experimental-web-platform-features

opera://flags/#enable-experimental-web-platform-features

edge://flags/#enable-experimental-web-platform-features
    

Там в странице настроек включите “Experimental Web Platform Features”. Браузер попросит перезапустить его.

Разница мощности режимов fcc и ce

Мощность сигнала в режимах FCC и CE различается значительно. В FCC она ограничена 400 мВт. Запомним эту цифру. В большинстве стран мира, Европе, в том числе и России дроны летают в режиме CE. В нем мощность излучения не превышает 100 мВт на частоте 2.4 ГГц. На частоте 5.

8 дроны летают на еще более низкой мощности 25 мВт. Но 5.8 изначально у нас недоступна. FCC мощнее CE режима в СНГ в 4 раза. Если бы у нас был доступен диапазон 5.8 из коробки, то разница с США в 5.8 достигала 16 раз! Тоесть мощность излучения в FCC режиме для диапазонов 2.4 и 5.8 одинакова.

Теперь становится понятно, почему в режиме CE в городских условиях дроны улетают на сотни метров и теряют связь. А в FCC дальность исчисляется километрами без помех и задержек картинки.

Теоретически в режиме FCC обеспечивается дальность до 10-12 километров на открытой местности, если не брать в расчет емкость аккумулятора. С учетом батареи и возвратом к точке взлета, дальность в безветренную погоду ограничена примерно 5-7 километрами.

На видео ниже видно можно увидеть разницу по уровню сигнала между режимами.

Но не везде существуют ограничения, есть приятные исключения в некоторых странах СНГ. К примеру, в Беларуси дроны DJI работают в режиме FCC и присутствует частота 5.8, как и в США. А в Казахстане дроны хоть и летают в FCC, но только на 2.4 ГГц. Частота 5.8 под запретом, приходится использовать твик.

Хакнем пульт

  1. Подключите ваш пульт USB-кабелем к этому компьютеру.
  2. Включите пульт.
  3. Нажмите кнопку ниже. Появится окно выбора серийного порта – выберите там ваш пульт. У меня на Маке он называется “Gadget Serial v2_4”.

Частота передачи сигнала. зачем нужен 5.8 ггц

Помимо мощности, для передачи также важна частота передачи сигнала. Как и режим FCC (максимальная мощности), этот параметр зависит от законодательства текущего государства.

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

На 2.4 ГГц обеспечивается наибольшая дальность сигнала. Но на практике это работает только на открытой местности вне города. В городских условиях частота 2.4 ГГц сильно «зашумлена» источниками, например Wi-Fi точками доступа.

Поэтому в городских условиях дроны стабильнее и дальше летают на частоте 5.8. Но в большинстве стран частота 5.8 ГГц закрыта для полетов любительских дронов. Из-за этого владельцы дронов сталкиваются с потерей сигнала в сотнях метров от точки взлета.

Дроны DJI могут обеспечивать передачу сигнала на частотах 2.4 ГГц и 5.8 ГГц. На частоте 2.4 ГГц дрон улетает дальше на открытой местности, а на 5.8 ГГц лучше связь держит в городской среде, где частота в 2.4 ГГц имеет много помех в виде Wi-Fi и других источников излучения. Твик позволяет разблокировать обе частоты.

Шаг 1

На Android телефон установим:

  • старую версию приложения DJI Fly App 1.1.2
  • приложение Fake GPS Location

Шаг 2

Поменяем в пульте одну настройку, чтобы выбранный в Шаге-1 режим сохранился.

Понадобится:

  1. Компьютер с любой ОС и браузером: Chrome, Opera или Edge.

    Safari, FireFox не годятся;
  2. ваш пульт от Mavic Mini;
  3. USB кабель, чтобы подключить пульт к компу – он есть в комплекте дрона.
Оцените статью
Радиокоптер.ру
Добавить комментарий