Bitmap创建
android.graphics.Bitmap
private static native Bitmap nativeCreate(int[] colors, int offset,
int stride, int width, int height,
int nativeConfig, boolean mutable,
long nativeColorSpace);
android.graphics.BitmapFactory
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle);
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle);
private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts,
long inBitmapHandle, long colorSpaceHandle);
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts, long inBitmapHandle, long colorSpaceHandle);
android.widget.ImageView
public void setImageDrawable(@Nullable Drawable drawable) {
}
frameworks/base/libs/hwui/jni/Bitmap.cpp
static const JNINativeMethod gBitmapMethods[] = {
{ "nativeCreate", "([IIIIIIZJ)Landroid/graphics/Bitmap;",
(void*)Bitmap_creator },
{ "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;",
(void*)Bitmap_copy },
{ "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;",
(void*)Bitmap_copyAshmem },
...
};
static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
jint offset, jint stride, jint width, jint height,
jint configHandle, jboolean isMutable,
jlong colorSpacePtr) {
...
sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap);
...
return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable));
}
sk_sp<Bitmap> Bitmap::allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes) {
// Android 8.0 后, calloc 在 Native 堆分配内存
void* addr = calloc(size, 1);
if (!addr) {
return nullptr;
}
return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes));
}
Frida hook
Java.perform(function x() {
console.log("jscode start");
var Bitmap = Java.use("android.graphics.Bitmap");
Bitmap.nativeCreate.implementation = function(colors, offset, stride, width, height, nativeConfig, mutable, nativeColorSpace) {
//console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
var bitmap = this.nativeCreate(colors, offset, stride, width, height, nativeConfig, mutable, nativeColorSpace);
if (bitmap.getAllocationByteCount() / (1000 * 1000) > 5) {
console.log("nativeCreate "+ bitmap.getAllocationByteCount() / (1000 * 1000));
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
return bitmap;
}
var BitmapFactory = Java.use("android.graphics.BitmapFactory");
BitmapFactory.nativeDecodeStream.implementation = function(is, storage, padding, opts, inBitmapHandle, colorSpaceHandle) {
var bitmap = this.nativeDecodeStream(is, storage, padding, opts, inBitmapHandle, colorSpaceHandle);
if (bitmap.getAllocationByteCount() / (1000 * 1000) > 5) {
console.log("nativeDecodeStream "+ bitmap.getAllocationByteCount() / (1000 * 1000));
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
return bitmap;
}
BitmapFactory.nativeDecodeFileDescriptor.implementation = function(fd, padding, opts, inBitmapHandle, colorSpaceHandle) {
var bitmap = this.nativeDecodeFileDescriptor(fd, padding, opts, inBitmapHandle, colorSpaceHandle);
console.log("nativeDecodeFileDescriptor "+ bitmap.getAllocationByteCount() / (1000 * 1000));
return bitmap;
}
BitmapFactory.nativeDecodeAsset.implementation = function(nativeAsset, padding, opts, inBitmapHandle, colorSpaceHandle) {
var bitmap = this.nativeDecodeAsset(nativeAsset, padding, opts, inBitmapHandle, colorSpaceHandle);
console.log("nativeDecodeAsset " + bitmap.getAllocationByteCount() / (1000 * 1000));
return bitmap;
}
BitmapFactory.nativeDecodeByteArray.implementation = function(data, offset, length, opts, inBitmapHandle, colorSpaceHandle) {
var bitmap = this.nativeDecodeByteArray(data, offset, length, opts, inBitmapHandle, colorSpaceHandle);
console.log("nativeDecodeByteArray " + bitmap.getAllocationByteCount() / (1000 * 1000));
return bitmap;
}
var ImageViewClass = Java.use("android.widget.ImageView");
ImageViewClass.setImageDrawable.implementation = function(drawable) {
// var intrinsicWidth = drawable.getIntrinsicWidth();
//console.log("setImageDrawable");
return this.setImageDrawable(drawable);
}
console.log("jscode end");
});
import frida, sys
# 查找USB设备并附加到目标进程
process = frida.get_usb_device().attach('浏览器')
# 读取js文件, 在目标进程里创建脚本
with open("hook.js", 'r', encoding='UTF-8') as f:
jscode_script = process.create_script(f.read())
# 加载创建的javascript脚本
jscode_script.load()
# 读取系统输入
sys.stdin.read()
java.lang.Throwable
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1137)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1095)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1045)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1006)
at com.android.browser.MultiWebViewAdapter.capturePageItem(MultiWebViewAdapter.java:4430)
at com.android.browser.MultiWebViewAdapter.openNewWebPage(MultiWebViewAdapter.java:4136)
at com.android.browser.MultiWebViewAdapter.loadUrl(MultiWebViewAdapter.java:1379)
at com.android.browser.MultiWebViewAdapter.loadUrlWithReferrer(MultiWebViewAdapter.java:5060)
at com.android.browser.MultiWebViewAdapter.access$3300(MultiWebViewAdapter.java:148)
at com.android.browser.MultiWebViewAdapter$InnerMiuiWebViewClient.proceedNavigation(MultiWebViewAdapter.java:3822)
at com.android.browser.MultiWebViewAdapter$InnerMiuiWebViewClient.shouldIgnoreNavigation(MultiWebViewAdapter.java:3812)
at com.miui.webview.MiuiWebViewClient.shouldIgnoreNavigation(MiuiWebViewClient.java:235)
at com.miui.webview.MiuiContents.shouldIgnoreNavigation(MiuiContents.java:148)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:341)
at android.os.Looper.loopOnce(Looper.java:168)
at android.os.Looper.loop(Looper.java:299)
at android.app.ActivityThread.main(ActivityThread.java:8261)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:559)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:954)
参考
https://juejin.cn/post/7206327507531399225
https://juejin.cn/post/7214800241245880379
https://www.cnblogs.com/luoyesiqiu/p/10718997.html
https://blog.51cto.com/u_15127581/2779737
https://www.jianshu.com/p/89cc79e29f45
https://blog.csdn.net/song_lee/article/details/103306677
https://kevinspider.github.io/frida/frida-hook-java/
https://blog.csdn.net/weixin_39190897/article/details/115582853
https://kevins.pro/recoding_use_frida.html
https://lingwu111.github.io/frida%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%B8%B8%E8%A7%81api%EF%BC%88%E4%B8%80%EF%BC%89.html
https://www.52pojie.cn/thread-1128884-1-1.html
https://blog.csdn.net/qq_52217283/article/details/122723278
https://blog.csdn.net/wangwanglele11/article/details/112945216
https://blog.csdn.net/LoopherBear/article/details/107085949
https://blog.csdn.net/weixin_61845324/article/details/130059314
https://blog.csdn.net/weixin_35016347/article/details/104002411
https://blog.csdn.net/weixin_43111232/article/details/121429371
https://www.jianshu.com/p/fa86044cecec
https://zhuanlan.zhihu.com/p/557373191
https://www.buaq.net/go-115026.html
https://rise-worlds.github.io/2023/04/23/frida-source-code-analysis/
https://evilpan.com/2022/04/17/frida-java/