User Tools

Site Tools

Translations of this page:

howto:fridahooklibrary

This is an old revision of the document!


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:

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.

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.

Configuration

The config below can be used for stand-alone hooks, allowing you to open DJI GO 4 from springboard.

FridaGadget.config
{
  "interaction": {
    "type": "script",
    "path": "Tweak.js",
    "on_change": "reload"
  },
  "code_signing": "required"
}

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.

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.

Hooks

DJITermsNotificationController - shouldShowTerms

DJITermsNotificationController.shouldShowTerms.js
'use strict';
if (ObjC.available) {
 
  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);
    console.log('Original says:', originalResult, 'we say: 0');
    return 0;
  });
}

DJIAppSettings - sdr_force_fcc

DJIAppSettings.sdr_force_fcc.js
if (ObjC.available) {
  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);
    console.log('DJIAppSettings:sdr_force_fcc  Original says:', originalResult, 'we say: 1');
    return 1;
  });
}

canUseIllegalChannels

DJIAppSettings.canUseIllegalChannels.js
if (ObjC.available) {
  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);
    console.log('DJIAppSettings:canUseIllegalChannels  Original says:', originalResult, 'we say: 1');
    return 1;
  });
 
  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);
    console.log('DJIRadioLogic:canUseIllegalChannels  Original says:', originalResult, 'we say: 1');
    return 1;
  });
}

AFSecurityPolicy - setSSLPinningMode

AFSecurityPolicy.setSSLPinningMode.js
if (ObjC.available) {
 
  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);
    console.log('AFSecurityPolicy:setSSLPinningMode. Changing from: ', originalResult, 'to: 0');
  });
}

DJIAccountManager - checkIsAdminUser

DJIAccountManager.checkIsAdminUser.js
//Set Admin mode in Flight Records
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);
     console.log('[*] Setting user to Admin for Flight Records');
     return 1;
});

DJIUpgradeNotifyViewModel - notifyHidden

DJIUpgradeNotifyViewModel.notifyHidden.js
//Bypass upgrade notification on splash screen
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);
     console.log('[*] Disabling Upgrade Notification');
     return 1;
});

DJIAppSettings - sdr_force_fcc

DJIAppSettings.sdr_force_fcc.js
//Force FCC Mode
var shown=0;
var fcc_enabled;
 
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);
     console.log('[*] Setting Forced FCC Mode');
     fcc_enabled = 1;
     return 1;
});
 
//Fake Mavic for P4 FCC
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(shown==0) {
          console.log('[*] Faking product code for FCC');
          shown=1;
     }
     if(fcc_enabled==0)
         return 13; //mavic
     else
         return originalResult
});

DJIAppForceUpdateManager - hasChecked

DJIAppForceUpdateManager.hasChecked.js
//Bypass DJI Go 4 new app version check
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);
     console.log("[*] Disabling App Upgrade Check");
     return 1;
});

DJIAppSettings - canUseIllegalChannels

DJIAppForceUpdateManager.hasChecked.js
//Enable Illegal Channels (32 Channels)
if (ObjC.available) {
     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);
          console.log('[*] Enabling Illegal Channels (32 Channels)');
          return 1;
     });
     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);
          console.log('[*] Enabling Illegal Channels (32 Channels)');
          return 1;
  });
}
howto/fridahooklibrary.1510008067.txt.gz · Last modified: 2017/11/06 22:41 by czokie