diff --git a/core/src/main/java/android/content/res/XResources.java b/core/src/main/java/android/content/res/XResources.java index 70141386..b0ad5b08 100644 --- a/core/src/main/java/android/content/res/XResources.java +++ b/core/src/main/java/android/content/res/XResources.java @@ -82,6 +82,10 @@ public class XResources extends XposedResources { private static final SparseArray> sReplacements = new SparseArray<>(); private static final SparseArray> sResourceNames = new SparseArray<>(); + // A resource ID is a 32 bit number of the form: PPTTNNNN. PP is the package the resource is for; + // TT is the type of the resource; + // NNNN is the name of the resource in that type. + // For applications resources, PP is always 0x7f. private static final byte[] sSystemReplacementsCache = new byte[256]; // bitmask: 0x000700ff => 2048 bit => 256 bytes private byte[] mReplacementsCache; // bitmask: 0x0007007f => 1024 bit => 128 bytes private static final HashMap sReplacementsCacheMap = new HashMap<>(); diff --git a/core/src/main/java/org/lsposed/lspd/impl/utils/LSPosedDexParser.java b/core/src/main/java/org/lsposed/lspd/impl/utils/LSPosedDexParser.java index 53dea714..e199bdcc 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/utils/LSPosedDexParser.java +++ b/core/src/main/java/org/lsposed/lspd/impl/utils/LSPosedDexParser.java @@ -368,14 +368,12 @@ public class LSPosedDexParser implements DexParser { @Nullable final AnnotationElement[] elements; - LSPosedAnnotation(int visibility, int type, @NonNull Object[] elements) { + LSPosedAnnotation(int visibility, int type, @NonNull int[] elements, @NonNull ByteBuffer[] elementValues) { this.visibility = visibility; this.type = typeIds[type]; - var a = (int[]) elements[0]; - var b = (ByteBuffer[]) elements[1]; - this.elements = new AnnotationElement[b.length]; - for (int i = 0; i < b.length; ++i) { - this.elements[i] = new LSPosedAnnotationElement(a[i * 2], a[i * 2 + 1], b[i]); + this.elements = new AnnotationElement[elementValues.length]; + for (int i = 0; i < elementValues.length; ++i) { + this.elements[i] = new LSPosedAnnotationElement(elements[i * 2], elements[i * 2 + 1], elementValues[i]); } } @@ -441,10 +439,10 @@ public class LSPosedDexParser implements DexParser { LSPosedFieldAnnotation(int field, @NonNull Object[] annotations) { this.field = fieldIds[field]; var a = (int[]) annotations[0]; - var b = (Object[][]) annotations[1]; + var b = (Object[]) annotations[1]; this.annotations = new Annotation[b.length]; for (int i = 0; i < b.length; ++i) { - this.annotations[i] = new LSPosedAnnotation(a[2 * i], a[2 * i + 1], b[i]); + this.annotations[i] = new LSPosedAnnotation(a[2 * i], a[2 * i + 1], (int[]) b[2 * i], (ByteBuffer[]) b[2 * i + 1]); } } @@ -470,10 +468,10 @@ public class LSPosedDexParser implements DexParser { LSPosedMethodAnnotation(int method, @NonNull Object[] annotations) { this.method = methodIds[method]; var a = (int[]) annotations[0]; - var b = (Object[][]) annotations[1]; + var b = (Object[]) annotations[1]; this.annotations = new Annotation[b.length]; for (int i = 0; i < b.length; ++i) { - this.annotations[i] = new LSPosedAnnotation(a[2 * i], a[2 * i + 1], b[i]); + this.annotations[i] = new LSPosedAnnotation(a[2 * i], a[2 * i + 1], (int[]) b[2 * i], (ByteBuffer[]) b[2 * i + 1]); } } @@ -501,10 +499,10 @@ public class LSPosedDexParser implements DexParser { this.annotations = new Annotation[annotations.length][]; for (int i = 0; i < annotations.length; ++i) { var a = (int[]) annotations[i][0]; - var b = (Object[][]) annotations[i][1]; + var b = (Object[]) annotations[i][1]; this.annotations[i] = new Annotation[b.length]; for (int j = 0; j < b.length; ++j) { - this.annotations[i][j] = new LSPosedAnnotation(a[2 * j], a[2 * j + 1], b[j]); + this.annotations[i][j] = new LSPosedAnnotation(a[2 * j], a[2 * j + 1], (int[]) b[2 * j], (ByteBuffer[]) b[2 * j + 1]); } } } @@ -599,9 +597,9 @@ public class LSPosedDexParser implements DexParser { this.classAnnotations = new LSPosedAnnotation[num_class_annotations]; if (num_class_annotations > 0) { var a = (int[]) classAnnotations[0]; - var b = (Object[][]) classAnnotations[1]; + var b = (Object[]) classAnnotations[1]; for (int i = 0; i < num_class_annotations; ++i) { - this.classAnnotations[i] = new LSPosedAnnotation(a[2 * i], a[2 * i + 1], b[i]); + this.classAnnotations[i] = new LSPosedAnnotation(a[2 * i], a[2 * i + 1], (int[]) b[2 * i], (ByteBuffer[]) b[2 * i + 1]); } } diff --git a/core/src/main/jni/src/jni/dex_parser.cpp b/core/src/main/jni/src/jni/dex_parser.cpp index 7735b91b..d83828e9 100644 --- a/core/src/main/jni/src/jni/dex_parser.cpp +++ b/core/src/main/jni/src/jni/dex_parser.cpp @@ -29,18 +29,22 @@ namespace { } auto a = env->NewIntArray(static_cast(2 * annotation->size)); auto *a_ptr = env->GetIntArrayElements(a, nullptr); - auto b = env->NewObjectArray(static_cast(annotation->size), object_class, nullptr); + auto b = env->NewObjectArray(static_cast(2 * annotation->size), object_class, + nullptr); for (size_t i = 0; i < annotation->size; ++i) { auto *item = dex.dataPtr(annotation->entries[i]); a_ptr[2 * i] = item->visibility; auto *annotation_data = item->annotation; a_ptr[2 * i + 1] = static_cast(dex::ReadULeb128(&annotation_data)); auto size = dex::ReadULeb128(&annotation_data); - auto bi = env->NewObjectArray(static_cast(size), object_class, nullptr); + auto b2i0 = env->NewIntArray(static_cast(2 * size)); + auto *b2i0_ptr = env->GetIntArrayElements(b2i0, nullptr); + auto b2i1 = env->NewObjectArray(static_cast(size), object_class, nullptr); for (size_t j = 0; j < size; ++j) { - auto name = dex::ReadULeb128(&annotation_data); + b2i0_ptr[2 * j] = static_cast(dex::ReadULeb128(&annotation_data)); auto arg_and_type = *annotation_data++; auto value_type = arg_and_type & 0x1f; + b2i0_ptr[2 * j + 1] = value_type; auto value_arg = arg_and_type >> 5; jobject value = nullptr; switch (value_type) { @@ -74,11 +78,13 @@ namespace { default: break; } - env->SetObjectArrayElement(bi, static_cast(j), value); + env->SetObjectArrayElement(b2i1, static_cast(j), value); env->DeleteLocalRef(value); } - env->SetObjectArrayElement(b, static_cast(i), bi); - env->DeleteLocalRef(bi); + env->SetObjectArrayElement(b, static_cast(2 * i), b2i0); + env->SetObjectArrayElement(b, static_cast(2 * i + 1), b2i1); + env->DeleteLocalRef(b2i0); + env->DeleteLocalRef(b2i1); } env->ReleaseIntArrayElements(a, a_ptr, 0); auto res = env->NewObjectArray(2, object_class, nullptr);