这次为 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!
oleavr