Changes to support android 13 T.

Added Android Version Manager.
This commit is contained in:
lazybinding-dev 2022-09-19 09:41:49 -04:00
parent 9088fd7885
commit f58070f484
23 changed files with 651 additions and 61 deletions

View File

@ -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<QueryResult> 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

View File

@ -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
* <a href="https://android.googlesource.com/platform/art/+/master/runtime/image.cc">master/runtime/image.cc</a>
*/
public final class ArtConstants {
@ -30,34 +30,34 @@ public final class ArtConstants {
public final static int VERSION_LENGTH = 4;
/** <a href="https://android.googlesource.com/platform/art/+/refs/heads/kitkat-release/runtime/image.cc#26">kitkat-release/runtime/image.c */
public final static String VERSION_KITKAT_RELEASE = "005";
/** <a href="https://android.googlesource.com/platform/art/+/refs/heads/lollipop-release/runtime/image.cc#26">lollipop-release/runtime/image.c */
public final static String VERSION_LOLLIPOP_RELEASE = "009";
/** <a href="https://android.googlesource.com/platform/art/+/refs/heads/lollipop-mr1-wfc-release/runtime/image.cc#26">lollipop-mr1-wfc-release/runtime/image.c */
public final static String VERSION_LOLLIPOP_MR1_WFC_RELEASE = "012";
/** <a href="https://android.googlesource.com/platform/art/+/marshmallow-release/runtime/image.cc#26">marshmallow-release/runtime/image.c */
public final static String VERSION_MARSHMALLOW_RELEASE = "017";
/** <a href="https://android.googlesource.com/platform/art/+/nougat-release/runtime/image.cc#26">nougat-release/runtime/image.c */
public final static String VERSION_NOUGAT_RELEASE = "029";
/** <a href="https://android.googlesource.com/platform/art/+/nougat-mr2-pixel-release/runtime/image.cc#26">nougat-mr2-pixel-release/runtime/image.c */
public final static String VERSION_NOUGAT_MR2_PIXEL_RELEASE = "030";
/** <a href="https://android.googlesource.com/platform/art/+/oreo-release/runtime/image.cc#28">oreo-release/runtime/image.c */
public final static String VERSION_OREO_RELEASE = "043";
/** <a href="https://android.googlesource.com/platform/art/+/oreo-dr1-release/runtime/image.cc#28">oreo-dr1-release/runtime/image.c */
public final static String VERSION_OREO_DR1_RELEASE = "044";
/** <a href="https://android.googlesource.com/platform/art/+/oreo-mr1-release/runtime/image.cc#28">oreo-mr1-release/runtime/image.c */
public final static String VERSION_OREO_MR1_RELEASE = "046";
/** <a href="https://android.googlesource.com/platform/art/+/pie-release/runtime/image.cc#28">pie-release/runtime/image.c */
public final static String VERSION_PIE_RELEASE = "056";
/** <a href="https://android.googlesource.com/platform/art/+/android10-release/runtime/image.cc#31">android10-release/runtime/image.c */
public final static String VERSION_10_RELEASE = "074";//Q
/** <a href="https://android.googlesource.com/platform/art/+/android11-release/runtime/image.cc#31">android11-release/runtime/image.c */
public final static String VERSION_11_RELEASE = "085";//R
/** <a href="https://android.googlesource.com/platform/art/+/android12-release/runtime/image.cc#31">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
/** <a href="https://android.googlesource.com/platform/art/+/android13-release/runtime/image.cc#31">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
};

View File

@ -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);
}
}

View File

@ -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(

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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<OatDexFile> 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;
}
}

View File

@ -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;
}

View File

@ -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(

View File

@ -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);
}

View File

@ -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);

View File

@ -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 {

View File

@ -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(

View File

@ -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";
/**

View File

@ -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 {

View File

@ -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 {

View File

@ -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
* <br>
* 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;
}
}

View File

@ -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<AndroidVersion> getByAPI(int api) {
List<AndroidVersion> 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<AndroidVersion> getByLetter(char letter) {
List<AndroidVersion> 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<AndroidVersion> 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<AndroidVersion> getByName(String name) {
List<AndroidVersion> 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.
* <pre>
* platformBuildVersionCode="33"
* platformBuildVersionName="T"
* </pre>
* @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;
}
}
}

View File

@ -147,5 +147,18 @@
<description>Dalvik DEX Android12</description>
<compiler name="default" spec="Dalvik_Base.cspec" id="default"/>
</language>
<!-- Android 13 is identical to Android 12, so just reuse -->
<language processor="Dalvik"
endian="little"
size="32"
variant="DEX Android13"
version="1.0"
slafile="Dalvik_DEX_Android12.sla"
processorspec="Dalvik_Base.pspec"
id="Dalvik:LE:32:DEX_Android13">
<description>Dalvik DEX Android13</description>
<compiler name="default" spec="Dalvik_Base.cspec" id="default"/>
</language>
</language_definitions>

View File

@ -2,64 +2,53 @@
<constraint loader="Dalvik Executable (DEX)" compilerSpecID="default">
<constraint primary="1" processor="Dalvik" endian="little" size="32" />
</constraint>
<constraint loader="Compact Dalvik Executable (CDEX)" compilerSpecID="default">
<constraint primary="1" processor="Dalvik" endian="little" size="32" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" processor="Dalvik" endian="little" size="32" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="K" processor="Dalvik" endian="little" size="32" variant="DEX KitKat" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="4" processor="Dalvik" endian="little" size="32" variant="DEX KitKat" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="L" processor="Dalvik" endian="little" size="32" variant="DEX Lollipop" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="5" processor="Dalvik" endian="little" size="32" variant="DEX Lollipop" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="M" processor="Dalvik" endian="little" size="32" variant="DEX Marshmallow" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="6" processor="Dalvik" endian="little" size="32" variant="DEX Marshmallow" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="N" processor="Dalvik" endian="little" size="32" variant="DEX Nougat" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="7" processor="Dalvik" endian="little" size="32" variant="DEX Nougat" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="O" processor="Dalvik" endian="little" size="32" variant="DEX Oreo" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="8" processor="Dalvik" endian="little" size="32" variant="DEX Oreo" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="P" processor="Dalvik" endian="little" size="32" variant="DEX Pie" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="9" processor="Dalvik" endian="little" size="32" variant="DEX Pie" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="Q" processor="Dalvik" endian="little" size="32" variant="DEX Android10" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="10" processor="Dalvik" endian="little" size="32" variant="DEX Android10" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="R" processor="Dalvik" endian="little" size="32" variant="DEX Android11" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="11" processor="Dalvik" endian="little" size="32" variant="DEX Android11" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="S" processor="Dalvik" endian="little" size="32" variant="DEX Android12" />
</constraint>
<constraint loader="Android APK" compilerSpecID="default">
<constraint primary="1" secondary="12" processor="Dalvik" endian="little" size="32" variant="DEX Android12" />
<constraint primary="1" secondary="T" processor="Dalvik" endian="little" size="32" variant="DEX Android13" />
</constraint>
</opinions>

View File

@ -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"