Why Frida?

Becase it can be many things, know more. Its is,

  • easy, sure learning curve takes some time, but it pays off spectacularly.
  • efficient, a rough estimate for the modification took 30 min in frida vs 2 hours in traditional methods, its way more flexible.
  • elegant when compared to traditional ways. you get creative new ideas and implement them easily (implementating manually takes way longer).

My setup

  • Genymotion, but why? (better than avd) runs way faster than avd, default root, runs via virtual box, image size is small, less cpu usage compared to avd.

  • latest frida server and client from frida/releases.

  • move the fridaserver to android device/emulator and start it.

    adb push /data/local/tmp/firda-server
    
    adb shell
    
    cd /data/local/tmp/frida-server
    
    ./frida-server &
    

Modding with very little effort

Frida has a great feature ‘TRACE’, but without manually injection, by doing it dynamically, more here.

what it does in oneline is you give it ‘wildcard methods’ and a process, it will then log the input params and out values when the traced method is called of the target process

# for tracing all methods which contains 'license'
noone@pc:frida-trace -U  Firewall  -j '*!*license*/isu'

Trace Logs

 26442 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.ActivityRules>")
 26443 ms  <= false
 26598 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.ActivityRules>")
 26599 ms  <= false
 26603 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.ActivityRules>")
 26604 ms  <= false
 39331 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.settings.Settings>")
 39331 ms  <= false
 45614 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.settings.Settings>")
 45614 ms  <= false
 49377 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.ActivityLogs>")
 49378 ms  <= false
 49567 ms  <= false
 49581 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.ActivityLogs>")
 49581 ms  <= false
 52637 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.settings.SettingsInApp>")
 52637 ms  <= false
 52786 ms  Settings.isLicenseActive("<instance: android.content.Context, $className: com.protectstar.firewall.activity.settings.SettingsInApp>")
 52789 ms  <= false
 52792 ms  SettingsInApp.initLicense()

With just guessing the method name ‘license’, following license methods were found and its input and output params are logged when run via adb, without even decompiling and going through code (isn’t this great!?)

8 directories, 31 files

__handlers__/
├── com.protectstar.firewall.activity.settings.Settings
│   └── isLicenseActive.js <--- this file seems interesting?!
├── com.protectstar.firewall.activity.settings.SettingsInApp
│   ├── initLicense.js
...
│   └── licenseSuccess.js
├── com.protectstar.firewall.cloud.Auth
│   ├── getLicense1Url.js
...
├── com.protectstar.firewall.utility.LicenseActivation
│   ├── access_000.js
...
│   ├── checkLicenseDuration.js  <--- this file seems interesting?!
│   └── _init.js
├── com.protectstar.firewall.utility.LicenseActivation_Customer
...
│   ├── access_900.js
│   └── _init.js
├── com.protectstar.firewall.utility.LicenseActivation_Reason
│   ├── valueOf.js
│   └── values.js
├── com.protectstar.firewall.utility.LicenseActivation_ResponseListener
    ├── error.js
    └── licenseSuccess.js

Now navigate though all sections of the app and find any interesting methods invoked through the trace logs.

patching on the fly, without seeing the original code

By observing the invoked methods and its input/output values, we can guess the method name to patch, it is ‘isLicenseActive’ from ‘com.protectstar.firewall.activity.settings.Settings’, in frida-trace, we see the return value is False, so why not make it as true and observe the behaviour?

// patching the method
function main() {
  Java.perform(function () {
    // match the method signature
    Java.use('com.protectstar.firewall.activity.settings.Settings').isLicenseActive.implementation = function (
      context
    ) {
      return true;
    };
  });
}
setImmediate(main);

After patching, navigating the app we now see the premium features are unlocked, that was way easier than conventional methods, greatly reduces the time.

End

I intend to use Frida in the future stuff I do, its simply great. Seeya next time. untill then - aghontpi :)