美文网首页
Frida Javascript api #Java 与 #We

Frida Javascript api #Java 与 #We

作者: 邓超_码农加点中 | 来源:发表于2020-02-15 22:08 被阅读0次

    原文链接: 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.

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

    相关文章

      网友评论

          本文标题:Frida Javascript api #Java 与 #We

          本文链接:https://www.haomeiwen.com/subject/pmkufhtx.html