Jump to content

Remove CE limits from DJI products and other fun stuff in DJI Go4


Bin4ry

Recommended Posts

  • 2 weeks later...
  • 3 weeks later...

hi guys, maybe you can give me the missing clue? trying to set FCC on my mavic pro and it dont really worked. max. range is always 900m :-(

patched .14/.15.neo version (windows) on my own with deejayeye-modder as shown in the readme. AC/FC .700 Firmware installed, android 7.1.1. no root

order of turning on devices with AirplaneMode enabled -> patched app, Remote, waiting for pop up and choosing DJI GO, when the app is open turning on AC.

log under ../log/cache/areacode shows  following:

2018-01-29 06:23:08:919 E: init success
2018-01-29 06:23:08:922 E: --------DeviceAC getRcVer:mRcVer =
2018-01-29 06:23:08:927 E: --------DeviceAC closeJp57
2018-01-29 06:23:08:932 E: --------DeviceAC getCcFromRc onFailure:ccodeNOCONNECTccrc4549
2018-01-29 06:23:08:939 E: --------DeviceAC getCcFromRc onFailure:ccode=NOCONNECTmCcFromRc=-1
2018-01-29 06:23:09:015 E: --------DeviceAC activity event
2018-01-29 06:23:09:701 E: --------DeviceAC activity event
2018-01-29 06:23:14:551 E: --------DeviceAC activity event
2018-01-29 06:23:35:984 E: --------DeviceAC 【国家码获取(get)】触发点::遥控器重连,DataEvent = ConnectOK
2018-01-29 06:23:35:994 E: --------DeviceAC getRcVer:mRcVer =
2018-01-29 06:23:36:005 E: --------DeviceAC closeJp57
2018-01-29 06:23:36:191 E: --------DeviceAC getRcVer:onSuccess,mRcVer = 00.01.00.01
2018-01-29 06:23:37:478 E: --------DeviceAC activity event
2018-01-29 06:23:38:013 E: --------DeviceAC getCcFromRc onFailure:ccodeTIMEOUTccrc4549
2018-01-29 06:23:38:021 E: --------DeviceAC getCcFromRc onFailure:ccode=TIMEOUTmCcFromRc=-1
2018-01-29 06:23:39:746 E: first get p loc
2018-01-29 06:23:39:788 E: -------start load city list--------
2018-01-29 06:23:40:438 E: city list load finish
2018-01-29 06:23:40:529 E: build kdtree finish count=xxxxxxx6
2018-01-29 06:23:40:546 E: find near city=US, index=99
2018-01-29 06:23:41:583 E: --------DeviceAC activity event
2018-01-29 06:23:43:350 E: --------DeviceAC activity event
2018-01-29 06:23:43:766 E: -------start load city list--------
2018-01-29 06:23:43:789 E: on p loc change dis=xxxxxxx.5
2018-01-29 06:23:44:555 E: city list load finish
2018-01-29 06:23:44:647 E: build kdtree finish count=xxxxxxxx6
2018-01-29 06:23:44:663 E: find near city=US, index=99
2018-01-29 06:24:44:736 E: on p loc change dis=x.yyyyyyyy7
2018-01-29 06:25:45:731 E: on p loc change dis=x.yyyyyyyy5

what am i missing?

thanks!

Link to comment
Share on other sites

  • 3 months later...
  • 1 month later...
On 7/4/2017 at 12:57 PM, Bin4ry said:

Hey, 

Update:

You can find the Modding tool on github: https://github.com/Bin4ry/deejayeye-modder

Feel free to contribute. 

 

i saw that here are already 2 topics regarding DJI products and their limitations, so i guessed it is ok to show you some of my recent work here. I don't want to introduce myself here too much, if you want to know something about me find me on XDA. 

Ok, so i recently bought a DJI spark, and i tried to come up with a way to remove the CE transmission limit without rooting the drone (because technically this is not my drone but my wifes ? ) and i started with reversing the dji go app. What i found was this part of code which is called when the app is started (this is decompiled from classes4.dex, because of that the code looks strange):


public void a(String paramString1, String paramString2, dji.pilot.countrycode.model.a parama1, dji.pilot.countrycode.model.a parama2, a parama)
  {
    boolean bool = dji.pilot2.usercenter.activate.c.d(DJIApplication.getAppContext());
    StringBuilder localStringBuilder = new StringBuilder(40);
    if ((!parama1.a()) && (bool))
    {
      a(paramString1, paramString2, parama1, parama);
      localStringBuilder.append("飞机GPS获得,采取策略1:UavGps策略");  //Aircraft GPS gets, take strategy 1: UavGps strategy
    }
    for (;;)
    {
      a.a(this.c, "【国家码获取(get)】触发后策略选择: " + localStringBuilder); //[Country code get (get)] After the trigger strategy selection:
      return;
      if ((!parama2.a()) && (bool))
      {
        b(paramString1, paramString2, parama2, parama);
        localStringBuilder.append("飞机GPS没有获得,手机GPS获得,采取策略2:MobileGps策略"); //Aircraft GPS does not get, mobile GPS gets, take strategy 2: MobileGps strategy
      }
      else if (a(parama, false, -1))
      {
        localStringBuilder.append("飞机GPS没有获得,手机GPS没有获得,mCC获得,采取策略3:Mcc策略"); //Aircraft GPS did not get, cell phone GPS did not get, mCC get, take strategy 3: Mcc strategy
      }
      else if (bool)
      {
        a(paramString1, paramString2, parama);
        localStringBuilder.append("飞机GPS没有获得,手机GPS没有获得,mCC没有获得,采取策略4:IP策略"); //Aircraft GPS did not get, cell phone GPS did not get, mCC did not get, take strategy 4: IP strategy
      }
      else
      {
        parama.a(-1, "get cc failure for network is disconnect");
      }
    }
  }

I added comments to translate the chinese stuff. So what this code does is simple, it has a few checks and goes through a strategy to determine which limitations it should apply. 

1.) check if aircraft has gps -> if yes, use the coords to determine which country (done on phone!)

2.) if 1 failed -> check if mobile has gps ......

3.) if 2 failed -> check if mobile has SIM, if yes look for MCC and determine sim country

4.) if 3 failed -> check if mobile has internet, if yes go to: https://mydjiflight.dji.com/api/v2/geocoder_service/geoip and parse the json result

 

Ok, so there are a few ways to get the app think we are located in the US to get FCC limits instead of CE. First i modified the above functions smali code to represent something lilke this java code: 


    public void a(String string, String string2, dji.pilot.countrycode.model.a a2, dji.pilot.countrycode.model.a a3, a a4) {
        c.d((Context)DJIApplication.getAppContext());
        StringBuilder stringBuilder = new StringBuilder(40);
        a2.a();
        this.a(a4, false, -1);
        stringBuilder.append("Call to fake function which will always answer with US MCC");
        dji.pilot.countrycode.a.a.a((Context)this.c, (String)("Going to use fake function to always return US MCC: " + stringBuilder));
    }

also i modified the function which it calls.

Before:


 private boolean a(a parama, boolean paramBoolean, int paramInt)
  {
    String str = ((TelephonyManager)this.c.getSystemService("phone")).getNetworkCountryIso();
    if (!TextUtils.isEmpty(str))
    {
      this.b[b.c.ordinal()] = str.toUpperCase();
      parama.a(a(), "getFromMcc");
      return true;
    }
    if (paramBoolean) {
      parama.a(paramInt, "getFromMcc():CountryCode is empty !");
    }
    return false;
  }

After:


    private boolean a(a a2, boolean bl, int n) {
        if (!TextUtils.isEmpty((CharSequence)"us")) {
            this.b[b.c.ordinal()] = "us".toUpperCase();
            a2.a(this.a(), "getFromMcc");
            return true;
        }
        if (!bl) return false;
        a2.a(n, "getFromMcc():CountryCode is empty !");
        return false;
    }

 

So the new program flow is:

1.) call MCC function -> MCC function answers "us" ?

 

I've done the changes directly in the smali code and put it together again to a dex file, then i packed the dex file into the apk, removed the manifest.mf with its signatures and signed the whole file again with testkeys. 

You can find the modified apk (based on version 4.1.3) here if you don't want to put together your own version (you will have to remove the original apk first because this one is signed with a testkey and not with dji's key): 

!Downloadlink removed!

I have not had time to test the range yet, but i am pretty sure it should work if there is no other check involved. As far as i was able to understand this check should be the same for all dji products which use the DJIGo4 App, so if you have multiple products this should work for all of them at the same time ?

I hope i was able to contribute here and would love to hear some of your thoughts. 

 

Best Regards

Bin4ry

 

On 7/4/2017 at 12:57 PM, Bin4ry said:

Hey, 

Update:

You can find the Modding tool on github: https://github.com/Bin4ry/deejayeye-modder

Feel free to contribute. 

 

i saw that here are already 2 topics regarding DJI products and their limitations, so i guessed it is ok to show you some of my recent work here. I don't want to introduce myself here too much, if you want to know something about me find me on XDA. 

Ok, so i recently bought a DJI spark, and i tried to come up with a way to remove the CE transmission limit without rooting the drone (because technically this is not my drone but my wifes ? ) and i started with reversing the dji go app. What i found was this part of code which is called when the app is started (this is decompiled from classes4.dex, because of that the code looks strange):


public void a(String paramString1, String paramString2, dji.pilot.countrycode.model.a parama1, dji.pilot.countrycode.model.a parama2, a parama)
  {
    boolean bool = dji.pilot2.usercenter.activate.c.d(DJIApplication.getAppContext());
    StringBuilder localStringBuilder = new StringBuilder(40);
    if ((!parama1.a()) && (bool))
    {
      a(paramString1, paramString2, parama1, parama);
      localStringBuilder.append("飞机GPS获得,采取策略1:UavGps策略");  //Aircraft GPS gets, take strategy 1: UavGps strategy
    }
    for (;;)
    {
      a.a(this.c, "【国家码获取(get)】触发后策略选择: " + localStringBuilder); //[Country code get (get)] After the trigger strategy selection:
      return;
      if ((!parama2.a()) && (bool))
      {
        b(paramString1, paramString2, parama2, parama);
        localStringBuilder.append("飞机GPS没有获得,手机GPS获得,采取策略2:MobileGps策略"); //Aircraft GPS does not get, mobile GPS gets, take strategy 2: MobileGps strategy
      }
      else if (a(parama, false, -1))
      {
        localStringBuilder.append("飞机GPS没有获得,手机GPS没有获得,mCC获得,采取策略3:Mcc策略"); //Aircraft GPS did not get, cell phone GPS did not get, mCC get, take strategy 3: Mcc strategy
      }
      else if (bool)
      {
        a(paramString1, paramString2, parama);
        localStringBuilder.append("飞机GPS没有获得,手机GPS没有获得,mCC没有获得,采取策略4:IP策略"); //Aircraft GPS did not get, cell phone GPS did not get, mCC did not get, take strategy 4: IP strategy
      }
      else
      {
        parama.a(-1, "get cc failure for network is disconnect");
      }
    }
  }

I added comments to translate the chinese stuff. So what this code does is simple, it has a few checks and goes through a strategy to determine which limitations it should apply. 

1.) check if aircraft has gps -> if yes, use the coords to determine which country (done on phone!)

2.) if 1 failed -> check if mobile has gps ......

3.) if 2 failed -> check if mobile has SIM, if yes look for MCC and determine sim country

4.) if 3 failed -> check if mobile has internet, if yes go to: https://mydjiflight.dji.com/api/v2/geocoder_service/geoip and parse the json result

 

Ok, so there are a few ways to get the app think we are located in the US to get FCC limits instead of CE. First i modified the above functions smali code to represent something lilke this java code: 


    public void a(String string, String string2, dji.pilot.countrycode.model.a a2, dji.pilot.countrycode.model.a a3, a a4) {
        c.d((Context)DJIApplication.getAppContext());
        StringBuilder stringBuilder = new StringBuilder(40);
        a2.a();
        this.a(a4, false, -1);
        stringBuilder.append("Call to fake function which will always answer with US MCC");
        dji.pilot.countrycode.a.a.a((Context)this.c, (String)("Going to use fake function to always return US MCC: " + stringBuilder));
    }

also i modified the function which it calls.

Before:


 private boolean a(a parama, boolean paramBoolean, int paramInt)
  {
    String str = ((TelephonyManager)this.c.getSystemService("phone")).getNetworkCountryIso();
    if (!TextUtils.isEmpty(str))
    {
      this.b[b.c.ordinal()] = str.toUpperCase();
      parama.a(a(), "getFromMcc");
      return true;
    }
    if (paramBoolean) {
      parama.a(paramInt, "getFromMcc():CountryCode is empty !");
    }
    return false;
  }

After:


    private boolean a(a a2, boolean bl, int n) {
        if (!TextUtils.isEmpty((CharSequence)"us")) {
            this.b[b.c.ordinal()] = "us".toUpperCase();
            a2.a(this.a(), "getFromMcc");
            return true;
        }
        if (!bl) return false;
        a2.a(n, "getFromMcc():CountryCode is empty !");
        return false;
    }

 

So the new program flow is:

1.) call MCC function -> MCC function answers "us" ?

 

I've done the changes directly in the smali code and put it together again to a dex file, then i packed the dex file into the apk, removed the manifest.mf with its signatures and signed the whole file again with testkeys. 

You can find the modified apk (based on version 4.1.3) here if you don't want to put together your own version (you will have to remove the original apk first because this one is signed with a testkey and not with dji's key): 

!Downloadlink removed!

I have not had time to test the range yet, but i am pretty sure it should work if there is no other check involved. As far as i was able to understand this check should be the same for all dji products which use the DJIGo4 App, so if you have multiple products this should work for all of them at the same time ?

I hope i was able to contribute here and would love to hear some of your thoughts. 

 

Best Regards

Bin4ry

I have a phantom 4 pro plus , and i need to change frontal CE to FCC..

can you explain wo make this ??

i apreciate your help

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...