这次为 Java 开发者和逆向工程人员带来了一些令人兴奋的消息:frida-java-bridge 现在支持 HotSpot JVM。这意味着 Java 运行时桥接不再是 Android 独有功能。非常感谢 Razvan Sima 带来这项出色的功能。

时机也恰到好处,因为我们最近还添加了全新的 Java.enumerateMethods(query) API,用于高效定位与指定查询匹配的方法。我们也确保在 HotSpot JVM 上实现了它。

查询以 "class!method" 形式指定,允许使用 glob。末尾还可以附加 / 和一个或多个修饰符:

  • i:不区分大小写匹配。
  • s:包含方法签名,例如 "putInt" 会变成 "putInt(java.lang.String, int): void"。这便于按参数和返回类型匹配,例如用 "*!*: boolean/s" 匹配所有返回布尔值的方法。
  • u:只包含用户定义的类,忽略系统类。

例如:

Java.perform(() => {
  const groups = Java.enumerateMethods('*youtube*!on*')
  console.log(JSON.stringify(groups, null, 2));
});

可能会得到如下输出:

[
  {
    "loader": "<instance: java.lang.ClassLoader, $className: dalvik.system.PathClassLoader>",
    "classes": [
      {
        "name": "com.google.android.apps.youtube.app.watch.nextgenwatch.ui.NextGenWatchLayout",
        "methods": [
          "onAttachedToWindow",
          "onDetachedFromWindow",
          "onFinishInflate",
          "onInterceptTouchEvent",
          "onLayout",
          "onMeasure",
          "onSizeChanged",
          "onTouchEvent",
          "onViewRemoved"
        ]
      },
      {
        "name": "com.google.android.apps.youtube.app.search.suggest.YouTubeSuggestionProvider",
        "methods": [
          "onCreate"
        ]
      },
      {
        "name": "com.google.android.libraries.youtube.common.ui.YouTubeButton",
        "methods": [
          "onInitializeAccessibilityNodeInfo"
        ]
      },
      …
    ]
  }
]

我们还增强了 frida-trace,使其支持跟踪 Java 方法:

$ frida-trace \
    -U \
    -f com.google.android.youtube \
    --runtime=v8 \
    -j '*!*certificate*/isu'
Instrumenting...
X509Util.addTestRootCertificate: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.X509Util/addTestRootCertificate.js"
X509Util.clearTestRootCertificates: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.X509Util/clearTestRootCertificates.js"
X509Util.createCertificateFromBytes: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.X509Util/createCertificateFromBytes.js"
X509Util.isKnownRoot: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.X509Util/isKnownRoot.js"
X509Util.verifyKeyUsage: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.X509Util/verifyKeyUsage.js"
X509Util.verifyServerCertificates: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.X509Util/verifyServerCertificates.js"
ResourceLoader$CppProxy.native_enableDevCertificate: Auto-generated handler at "/Users/oleavr/__handlers__/com.google.android.libraries.elements.interfaces.ResourceLoader_CppProxy/native_enableDevCertificate.js"
ResourceLoader$CppProxy.enableDevCertificate: Auto-generated handler at "/Users/oleavr/__handlers__/com.google.android.libraries.elements.interfaces.ResourceLoader_CppProxy/enableDevCertificate.js"
AndroidCertVerifyResult.getCertificateChainEncoded: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.AndroidCertVerifyResult/getCertificateChainEncoded.js"
bjbm.a: Auto-generated handler at "/Users/oleavr/__handlers__/bjbm/a.js"
bjbn.a: Auto-generated handler at "/Users/oleavr/__handlers__/bjbn/a.js"
AndroidNetworkLibrary.addTestRootCertificate: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.AndroidNetworkLibrary/addTestRootCertificate.js"
AndroidNetworkLibrary.clearTestRootCertificates: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.AndroidNetworkLibrary/clearTestRootCertificates.js"
AndroidNetworkLibrary.verifyServerCertificates: Auto-generated handler at "/Users/oleavr/__handlers__/org.chromium.net.AndroidNetworkLibrary/verifyServerCertificates.js"
vxr.checkClientTrusted: Auto-generated handler at "/Users/oleavr/__handlers__/vxr/checkClientTrusted.js"
vxr.checkServerTrusted: Auto-generated handler at "/Users/oleavr/__handlers__/vxr/checkServerTrusted.js"
vxr.getAcceptedIssuers: Auto-generated handler at "/Users/oleavr/__handlers__/vxr/getAcceptedIssuers.js"
ResourceLoader.enableDevCertificate: Auto-generated handler at "/Users/oleavr/__handlers__/com.google.android.libraries.elements.interfaces.ResourceLoader/enableDevCertificate.js"
Started tracing 18 functions. Press Ctrl+C to stop.
           /* TID 0x339d */
   955 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,9,…],[48,-126,4,…]], "RSA", "suggestqueries.google.com")
   972 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
  1043 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,4,…],[48,-126,4,…]], "RSA", "www.googleadservices.com")
  1059 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x33a0 */
  1643 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,5,…],[48,-126,4,…]], "RSA", "googleads.g.doubleclick.net")
           /* TID 0x339d */
  1651 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,9,…],[48,-126,4,…]], "RSA", "www.youtube.com")
           /* TID 0x33a1 */
  1665 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,15,…],[48,-126,4,…]], "RSA", "lh3.googleusercontent.com")
           /* TID 0x33a0 */
  1674 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x339d */
  1674 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x3417 */
  1674 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,15,…],[48,-126,4,…]], "RSA", "yt3.ggpht.com")
           /* TID 0x33a1 */
  1684 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x3417 */
  1688 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
  2513 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,9,…],[48,-126,4,…]], "RSA", "redirector.googlevideo.com")
  2527 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
  2722 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,9,…],[48,-126,4,…]], "RSA", "r1---sn-bxuovgf5t-vnaz.googlevideo.com")
           /* TID 0x33a1 */
  2741 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,9,…],[48,-126,4,…]], "RSA", "r2---sn-bxuovgf5t-vnas.googlevideo.com")
           /* TID 0x339d */
  2758 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,9,…],[48,-126,4,…]], "RSA", "r2---sn-bxuovgf5t-vnaz.googlevideo.com")
           /* TID 0x33a1 */
  2771 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x3417 */
  2772 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x339d */
  2777 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
  2892 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,6,…],[48,-126,4,…]], "RSA", "r2---sn-bxuovgf5t-vnas.googlevideo.com")
           /* TID 0x3417 */
  2908 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,6,…],[48,-126,4,…]], "RSA", "r2---sn-bxuovgf5t-vnaz.googlevideo.com")
           /* TID 0x33a1 */
  2926 ms  AndroidNetworkLibrary.verifyServerCertificates([[48,-126,6,…],[48,-126,4,…]], "RSA", "r1---sn-bxuovgf5t-vnaz.googlevideo.com")
           /* TID 0x3417 */
  2935 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x339d */
  2937 ms  AndroidCertVerifyResult.getCertificateChainEncoded()
           /* TID 0x33a1 */
  2942 ms  AndroidCertVerifyResult.getCertificateChainEncoded()

此功能刚刚随 frida-tools 8.0 发布,可通过例如 pip3 install -U frida-tools 获取。

我们也一直努力从各方面改进质量。32 位 ARM 上的 Stalker 就是一个很好的例子,现在它在 Android 上运行得好得多,速度也快了很多;此前有一个错误会导致 Thumb 代码块被反复重新编译。我们还实现了其他 Stalker 后端采用的一项自适应优化,仅此一项通常就能带来约 5 倍的性能提升。

以上就是主要亮点。如果你对细节感兴趣,强烈建议阅读下面的变更日志。

祝使用愉快!

12.10.0 的变更

  • Java:添加 HotSpot JVM 支持。使用 JVMTI 枚举类和选择对象。如果 JVM 库含有符号(macOS 上的 JDK 默认如此),方法拦截即可工作。已在 macOS 上使用 Java 8、11、13、14 测试。感谢 @0xraaz!
  • Java:修复 _getUsedClass() 不返回的问题。不使用 Java.perform() 而连续调用两次 Java.use() 会使 _getUsedClass() 陷入无限休眠循环。感谢 @0xraaz!
  • Java:修复此前重构破坏的 $alloc()。
  • ObjC:添加 Block.declare(),以便处理没有签名元数据的 block。
  • ObjC:修复 12.9.8 引入的 ObjC pointer 处理回归。

12.10.1 的变更

  • Java:允许 ClassFactory.get(null),方便配合 enumerateMethods() 使用。
  • Java:恢复拉取请求中意外遗漏的 JVM 方法调整逻辑。感谢 @0xraaz!

12.10.2 的变更

  • 修复 i/macOS 上长符号名的处理。感谢 @mrmacete!
  • Java:修复静态/final 方法的 JVM 拦截问题。感谢 @0xraaz!
  • 修复 Stalker ARM 对 Thumb-2 “mov pc, <reg>” 的处理。
  • 修复 Stalker ARM 对易失 VFP 寄存器的处理。

12.10.3 的变更

  • 修复 Fruity 后端中设备移除事件的接线。感谢 @mrmacete!
  • 避免在 ArmWriter.put_branch_address() 中破坏 R9。
  • 添加 ThumbWriter.can_branch_directly_between()。
  • 添加 ThumbWriter.put_branch_address()。
  • 改进 ThumbRelocator 以处理 ADR。
  • 修复 Stalker ARM 代码块损坏。
  • 修复 Stalker ARM 针对 Thumb 代码块的回收逻辑。
  • 添加缺失的 Stalker ARM 延续逻辑,以支持较长的基本块。
  • 实现 Stalker ARM 回填逻辑,性能通常提高 5 倍。

12.10.4 的变更

  • 修复 V8 运行时中 Module.name 的编码。感谢 @mrmacete!