diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/app/util/opinion/ApkLoader.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/app/util/opinion/ApkLoader.java index 98dd078599..b3bd1985ca 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/app/util/opinion/ApkLoader.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/app/util/opinion/ApkLoader.java @@ -31,6 +31,8 @@ import ghidra.file.formats.android.dex.DexHeaderFactory; import ghidra.file.formats.android.dex.format.DexConstants; import ghidra.file.formats.android.dex.format.DexHeader; import ghidra.file.formats.android.multidex.MultiDexLinker; +import ghidra.file.formats.android.versions.AndroidVersion; +import ghidra.file.formats.android.versions.AndroidVersionManager; import ghidra.file.formats.android.xml.AndroidXmlFileSystem; import ghidra.file.formats.zip.ZipFileSystem; import ghidra.formats.gfilesystem.FileSystemService; @@ -190,12 +192,12 @@ public class ApkLoader extends DexLoader { SAXBuilder sax = XmlUtilities.createSecureSAXBuilder(false, false); Document document = sax.build(xmlFileByteProvider.getInputStream(0)); Element rootElement = document.getRootElement(); - Attribute attribute = rootElement.getAttribute("platformBuildVersionName"); - String platformBuildVersionName = attribute.getValue(); + AndroidVersion version = getAndroidVersion(rootElement); List queries = QueryOpinionService.query(getName(), DexConstants.MACHINE, - platformBuildVersionName); + String.valueOf(version.getVersionLetter())); + for (QueryResult result : queries) { loadSpecs.add(new LoadSpec(this, 0, result)); } @@ -207,6 +209,17 @@ public class ApkLoader extends DexLoader { return loadSpecs; } + private AndroidVersion getAndroidVersion(Element rootElement) { + Attribute codeAttribute = + rootElement.getAttribute(AndroidVersionManager.PLATFORM_BUILD_VERSION_CODE); + String platformBuildVersionCode = codeAttribute == null ? null : codeAttribute.getValue(); + Attribute nameAttribute = + rootElement.getAttribute(AndroidVersionManager.PLATFORM_BUILD_VERSION_NAME); + String platformBuildVersionName = nameAttribute == null ? null : nameAttribute.getValue(); + return AndroidVersionManager.getByPlatformBuildVersion(platformBuildVersionCode, + platformBuildVersionName); + } + /** * Loads the "classes.dex" file to determine the LoadSpec * @param zipFS the Android APK file system diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtConstants.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtConstants.java index 0d12c309c3..6054c7a6d4 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtConstants.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtConstants.java @@ -20,7 +20,7 @@ import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; /** - * https://android.googlesource.com/platform/art/+/master/runtime/image.cc#31 + * master/runtime/image.cc */ public final class ArtConstants { @@ -30,34 +30,34 @@ public final class ArtConstants { public final static int VERSION_LENGTH = 4; + /** kitkat-release/runtime/image.c */ public final static String VERSION_KITKAT_RELEASE = "005"; + /** lollipop-release/runtime/image.c */ public final static String VERSION_LOLLIPOP_RELEASE = "009"; + /** lollipop-mr1-wfc-release/runtime/image.c */ public final static String VERSION_LOLLIPOP_MR1_WFC_RELEASE = "012"; + /** marshmallow-release/runtime/image.c */ public final static String VERSION_MARSHMALLOW_RELEASE = "017"; + /** nougat-release/runtime/image.c */ public final static String VERSION_NOUGAT_RELEASE = "029"; + /** nougat-mr2-pixel-release/runtime/image.c */ public final static String VERSION_NOUGAT_MR2_PIXEL_RELEASE = "030"; + /** oreo-release/runtime/image.c */ public final static String VERSION_OREO_RELEASE = "043"; + /** oreo-dr1-release/runtime/image.c */ public final static String VERSION_OREO_DR1_RELEASE = "044"; + /** oreo-mr1-release/runtime/image.c */ public final static String VERSION_OREO_MR1_RELEASE = "046"; + /** pie-release/runtime/image.c */ public final static String VERSION_PIE_RELEASE = "056"; + /** android10-release/runtime/image.c */ public final static String VERSION_10_RELEASE = "074";//Q + /** android11-release/runtime/image.c */ public final static String VERSION_11_RELEASE = "085";//R + /** android12-release/runtime/image.c */ public final static String VERSION_12_RELEASE = "099";//S - - // "005",// kitkat-release - // "009",// lollipop-release - // "012",// lollipop-mr1-wfc-release - // "017",// marshmallow-release - // "029",// nougat-release - // "030",// nougat-mr2-pixel-release - // "043",// oreo-release - // "044",// taimen-op1 - // "046",// oreo-mr1-release - // "051",// - // "056",// pie-release - // "059",// android-o-mr1-iot-release-1.0.0 - // "060",// android-o-mr1-iot-release-1.0.1 - // "061",// android-n-iot-release-polk-at1 + /** android13-release/runtime/image.c */ + public final static String VERSION_13_RELEASE = "106";//S v2, 13 /** * NOTE: only going to support RELEASE versions @@ -77,6 +77,7 @@ public final class ArtConstants { VERSION_10_RELEASE, VERSION_11_RELEASE, VERSION_12_RELEASE, + VERSION_13_RELEASE, //@formatter:on }; diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtFactory.java index 93518174e3..49f537ef34 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtFactory.java @@ -72,6 +72,7 @@ public final class ArtFactory { case ArtConstants.VERSION_11_RELEASE: return new ArtHeader_11(reader); case ArtConstants.VERSION_12_RELEASE: + case ArtConstants.VERSION_13_RELEASE: return new ArtHeader_12(reader); } } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtImageSectionsFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtImageSectionsFactory.java index 7e5ea3a3ac..22eca50fcf 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtImageSectionsFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtImageSectionsFactory.java @@ -56,6 +56,7 @@ public final class ArtImageSectionsFactory { case ArtConstants.VERSION_11_RELEASE: return new ImageSections_10(reader, artHeader); case ArtConstants.VERSION_12_RELEASE: + case ArtConstants.VERSION_13_RELEASE: return new ImageSections_12(reader, artHeader); } throw new IOException( diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtMethod.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtMethod.java index 0a6b1bd2ac..74ab7cb760 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtMethod.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/ArtMethod.java @@ -23,9 +23,7 @@ import ghidra.program.model.data.*; import ghidra.util.exception.DuplicateNameException; /** - * https://android.googlesource.com/platform/art/+/refs/heads/android10-release/runtime/art_method.h - * - * + * https://android.googlesource.com/platform/art/+/refs/heads/master/runtime/art_method.h */ public class ArtMethod implements StructConverter { private final int pointerSize; @@ -150,6 +148,7 @@ public class ArtMethod implements StructConverter { entry_point_from_quick_compiled_code_ = reader.readNextLong(); } } + /** https://android.googlesource.com/platform/art/+/refs/heads/android10-release/runtime/art_method.h#741 */ else if (ArtConstants.VERSION_10_RELEASE.equals(artVersion)) { declaring_class_ = reader.readNextInt(); access_flags_ = reader.readNextInt(); @@ -168,6 +167,7 @@ public class ArtMethod implements StructConverter { entry_point_from_quick_compiled_code_ = reader.readNextLong(); } } + /** https://android.googlesource.com/platform/art/+/refs/heads/android11-release/runtime/art_method.h#798 */ else if (ArtConstants.VERSION_11_RELEASE.equals(artVersion)) { declaring_class_ = reader.readNextInt(); access_flags_ = reader.readNextInt(); @@ -186,6 +186,43 @@ public class ArtMethod implements StructConverter { entry_point_from_quick_compiled_code_ = reader.readNextLong(); } } + /** https://android.googlesource.com/platform/art/+/refs/heads/android12-release/runtime/art_method.h#787 */ + else if (ArtConstants.VERSION_12_RELEASE.equals(artVersion)) { + declaring_class_ = reader.readNextInt(); + access_flags_ = reader.readNextInt(); + dex_method_index_ = reader.readNextInt(); + method_index_ = reader.readNextShort(); + hotness_count_ = reader.readNextShort(); + imt_index_ = reader.readNextShort(); + padding_ = reader.readNextShort(); + + if (pointerSize == 4) { + data_ = Integer.toUnsignedLong(reader.readNextInt()); + } + else if (pointerSize == 8) { + //data_ = reader.readNextLong(); + data_ = Integer.toUnsignedLong(reader.readNextInt()); + entry_point_from_quick_compiled_code_ = reader.readNextLong(); + } + } + /** https://android.googlesource.com/platform/art/+/refs/heads/android13-release/runtime/art_method.h#787 */ + else if (ArtConstants.VERSION_13_RELEASE.equals(artVersion)) { + declaring_class_ = reader.readNextInt(); + access_flags_ = reader.readNextInt(); + dex_method_index_ = reader.readNextInt(); + method_index_ = reader.readNextShort(); + hotness_count_ = reader.readNextShort(); + imt_index_ = reader.readNextShort(); + padding_ = reader.readNextShort(); + + if (pointerSize == 4) { + data_ = Integer.toUnsignedLong(reader.readNextInt()); + } + else if (pointerSize == 8) { + data_ = Integer.toUnsignedLong(reader.readNextInt()); + entry_point_from_quick_compiled_code_ = reader.readNextLong(); + } + } else { throw new IOException("Unsupported ART method format: " + artVersion); } @@ -393,6 +430,41 @@ public class ArtMethod implements StructConverter { struct.add(QWORD, "entry_point_from_quick_compiled_code_", null); } } + else if (ArtConstants.VERSION_12_RELEASE.equals(artVersion)) { + struct.add(ptr32, "declaring_class_", null); + struct.add(DWORD, "access_flags_", null); + struct.add(DWORD, "dex_method_index_", null); + struct.add(WORD, "method_index_", null); + struct.add(WORD, "hotness_count_", null); + struct.add(WORD, "imt_index_", null); + struct.add(WORD, "padding", null); + + if (pointerSize == 4) { + struct.add(DWORD, "data", null); + } + else if (pointerSize == 8) { + //struct.add(QWORD, "data", null); + struct.add(DWORD, "data", null); + struct.add(QWORD, "entry_point_from_quick_compiled_code_", null); + } + } + else if (ArtConstants.VERSION_13_RELEASE.equals(artVersion)) { + struct.add(ptr32, "declaring_class_", null); + struct.add(DWORD, "access_flags_", null); + struct.add(DWORD, "dex_method_index_", null); + struct.add(WORD, "method_index_", null); + struct.add(WORD, "hotness_count_", null); + struct.add(WORD, "imt_index_", null); + struct.add(WORD, "padding", null); + + if (pointerSize == 4) { + struct.add(DWORD, "data", null); + } + else if (pointerSize == 8) { + struct.add(DWORD, "data", null); + struct.add(QWORD, "entry_point_from_quick_compiled_code_", null); + } + } else { throw new IOException("Unsupported ART method format: " + artVersion); } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/android12/ImageSections_12.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/android12/ImageSections_12.java index a16929d285..5ceeee22ce 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/android12/ImageSections_12.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/art/android12/ImageSections_12.java @@ -32,11 +32,11 @@ public class ImageSections_12 extends ArtImageSections { public final static int kSectionImTables = 4; public final static int kSectionIMTConflictTables = 5; public final static int kSectionInternedStrings = 6; - public final static int kSectionClassTable = 8; - public final static int kSectionStringReferenceOffsets = 9; - public final static int kSectionMetadata = 10; - public final static int kSectionImageBitmap = 11; - public final static int kSectionCount = 12; // Number of elements in enum. + public final static int kSectionClassTable = 7; + public final static int kSectionStringReferenceOffsets = 8; + public final static int kSectionMetadata = 9; + public final static int kSectionImageBitmap = 10; + public final static int kSectionCount = 11; // Number of elements in enum. public ImageSections_12(BinaryReader reader, ArtHeader header) { super(reader, header); diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatConstants.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatConstants.java index b3b38a6058..c91bcd1060 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatConstants.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatConstants.java @@ -18,7 +18,7 @@ package ghidra.file.formats.android.oat; import ghidra.app.util.bin.format.elf.ElfSectionHeaderConstants; /** - * https://android.googlesource.com/platform/art/+/marshmallow-mr3-release/runtime/oat.h + * https://android.googlesource.com/platform/art/+/master/runtime/oat.h */ public final class OatConstants { //@formatter:off @@ -67,34 +67,70 @@ public final class OatConstants { // NOTE: we plan to only support RELEASE versions... // Upper case indicates supported version. - public final static String VERSION_KITKAT_RELEASE = "007"; + /** https://android.googlesource.com/platform/art/+/refs/heads/kitkat-release/runtime/oat.cc#24 */ + public final static String VERSION_KITKAT_RELEASE = "007"; + /** https://android.googlesource.com/platform/art/+/refs/heads/kitkat-dev/runtime/oat.cc#24 */ public final static String version_kitkat_dev = "008"; + /** https://android.googlesource.com/platform/art/+/refs/heads/lollipop-release/runtime/oat.cc#25 */ public final static String VERSION_LOLLIPOP_RELEASE = "039"; + /** https://android.googlesource.com/platform/art/+/refs/heads/lollipop-mr1-release/runtime/oat.cc#25 */ public final static String VERSION_LOLLIPOP_MR1_FI_RELEASE = "045"; + /** https://android.googlesource.com/platform/art/+/refs/heads/lollipop-wear-release/runtime/oat.cc#27 */ public final static String VERSION_LOLLIPOP_WEAR_RELEASE = "051"; + /** https://android.googlesource.com/platform/art/+/refs/heads/marshmallow-release/runtime/oat.h#34 */ public final static String VERSION_MARSHMALLOW_RELEASE = "064"; + /** https://android.googlesource.com/platform/art/+/refs/heads/nougat-release/runtime/oat.h#34 */ public final static String VERSION_NOUGAT_RELEASE = "079"; + /** https://android.googlesource.com/platform/art/+/refs/heads/n-iot-preview-2/runtime/oat.h#34 */ public final static String version_n_iot_preview_2 = "083"; + /** https://android.googlesource.com/platform/art/+/refs/heads/nougat-mr1-release/runtime/oat.h#34 */ public final static String VERSION_NOUGAT_MR1_RELEASE = "088"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-preview/runtime/oat.h#34 */ public final static String version_o_preview = "114"; + /** https://android.googlesource.com/platform/art/+/refs/heads/oreo-release/runtime/oat.h#34 */ public final static String VERSION_OREO_RELEASE = "124"; + /** https://android.googlesource.com/platform/art/+/refs/heads/n-iot-preview-4/runtime/oat.h#34 */ public final static String version_n_iot_preview_4 = "125"; + /** https://android.googlesource.com/platform/art/+/refs/heads/oreo-dr3-release/runtime/oat.h#34 */ public final static String VERSION_OREO_DR3_RELEASE = "126"; + /** https://android.googlesource.com/platform/art/+/refs/heads/oreo-m2-release/runtime/oat.h#34 */ public final static String VERSION_OREO_M2_RELEASE = "131"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-iot-preview-5/runtime/oat.h#34 */ public final static String version_o_iot_preview_5 = "132"; - public final static String version_134 = "134"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-mr1-iot-preview-6/runtime/oat.h#34 */ public final static String version_o_mr1_iot_preview_6 = "135"; + /** https://android.googlesource.com/platform/art/+/refs/heads/pie-release/runtime/oat.h#34 */ public final static String VERSION_PIE_RELEASE = "138"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-mr1-iot-preview-7/runtime/oat.h#34 */ public final static String version_o_mr1_iot_preview_7 = "139"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-mr1-iot-preview-8/runtime/oat.h#34 */ public final static String version_o_mr1_iot_preview_8 = "140"; + /** https://android.googlesource.com/platform/art/+/refs/tags/android-o-mr1-iot-release-1.0.0/runtime/oat.h#34 */ public final static String version_o_mr1_iot_release_1_0_0 = "141"; + /** https://android.googlesource.com/platform/art/+/refs/tags/android-o-mr1-iot-release-1.0.1/runtime/oat.h#34 */ public final static String version_o_mr1_iot_release_1_0_1 = "146"; + /** https://android.googlesource.com/platform/art/+/refs/tags/android-n-iot-release-polk-at1/runtime/oat.h#34 */ public final static String version_n_iot_release_polk_at1 = "147"; + /** https://android.googlesource.com/platform/art/+/refs/tags/android-q-preview-1/runtime/oat.h#33 */ public final static String version_q_preview_1 = "166"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android10-release/runtime/oat.h#34 */ public final static String VERSION_10_RELEASE = "170"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android11-release/runtime/oat.h#34 */ public final static String VERSION_11_RELEASE = "183"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android12-release/runtime/oat.h#36 */ public final static String VERSION_12_RELEASE = "195"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android-s-beta-4/runtime/oat.h#36 */ + public final static String VERSION_S_BETA4 = "197"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android-s-v2-preview-1/runtime/oat.h#36 */ public final static String VERSION_S_V2_PREVIEW = "199"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android-t-preview-1/runtime/oat.h#36 */ + public final static String VERSION_T_PREVIEW_1 = "220"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android-s-v2-beta-3/runtime/oat.h#36 */ + public final static String VERSION_S_V2_BETA2 = "223"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android13-release/runtime/oat.h#36 */ + public final static String VERSION_13_RELEASE = "225"; + /** https://android.googlesource.com/platform/art/+/master/runtime/oat.h#36 */ + public final static String VERSION_227 = "227"; /** * This array contains versions that have been actively tested and verified. @@ -116,6 +152,9 @@ public final class OatConstants { VERSION_11_RELEASE, VERSION_12_RELEASE, VERSION_S_V2_PREVIEW, + VERSION_T_PREVIEW_1, + VERSION_S_V2_BETA2, + VERSION_13_RELEASE, }; //@formatter:on diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeaderFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeaderFactory.java index 8b1cf6b0fd..af9c410dae 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeaderFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeaderFactory.java @@ -64,7 +64,11 @@ public final class OatHeaderFactory { return new OatHeader_11(reader); case OatConstants.VERSION_12_RELEASE: case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: return new OatHeader_12(reader); + case OatConstants.VERSION_13_RELEASE: + return new OatHeader_13(reader); } } } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeader_13.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeader_13.java new file mode 100644 index 0000000000..1661ce2511 --- /dev/null +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/OatHeader_13.java @@ -0,0 +1,133 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.file.formats.android.oat; + +import java.io.IOException; +import java.util.*; + +import ghidra.app.util.bin.BinaryReader; +import ghidra.file.formats.android.oat.oatdexfile.OatDexFile; +import ghidra.program.model.data.*; +import ghidra.util.exception.DuplicateNameException; + +/** + * https://android.googlesource.com/platform/art/+/refs/heads/android13-release/runtime/oat.h#127 + */ +public class OatHeader_13 extends OatHeader { + protected int oat_checksum_; + protected int instruction_set_; + protected int instruction_set_features_bitmap_; + protected int dex_file_count_; + protected int oat_dex_files_offset_; + protected int bcp_bss_info_offset_; + protected int executable_offset_; + protected int jni_dlsym_lookup_offset_; + protected int jni_dlsym_lookup_critical_trampoline_offset_; + protected int quick_generic_jni_trampoline_offset_; + protected int quick_imt_conflict_trampoline_offset_; + protected int quick_resolution_trampoline_offset_; + protected int quick_to_interpreter_bridge_offset_; + protected int nterp_trampoline_offset_; + protected int key_value_store_size_; + + OatHeader_13(BinaryReader reader) throws IOException { + super(reader); + + oat_checksum_ = reader.readNextInt(); + instruction_set_ = reader.readNextInt(); + instruction_set_features_bitmap_ = reader.readNextInt(); + dex_file_count_ = reader.readNextInt(); + oat_dex_files_offset_ = reader.readNextInt(); + bcp_bss_info_offset_ = reader.readNextInt(); + executable_offset_ = reader.readNextInt(); + jni_dlsym_lookup_offset_ = reader.readNextInt(); + jni_dlsym_lookup_critical_trampoline_offset_ = reader.readNextInt(); + quick_generic_jni_trampoline_offset_ = reader.readNextInt(); + quick_imt_conflict_trampoline_offset_ = reader.readNextInt(); + quick_resolution_trampoline_offset_ = reader.readNextInt(); + quick_to_interpreter_bridge_offset_ = reader.readNextInt(); + nterp_trampoline_offset_ = reader.readNextInt(); + key_value_store_size_ = reader.readNextInt(); + } + + @Override + public int getOatDexFilesOffset(BinaryReader reader) { + return oat_dex_files_offset_; + } + + @Override + public int getDexFileCount() { + return dex_file_count_; + } + + @Override + public int getKeyValueStoreSize() { + return key_value_store_size_; + } + + @Override + public List getOatDexFileList() { + return oatDexFileList; + } + + @Override + public OatInstructionSet getInstructionSet() { + return OatInstructionSet.valueOf(instruction_set_); + } + + @Override + public int getExecutableOffset() { + return executable_offset_; + } + + @Override + public int getChecksum() { + return oat_checksum_; + } + + @Override + public DataType toDataType() throws DuplicateNameException, IOException { + Structure structure = new StructureDataType(OatHeader_13.class.getSimpleName(), 0); + structure.add(STRING, 4, "magic_", null); + structure.add(STRING, 4, "version_", null); + structure.add(DWORD, "oat_checksum_", null); + structure.add(DWORD, OatInstructionSet.DISPLAY_NAME, null); + structure.add(DWORD, "instruction_set_features_bitmap_", null); + structure.add(DWORD, "dex_file_count_", null); + structure.add(DWORD, "oat_dex_files_offset_", null); + structure.add(DWORD, "bcp_bss_info_offset_", null); + structure.add(DWORD, "executable_offset_", null); + structure.add(DWORD, "jni_dlsym_lookup_offset_", null); + structure.add(DWORD, "jni_dlsym_lookup_critical_trampoline_offset_", null); + structure.add(DWORD, "quick_generic_jni_trampoline_offset_", null); + structure.add(DWORD, "quick_imt_conflict_trampoline_offset_", null); + structure.add(DWORD, "quick_resolution_trampoline_offset_", null); + structure.add(DWORD, "quick_to_interpreter_bridge_offset_", null); + structure.add(DWORD, "nterp_trampoline_offset_", null); + structure.add(DWORD, "key_value_store_size_", null); + + for (int i = 0; i < orderedKeyList.size(); ++i) { + String key = orderedKeyList.get(i); + String value = key_value_store_.get(key); + structure.add(STRING, key.length() + 1, "key_value_store_[" + i + "].key", null); + structure.add(STRING, value.length() + 1, "key_value_store_[" + i + "].value", null); + } + + structure.setCategoryPath(new CategoryPath("/oat")); + return structure; + } + +} diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClass.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClass.java index 5fa0ce8da0..47e461bf04 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClass.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClass.java @@ -76,7 +76,11 @@ public abstract class OatClass implements StructConverter { break; } case OatConstants.VERSION_11_RELEASE: - case OatConstants.VERSION_12_RELEASE: { + case OatConstants.VERSION_12_RELEASE: + case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: + case OatConstants.VERSION_13_RELEASE: { statusEnum = OatClassStatusEnum_11_12.kLast.get(status_); break; } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClassFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClassFactory.java index 8f2dd9a216..8bd41dccef 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClassFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatclass/OatClassFactory.java @@ -51,6 +51,9 @@ public class OatClassFactory { return new OatClass_Android11(reader, classDataItem, oatVersion); case OatConstants.VERSION_12_RELEASE: case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: + case OatConstants.VERSION_13_RELEASE: return new OatClass_Android12(reader, classDataItem, oatVersion); default: throw new UnsupportedOatVersionException( diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatdexfile/OatDexFileFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatdexfile/OatDexFileFactory.java index aeadcaf2fc..c15aaa1b59 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatdexfile/OatDexFileFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/oatdexfile/OatDexFileFactory.java @@ -51,6 +51,9 @@ public final class OatDexFileFactory { return new OatDexFile_Android11(reader, bundle); case OatConstants.VERSION_12_RELEASE: case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: + case OatConstants.VERSION_13_RELEASE: return new OatDexFile_Android12(reader, bundle); } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeaderFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeaderFactory.java index 901c949ba6..ea64e9a09f 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeaderFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeaderFactory.java @@ -43,6 +43,9 @@ public final class OatQuickMethodHeaderFactory { return 8; case OatConstants.VERSION_12_RELEASE: case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: + case OatConstants.VERSION_13_RELEASE: return 4; } throw new IOException("OatQuickMethodHeader unsupported OAT version: " + oatVersion); @@ -69,6 +72,10 @@ public final class OatQuickMethodHeaderFactory { case OatConstants.VERSION_11_RELEASE: return new OatQuickMethodHeader_Android10(reader); case OatConstants.VERSION_12_RELEASE: + case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: + case OatConstants.VERSION_13_RELEASE: return new OatQuickMethodHeader_Android12(reader); } throw new IOException("OatQuickMethodHeader unsupported OAT version: " + oatVersion); diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeader_Android12.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeader_Android12.java index a758e54605..385e02740f 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeader_Android12.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/quickmethod/OatQuickMethodHeader_Android12.java @@ -22,7 +22,7 @@ import ghidra.program.model.data.*; import ghidra.util.exception.DuplicateNameException; /** - * https://android.googlesource.com/platform/art/+/refs/heads/android-s-beta-5/runtime/oat_quick_method_header.h#160 + * https://android.googlesource.com/platform/art/+/refs/heads/android12-release/runtime/oat_quick_method_header.h#160 * */ public class OatQuickMethodHeader_Android12 extends OatQuickMethodHeader { diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/tlt/TypeLookupTableFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/tlt/TypeLookupTableFactory.java index a02fb29e16..b12264d336 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/tlt/TypeLookupTableFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/oat/tlt/TypeLookupTableFactory.java @@ -42,6 +42,9 @@ public final class TypeLookupTableFactory { return new TypeLookupTable_Android11(reader); case OatConstants.VERSION_12_RELEASE: case OatConstants.VERSION_S_V2_PREVIEW: + case OatConstants.VERSION_T_PREVIEW_1: + case OatConstants.VERSION_S_V2_BETA2: + case OatConstants.VERSION_13_RELEASE: return new TypeLookupTable_Android12(reader); default: throw new IOException(new UnsupportedOatVersionException( diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/VdexConstants.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/VdexConstants.java index f4b69e1a5f..6874a245b6 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/VdexConstants.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/VdexConstants.java @@ -40,14 +40,23 @@ public final class VdexConstants { */ public final static String MAGIC = "vdex"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-preview/runtime/vdex_file.h#64 */ public final static String version_o_preview = "003"; + /** https://android.googlesource.com/platform/art/+/refs/heads/oreo-release/runtime/vdex_file.h#69 */ public final static String VERSION_OREO_RELEASE = "006"; + /** https://android.googlesource.com/platform/art/+/refs/heads/oreo-m2-release/runtime/vdex_file.h#76 */ public final static String VERSION_OREO_M2_RELEASE = "010"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-iot-preview-5/runtime/vdex_file.h#76 */ public final static String version_o_iot_preview_5 = "010"; + /** https://android.googlesource.com/platform/art/+/refs/heads/o-mr1-iot-preview-6/runtime/vdex_file.h#76 */ public final static String version_o_mr1_iot_preview_6 = "011"; + /** https://android.googlesource.com/platform/art/+/refs/heads/pie-release/runtime/vdex_file.h#96 */ public final static String VERSION_PIE_RELEASE = "019"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android10-release/runtime/vdex_file.h#118 */ public final static String VERSION_10_RELEASE = "021"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android11-release/runtime/vdex_file.h#118 */ public final static String VERSION_11_RELEASE = "021"; + /** https://android.googlesource.com/platform/art/+/refs/heads/android12-release/runtime/vdex_file.h#127 */ public final static String VERSION_12_RELEASE = "027"; /** diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexHeader_12.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexHeader_12.java index 3c5a6f9657..1b462c12be 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexHeader_12.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexHeader_12.java @@ -35,7 +35,8 @@ import ghidra.util.task.TaskMonitor; * https://android.googlesource.com/platform/art/+/refs/heads/android-s-beta-5/runtime/vdex_file.h#129 * * https://android.googlesource.com/platform/art/+/refs/heads/android12-release/runtime/vdex_file.h#129 - * + * + * https://android.googlesource.com/platform/art/+/refs/heads/android13-release/runtime/vdex_file.h#129 */ public class VdexHeader_12 extends VdexHeader { diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexSectionHeader_12.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexSectionHeader_12.java index 559bee9c8e..7203dde307 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexSectionHeader_12.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/vdex/android12/VdexSectionHeader_12.java @@ -24,7 +24,10 @@ import ghidra.util.exception.DuplicateNameException; /** * https://android.googlesource.com/platform/art/+/refs/heads/android-s-beta-5/runtime/vdex_file.h#92 - * + * + * https://android.googlesource.com/platform/art/+/refs/heads/android12-release/runtime/vdex_file.h#92 + * + * https://android.googlesource.com/platform/art/+/refs/heads/android13-release/runtime/vdex_file.h#92 */ public class VdexSectionHeader_12 implements StructConverter { diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/versions/AndroidVersion.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/versions/AndroidVersion.java new file mode 100644 index 0000000000..eda52059a9 --- /dev/null +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/versions/AndroidVersion.java @@ -0,0 +1,145 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.file.formats.android.versions; + +/** + * https://developer.android.com/studio/releases/platforms + *
+ * https://en.wikipedia.org/wiki/Android_version_history#Overview + */ +public enum AndroidVersion { + //@formatter:off + VERSION_1_5 ( 3, "1.5", 'C', "Cupcake"), + VERSION_1_6 ( 4, "1.5", 'D', "Donut"), + VERSION_2_0 ( 5, "2.0", 'E', "Eclair"), + VERSION_2_0_1( 6, "2.0.1", 'E', "Eclair"), + VERSION_2_1 ( 7, "2.1", 'E', "Eclair"), + VERSION_2_2 ( 8, "2.2", 'F', "Froyo"), + VERSION_2_2_1( 8, "2.2.1", 'F', "Froyo"), + VERSION_2_2_2( 8, "2.2.2", 'F', "Froyo"), + VERSION_2_2_3( 8, "2.2.3", 'F', "Froyo"), + VERSION_2_3 ( 9, "2.3", 'G', "Gingerbread"), + VERSION_2_3_1( 9, "2.3.1", 'G', "Gingerbread"), + VERSION_2_3_2( 9, "2.3.2", 'G', "Gingerbread"), + VERSION_2_3_3(10, "2.3.3", 'G', "Gingerbread"), + VERSION_2_3_4(10, "2.3.4", 'G', "Gingerbread"), + VERSION_2_3_5(10, "2.3.5", 'G', "Gingerbread"), + VERSION_2_3_6(10, "2.3.6", 'G', "Gingerbread"), + VERSION_2_3_7(10, "2.3.7", 'G', "Gingerbread"), + VERSION_3_0 (11, "3.0", 'H', "Honeycomb"), + VERSION_3_1 (12, "3.1", 'H', "Honeycomb"), + VERSION_3_2 (13, "3.2", 'H', "Honeycomb"), + VERSION_3_2_1(13, "3.2.1", 'H', "Honeycomb"), + VERSION_3_2_2(13, "3.2.2", 'H', "Honeycomb"), + VERSION_3_2_3(13, "3.2.3", 'H', "Honeycomb"), + VERSION_3_2_4(13, "3.2.4", 'H', "Honeycomb"), + VERSION_3_2_5(13, "3.2.5", 'H', "Honeycomb"), + VERSION_3_2_6(13, "3.2.6", 'H', "Honeycomb"), + VERSION_4_0 (14, "4.0", 'I', "Ice Cream Sandwich"), + VERSION_4_0_1(14, "4.0.1", 'I', "Ice Cream Sandwich"), + VERSION_4_0_2(14, "4.0.2", 'I', "Ice Cream Sandwich"), + VERSION_4_0_3(15, "4.0.3", 'I', "Ice Cream Sandwich"), + VERSION_4_0_4(15, "4.0.4", 'I', "Ice Cream Sandwich"), + VERSION_4_1 (16, "4.1", 'J', "Jelly Bean"), + VERSION_4_1_1(16, "4.1.1", 'J', "Jelly Bean"), + VERSION_4_1_2(16, "4.1.2", 'J', "Jelly Bean"), + VERSION_4_2 (17, "4.2", 'J', "Jelly Bean"), + VERSION_4_2_1(17, "4.2.1", 'J', "Jelly Bean"), + VERSION_4_2_2(17, "4.2.1", 'J', "Jelly Bean"), + VERSION_4_3 (18, "4.3", 'J', "Jelly Bean"), + VERSION_4_3_1(18, "4.3.1", 'J', "Jelly Bean"), + VERSION_4_4 (19, "4.4", 'K', "KitKat"), + VERSION_4_4_1(19, "4.4.1", 'K', "KitKat"), + VERSION_4_4_2(19, "4.4.2", 'K', "KitKat"), + VERSION_4_4_3(19, "4.4.3", 'K', "KitKat"), + VERSION_4_4_4(19, "4.4.4", 'K', "KitKat"), + VERSION_4_4_W(20, "4.4W", 'K', "KitKat"), + VERSION_5_0 (21, "5.0", 'L', "Lollipop"), + VERSION_5_0_1(21, "5.0.1", 'L', "Lollipop"), + VERSION_5_0_2(21, "5.0.2", 'L', "Lollipop"), + VERSION_5_1 (22, "5.1", 'L', "Lollipop"), + VERSION_5_1_1(22, "5.1.1", 'L', "Lollipop"), + VERSION_6_0 (23, "6.0", 'M', "Marshmallow"), + VERSION_6_0_1(23, "6.0.1", 'M', "Marshmallow"), + VERSION_7_0 (24, "7.0", 'N', "Nougat"), + VERSION_7_1 (25, "7.1", 'N', "Nougat"), + VERSION_7_1_1(25, "7.1.1", 'N', "Nougat"), + VERSION_7_1_2(25, "7.1.2", 'N', "Nougat"), + VERSION_8_0 (26, "8.0", 'O', "Oreo"), + VERSION_8_1 (27, "8.1", 'O', "Oreo"), + VERSION_9 (28, "9", 'P', "Pie"), + VERSION_10 (29, "10", 'Q', "Quince Tart"), + VERSION_11 (30, "11", 'R', "Red Velvet Cake"), + VERSION_12 (31, "12", 'S', "Snow Cone"), + VERSION_12_L (32, "12L", 'S', "Snow Cone v2"), + VERSION_13 (33, "13", 'T', "Tiramisu"), + + UNKNOWN ( 0, "0", '\0', ""); + //@formatter:on + + public static final int INVALID_API_VALUE = -1; + + private int apiVersion; + private String versionNumber; + private char versionLetter; + private String versionName; + + private AndroidVersion(int apiVersion, String versionNumber, char versionLetter, + String versionName) { + + this.apiVersion = apiVersion; + this.versionNumber = versionNumber; + this.versionLetter = versionLetter; + this.versionName = versionName; + } + + /** + * Returns the API version. + * For example, 24, 25, 26, etc. + * @return the API version + */ + public int getApiVersion() { + return apiVersion; + } + + /** + * Returns the OS version. + * For example, "4.0", "5.0.1", etc. + * @return the OS version + */ + public String getVersionNumber() { + return versionNumber; + } + + /** + * Returns the version letter. + * For example, "S", "T", etc. + * @return the version letter + */ + public char getVersionLetter() { + return versionLetter; + } + + /** + * Returns the version name. + * For example, "KitKat", "Oreo", etc. + * @return the version name + */ + public String getVersionName() { + return versionName; + } + +} diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/versions/AndroidVersionManager.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/versions/AndroidVersionManager.java new file mode 100644 index 0000000000..bc58878cbc --- /dev/null +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/android/versions/AndroidVersionManager.java @@ -0,0 +1,145 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.file.formats.android.versions; + +import java.util.*; + +public class AndroidVersionManager { + + /** Name of XML attribute in the AndroidManifest.xml file. */ + public static final String PLATFORM_BUILD_VERSION_NAME = "platformBuildVersionName"; + + /** Name of XML attribute in the AndroidManifest.xml file. */ + public static final String PLATFORM_BUILD_VERSION_CODE = "platformBuildVersionCode"; + + /** + * Returns an array of AndroidVersion's for the given API level. + * For example, Android API level "23" applied to versions "6.0" and "6.0.1". + * @param api the Android API level + * @return the AndroidVersion for the given API level + */ + public static List getByAPI(int api) { + List list = new ArrayList<>(); + for (AndroidVersion androidVersion : AndroidVersion.values()) { + if (androidVersion.getApiVersion() == api) { + list.add(androidVersion); + } + } + return list; + } + + /** + * Returns the AndroidVersion for the given version number. + * For example, "4.0", "5.0.1", etc. + * @param number the Android version number + * @return the AndroidVersion for the given version number + */ + public static AndroidVersion getByNumber(String number) { + for (AndroidVersion androidVersion : AndroidVersion.values()) { + if (androidVersion.getVersionNumber().equals(number)) { + return androidVersion; + } + } + return AndroidVersion.UNKNOWN; + } + + /** + * Returns an array of AndroidVersion's for the given version letter. + * For example, Android 'M' applied to versions "6.0" and "6.0.1". + * @param letter the Android version letter + * @return the AndroidVersion for the given version letter + */ + public static List getByLetter(char letter) { + List list = new ArrayList<>(); + for (AndroidVersion androidVersion : AndroidVersion.values()) { + if (androidVersion.getVersionLetter() == letter) { + list.add(androidVersion); + } + } + return list; + } + + /** + * Returns an array of AndroidVersion's for the given version letter. + * For example, Android 'M' applied to versions "6.0" and "6.0.1". + * @param letter the Android version letter + * @return the AndroidVersion for the given version letter + */ + public static List getByLetter(String letter) { + if (letter == null || letter.length() == 0) { + return Collections.emptyList(); + } + return getByLetter(letter.charAt(0)); + } + + /** + * Returns an array of AndroidVersion's for the given version name. + * For example, Android "Marshmallow" applied to versions "6.0" and "6.0.1". + * @param name the Android version name + * @return the AndroidVersion for the given version name + */ + public static List getByName(String name) { + List list = new ArrayList<>(); + for (AndroidVersion androidVersion : AndroidVersion.values()) { + if (androidVersion.getVersionName().equals(name)) { + list.add(androidVersion); + } + } + return list; + } + + /** + * Returns the Android Version for the given code or name. + * The code will represent the API version. + * The name can specify either the version number (eg 5.0.1), version name (eg Oreo), or version letter (eg M). + * The "PlatformBuildVersionCode" and "PlatformBuildVersionName" are specified + * in the AndroidManifest.xml file. + *
+	 * platformBuildVersionCode="33"
+	 * platformBuildVersionName="T"
+	 * 
+ * @param code the PlatformBuildVersionCode specified in the AndroidManifest.xml + * @param name the PlatformBuildVersionName specified in the AndroidManifest.xml + * @return the AndroidVersion for the given PlatformBuildVersionCode or PlatformBuildVersionName + */ + public static AndroidVersion getByPlatformBuildVersion(String code, String name) { + for (AndroidVersion version : AndroidVersion.values()) { + if (version.getApiVersion() == toInteger(code)) { + return version; + } + else if (version.getVersionName().equals(name)) { + return version; + } + else if (version.getVersionNumber().equals(name)) { + return version; + } + else if (String.valueOf(version.getVersionLetter()).equals(name)) { + return version; + } + } + return AndroidVersion.UNKNOWN; + } + + private static int toInteger(String platformBuildVersionCode) { + try { + return Integer.parseInt(platformBuildVersionCode); + } + catch (Exception e) { + return AndroidVersion.INVALID_API_VALUE; + } + } + +} diff --git a/Ghidra/Processors/Dalvik/data/languages/Dalvik.ldefs b/Ghidra/Processors/Dalvik/data/languages/Dalvik.ldefs index 9045716b10..21bcd33644 100644 --- a/Ghidra/Processors/Dalvik/data/languages/Dalvik.ldefs +++ b/Ghidra/Processors/Dalvik/data/languages/Dalvik.ldefs @@ -147,5 +147,18 @@ Dalvik DEX Android12 - + + + + Dalvik DEX Android13 + + + diff --git a/Ghidra/Processors/Dalvik/data/languages/Dalvik.opinion b/Ghidra/Processors/Dalvik/data/languages/Dalvik.opinion index 6bd557d633..e19ce577ea 100644 --- a/Ghidra/Processors/Dalvik/data/languages/Dalvik.opinion +++ b/Ghidra/Processors/Dalvik/data/languages/Dalvik.opinion @@ -2,64 +2,53 @@ + + + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + + - + + diff --git a/Ghidra/Processors/Dalvik/data/languages/Dalvik_DEX_Android12.slaspec b/Ghidra/Processors/Dalvik/data/languages/Dalvik_DEX_Android12.slaspec index bd9ee176d0..9cd7bad62d 100644 --- a/Ghidra/Processors/Dalvik/data/languages/Dalvik_DEX_Android12.slaspec +++ b/Ghidra/Processors/Dalvik/data/languages/Dalvik_DEX_Android12.slaspec @@ -3,7 +3,8 @@ #------------------------------------------------------------------------------------ # Source: -# https://android.googlesource.com/platform/art/+/refs/heads/android-s-beta-5/libdexfile/dex/dex_instruction_list.h +# https://android.googlesource.com/platform/art/+/refs/heads/android12-release/libdexfile/dex/dex_instruction_list.h +# https://android.googlesource.com/platform/art/+/refs/heads/android13-release/libdexfile/dex/dex_instruction_list.h @include "Dalvik_Base.sinc"