Skip to content

Instantly share code, notes, and snippets.

@SeeFlowerX
Created May 26, 2023 08:45
Show Gist options
  • Save SeeFlowerX/05e60e476ca9ea1efa10b0ae91aa2150 to your computer and use it in GitHub Desktop.
Save SeeFlowerX/05e60e476ca9ea1efa10b0ae91aa2150 to your computer and use it in GitHub Desktop.
使用Java.retain出现了非常诡异的现象,最后发现是因为没有把Java.retain的结果赋值给全局变量导致的...
function log(msg) {
console.log(msg);
}
function getRealClassNameByHandle (handle) {
let obj = Java.use("java.lang.Object");
log(`[getRealClassNameByHandle] obj => ${obj}`);
let jObject = Java.cast(ptr(handle), obj);
log(`[getRealClassNameByHandle] jObject => ${jObject}`);
let objClass = jObject.getClass();
log(`[getRealClassNameByHandle] objClass => ${objClass}`);
return objClass.getName();
};
function handledump(handle) {
Java.perform(function() {
log(`[handledump] 0 ${handle}`);
let origClassName1 = getRealClassNameByHandle(handle);
log(`[handledump] 1 ${handle} origClassName => ${origClassName1}`);
let origClassName2 = getRealClassNameByHandle(handle);
log(`[handledump] 2 ${handle} origClassName => ${origClassName2}`);
})
}
let g_handle = null;
function mainv2() {
Java.perform(function() {
let flag = true;
let Uri = Java.use("android.net.Uri");
Uri.parse.overload("java.lang.String").implementation = function(uri_str) {
let instance = this.parse(uri_str);
if (flag) {
flag = false;
// let handle = instance.$h;
// let handle = Java.retain(instance).$h;
// log(`[mainv2] ${handle}`);
g_handle = Java.retain(instance);
log(`[mainv2] ${g_handle.$h}`);
}
return instance;
}
})
}
function main() {
Java.perform(function() {
let flag = true;
let Uri = Java.use("android.net.Uri");
Uri.parse.overload("java.lang.String").implementation = function(uri_str) {
let instance = this.parse(uri_str);
if (flag) {
flag = false;
// let handle = instance.$h;
let handle = Java.retain(instance).$h;
handledump(handle);
}
return instance;
}
})
}
// setImmediate(main);
setImmediate(mainv2);
rpc.exports = {
handledump:handledump
}
/*
可能是frida的bug,简单来说就是 用 Java.retain 之后得到的 handle 非常容易出现奇怪的情况
推出是 getRealClassNameByHandle 中 Java.cast 带来的问题
对于frida主动构造的实例 似乎没有问题
可以选择 设置APP 进行hook hook生效后点击 存储 功能
这里只是为了触发 Uri.parse 这个方法
---
mainv2 是打印出 handle 值,然后在终端中执行 handledump(0x1b56) 这样去测试
*/
// frida -U -p 28957 -l poc_frida_bug.js -o poc_frida_bug.log
/* not use retain 正常打印预期信息
[handledump] 0 0x1892
[getRealClassNameByHandle] obj => <class: java.lang.Object>
[getRealClassNameByHandle] jObject => content://com.android.providers.media.documents/root/images_root
[getRealClassNameByHandle] objClass => class android.net.Uri$StringUri
[handledump] 1 0x1892 origClassName => android.net.Uri$StringUri
[getRealClassNameByHandle] obj => <class: java.lang.Object>
[getRealClassNameByHandle] jObject => content://com.android.providers.media.documents/root/images_root
[getRealClassNameByHandle] objClass => class android.net.Uri$StringUri
[handledump] 2 0x1892 origClassName => android.net.Uri$StringUri
*/
/* use retain 有多种情况
1. 如下
[handledump] 0 0x1aea
[getRealClassNameByHandle] obj => <class: java.lang.Object>
[getRealClassNameByHandle] jObject => class java.lang.Object
[getRealClassNameByHandle] objClass => class java.lang.Class
[handledump] 1 0x1aea origClassName => java.lang.Class
[getRealClassNameByHandle] obj => <class: java.lang.Object>
[getRealClassNameByHandle] jObject => class java.lang.Object
[getRealClassNameByHandle] objClass => class java.lang.Class
[handledump] 2 0x1aea origClassName => java.lang.Class
2. 第二轮 getRealClassNameByHandle 必定崩溃
[handledump] 0 0x19fa
[getRealClassNameByHandle] obj => <class: java.lang.Object>
[getRealClassNameByHandle] jObject => content://com.android.providers.media.documents/root/images_root
[getRealClassNameByHandle] objClass => class android.net.Uri$StringUri
[handledump] 1 0x19fa origClassName => android.net.Uri$StringUri
[getRealClassNameByHandle] obj => <class: java.lang.Object>
Process crashed: Bad access due to invalid address
3. 直接崩溃
[handledump] 0 0x1c76
[getRealClassNameByHandle] obj => <class: java.lang.Object>
Process crashed: Bad access due to invalid address
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment