Frida Javascript api #Java 与 #WeakRef (中文版)

原文链接: https://frida.re/docs/javascript-api/#java
欢迎加入 Frida 交流群: 1049977261

Java

  • Java.available: 一个指明当前进程是否有 Java 虚拟机 ( Dalvik 或 ART ) 被加载的布尔值.
    请不要在这个值为 false 时调用其他任何的 Java 属性或方法.

  • Java.androidVersion: 一个指明了当前运行环境的 Android 版本字符串.

  • Java.enumerateLoadedClasses(callbacks):
    列举当前已加载的类, callbacks 是一个包含以下方法的对象:

    • onMatch: function (name, handle):
      对于已加载的每一个类调用一次, name 可用于传递给 use() 来获得一个 JavaScript 包裹对象. 您也可以对 handle 进行 Java.cast() 来转换成 java.lang.Class.

    • onComplete: function (): 当所有的类都列举完时被调用.

  • Java.enumerateLoadedClassesSync():
    enumerateLoadedClasses() 的同步版本, 返回一个包含类名的数组.

  • Java.enumerateClassLoaders(callbacks):
    列举当前 Java 虚拟机中存在的类加载器, callbacks 是一个包含以下方法的对象:

    • onMatch: function (loader):
      对于每一个类加载器调用一次, loader 是特定 java.lang.ClassLoader 的包裹对象.

    • onComplete: function (): 当所有的类加载器都列举完时被调用.

    您必须将一个加载器传递给 Java.ClassFactory.get() 以便能够对特定加载器中的类进行 Java.use().

  • Java.enumerateClassLoadersSync():
    enumerateClassLoaders() 的同步版本, 返回一个类加载器的数组.

  • Java.scheduleOnMainThread(fn): 在虚拟机的主线程上运行 fn .

  • Java.perform(fn):
    确保当前线程已附加到虚拟机并调用 fn. (这在 Java 的回调中是不必要的.)
    如果应用的类加载器不可用时, 将会延时调用 fn.
    如果不需要接触应用中的类, 则可以使用 Java.performNow().

Java.perform(function () {
  var Activity = Java.use('android.app.Activity');
  Activity.onResume.implementation = function () {
    send('onResume() got called! Let\'s call the original implementation');
    this.onResume();
  };
});
  • Java.performNow(fn):
    确保当前线程已附加到虚拟机并调用 fn. (这在 Java 的回调中是不必要的.)

  • Java.use(className):
    动态的获得一个类 className 的 JavaScript 包裹对象, 您可以通过在这个对象上调用 $new() 执行它的构造器来实例化对象. 对实例调用 $dispose() 来显示的清理掉它 (或者等 JavaScript 对象被垃圾回收或脚本被卸载). 静态与非静态方法都可用, 您甚至可以替换掉一个方法的实现, 并从中抛出异常:

Java.perform(function () {
  var Activity = Java.use('android.app.Activity');
  var Exception = Java.use('java.lang.Exception');
  Activity.onResume.implementation = function () {
    throw Exception.$new('Oh noes!');
  };
});

默认使用应用的类加载器, 但您可以通过给 Java.classFactory.loader 赋值一个不同的加载器实例来进行自定义.
请注意, 所有的方法包裹都提供了 clone(options) API 来配合 NativeFunction 选项创造一个新的方法包裹对象.

  • Java.openClassFile(filePath):
    打开 filePath 处的 dex 文件, 返回一个包含以下方法的对象:

    • load(): 将包含的类加载进虚拟机.

    • getClassNames(): 包含的类名称的数组.

  • Java.choose(className, callbacks):
    通过扫描 Java 栈堆来列举 className 的存活实例, callbacks 是一个包含以下方法的对象:

    • onMatch: function (instance):
      对于每一个找到的存活实例 instance 被调用一次.

      这个方法可以通过返回字符串 "stop" 来提前终止扫描.

    • onComplete: function (): 当所有的实例都被列举时调用.

  • Java.retain(obj):
    复制 JavaScript 包裹对象 obj, 以便之后在替换方法之外使用.

Java.perform(function () {
  var Activity = Java.use('android.app.Activity');
  var lastActivity = null;
  Activity.onResume.implementation = function () {
    lastActivity = Java.retain(this);
    this.onResume();
  };
});
  • Java.cast(handle, klass):
    通过将已有的实例 handleJava.use() 返回的指定类型 klass 一起创建一个新的 JavaScript 包裹对象. 这个包裹对象有一个 class 属性可用于获得它的类型的包裹, 以及一个代表着它类名的 $className 字符串.
var Activity = Java.use('android.app.Activity');
var activity = Java.cast(ptr('0x1234'), Activity);
  • Java.array(type, elements):
    使用 JavaScript 的数组 element 创建一个指定类型 type 的 Java 数组. 返回的 Java 数组的行为与 JavaScript 数组的行为相似, 但可用于 Java API, 以便这些 API 可以修改它的内容.
var values = Java.array('int', [ 1003, 1005, 1007 ]);

var JString = Java.use('java.lang.String');
var str = JString.$new(Java.array('byte', [ 0x48, 0x65, 0x69 ]));
  • Java.isMainThread(): 判断调用者是否处于主线程.

  • Java.registerClass(spec):
    创建一个新的 Java 类, 并返回它的包裹对象, spec 是一个包含以下属性的对象:

    • name: 类名字符串.
    • superClass: (可选的) 父类. 省略的话则继承自 java.lang.Object.
    • implements: (可选的) 这个类实现的接口的数组.
    • fields: (可选的) 指明了名称与类型的待公开的字段对象.
    • methods: (可选的) 指明了实现的方法.
var SomeBaseClass = Java.use('com.example.SomeBaseClass');
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');

var MyTrustManager = Java.registerClass({
  name: 'com.example.MyTrustManager',
  implements: [X509TrustManager],
  methods: {
    checkClientTrusted: function (chain, authType) {
    },
    checkServerTrusted: function (chain, authType) {
    },
    getAcceptedIssuers: function () {
      return [];
    },
  }
});

var MyWeirdTrustManager = Java.registerClass({
  name: 'com.example.MyWeirdTrustManager',
  superClass: SomeBaseClass,
  implements: [X509TrustManager],
  fields: {
    description: 'java.lang.String',
    limit: 'int',
  },
  methods: {
    $init: function () {
      console.log('Constructor called');
    },
    checkClientTrusted: function (chain, authType) {
      console.log('checkClientTrusted');
    },
    checkServerTrusted: [{
      returnType: 'void',
      argumentTypes: ['[Ljava.security.cert.X509Certificate;', 'java.lang.String'],
      implementation: function (chain, authType) {
        console.log('checkServerTrusted A');
      }
    }, {
      returnType: 'java.util.List',
      argumentTypes: ['[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String'],
      implementation: function (chain, authType, host) {
        console.log('checkServerTrusted B');
        return null;
      }
    }],
    getAcceptedIssuers: function () {
      console.log('getAcceptedIssuers');
      return [];
    },
  }
});
  • Java.deoptimizeEverything():
    强制虚拟机通过解释器执行任何代码. 这在某些情况下需要阻止绕过方法钩子的优化时很有必要, 并且允许 ART 的 Instrumentation API 可用于运行时的跟踪.

  • Java.vm: 一个包含以下方法的对象:

    • perform(fn):
      确保当前线程已附加到虚拟机并调用 fn. (这在 Java 的回调中是不必要的.)

    • getEnv():
      获得当前线程的 JNIEnv 对象的包裹. 如果当前线程没有附加到虚拟机上, 则抛出异常.

    • tryGetEnv():
      获得当前线程的 JNIEnv 对象的包裹. 如果当前线程没有附加到虚拟机上, 则返回 null.

  • Java.classFactory:
    默认的类工厂用于实现 Java.use() 等. 它使用应用的主要类加载器.

  • Java.ClassFactory: 包含以下属性与方法的类:

    • get(classLoader):
      获得指定类加载器的类工厂实例. 默认的类工厂仅与应用的主要类加载器互动. 其他的类加载器可以通过 Java.enumerateClassLoaders() 来发现, 并通过这个 API 进行互动.
    • loader:
      当前正在被使用的类加载器的只读属性.
      对于默认的类加载器, 这个值在第一次调用 Java.perform() 时被更新.

    • cacheDir:
      当前正在使用的缓存文件夹的路径字符串.
      对于默认的类加载器, 这个值在第一次调用 Java.perform() 时被更新.

    • tempFileNaming:
      指明了临时文件命名规则的对象. 默认值是: { prefix: 'frida', suffix: 'dat' }.

    • use(className):
      类似于 Java.use(), 但使用指定的类加载器.

    • openClassFile(filePath):
      类似于 Java.openClassFile(), 但使用指定的类加载器.

    • choose(className, callbacks):
      类似于 Java.choose(), 但使用指定的类加载器.

    • retain(obj):
      类似于 Java.retain(), 但使用指定的类加载器.

    • cast(handle, klass):
      类似于 Java.cast(), 但使用指定的类加载器.

    • array(type, elements):
      类似于 Java.array(), 但使用指定的类加载器.

    • registerClass(spec):
      类似于 Java.registerClass(), 但使用指定的类加载器.

WeakRef

  • WeakRef.bind(value, fn):
    监控 value 并在 value 被当做垃圾回收或者脚本被卸载时调用回调 fn.
    返回一个可以传递给 WeakRef.unbind() 的用于清理的 id.

    当你在构建一种语言时十分有用.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容