Search code examples
androidfrida

Unable to hook non-static method with Frida


I'm trying to intercept and change the isRooted and isEmulator but I can't seem to hook the instance.

Java.perform(() => {
  var classLoaderToUse = Java.enumerateClassLoadersSync()[2]; //found through trial and error
  Java.classFactory.loader = classLoaderToUse;

  try {
    Java.choose("com.moe.device.DeviceDetails", {
      onMatch: function (instance) {
        console.log("[ * ] Instance found in memory: " + instance);
        a=instance.collect();
        a.map.put("isRooted", "false");
        a.map.put(DeviceInformationInspector.IS_EMULATOR, String.valueOf(false));
      },
      onComplete: function () {},
    });
  } catch (error) {
      console.log(error);
  }
});

Here is a mockup of the function Im trying to hook:

package com.moe.device;
    public final class DeviceDetails{
        public static void collect(Context context, Map<String, String> map) {
            map.put("deviceManufacturer", Build.MANUFACTURER);
            map.put("hardwareModel", Build.MODEL);
            map.put("deviceBoard", Build.BOARD);
            map.put("deviceBrand", Build.BRAND);
            map.put("buildDisplayId", Build.DISPLAY);
            map.put("isRooted", isRooted());
            map.put(DeviceInformationInspector.IS_EMULATOR, String.valueOf(isEmulator()));
        }
    
         private static String isRooted() {
           return "False"
         }
         private static String isEmulator() {
           return False
         }
    }

I cant get the "Instance found in memory:" to show up but any console.log() in onComplete does. I'm not sure if I'm doing the map replacements correct but right now I'm just trying to get inside the method.


Solution

  • The common approach used by Frida is not to hook existing instances of classes in memory. Instead you simply hook the whole class so every existing or instance that is created in future will use your hooked method(s).

    The common approach would be this hooking code:

    Java.perform(() => {
      
      let DeviceDetailsClass = Java.use("com.moe.device.DeviceDetails");
      
      DeviceDetailsClass.isRooted.implementation =  function () {
        return "False";
      };
      
      
      DeviceDetailsClass.isEmulator.implementation =  function () {
        return "False";
      };
      
    });