1 /* 2 * Copyright 2019, Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google LLC nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 package com.android.tools.smali.dexlib2.dexbacked; 32 33 import com.android.tools.smali.dexlib2.Opcodes; 34 import com.android.tools.smali.dexlib2.dexbacked.raw.CdexHeaderItem; 35 import com.android.tools.smali.dexlib2.dexbacked.raw.HeaderItem; 36 import com.android.tools.smali.dexlib2.util.DexUtil; 37 38 import javax.annotation.Nonnull; 39 import javax.annotation.Nullable; 40 import java.io.UnsupportedEncodingException; 41 42 public class CDexBackedDexFile extends DexBackedDexFile { CDexBackedDexFile(@ullable Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic)43 public CDexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) { 44 super(opcodes, buf, offset, verifyMagic); 45 } 46 CDexBackedDexFile(@ullable Opcodes opcodes, @Nonnull DexBuffer buf)47 public CDexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull DexBuffer buf) { 48 super(opcodes, buf); 49 } 50 CDexBackedDexFile(@ullable Opcodes opcodes, @Nonnull byte[] buf, int offset)51 public CDexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull byte[] buf, int offset) { 52 super(opcodes, buf, offset); 53 } 54 CDexBackedDexFile(@ullable Opcodes opcodes, @Nonnull byte[] buf)55 public CDexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull byte[] buf) { 56 super(opcodes, buf); 57 } 58 isCdex(byte[] buf, int offset)59 public static boolean isCdex(byte[] buf, int offset) { 60 if (offset + 4 > buf.length) { 61 return false; 62 } 63 64 byte[] cdexMagic; 65 try { 66 cdexMagic = "cdex".getBytes("US-ASCII"); 67 } catch (UnsupportedEncodingException ex) { 68 throw new RuntimeException(ex); 69 } 70 return buf[offset] == cdexMagic[0] && 71 buf[offset+1] == cdexMagic[1] && 72 buf[offset+2] == cdexMagic[2] && 73 buf[offset+3] == cdexMagic[3]; 74 } 75 76 @Override getVersion(byte[] buf, int offset, boolean verifyMagic)77 protected int getVersion(byte[] buf, int offset, boolean verifyMagic) { 78 if (verifyMagic) { 79 return DexUtil.verifyCdexHeader(buf, offset); 80 } else { 81 return CdexHeaderItem.getVersion(buf, offset); 82 } 83 } 84 85 @Override getDefaultOpcodes(int version)86 protected Opcodes getDefaultOpcodes(int version) { 87 // There is currently only 1 possible cdex version, which was introduced in api 28. 88 return Opcodes.forApi(28); 89 } 90 91 @Override getBaseDataOffset()92 public int getBaseDataOffset() { 93 return getBuffer().readSmallUint(HeaderItem.DATA_START_OFFSET); 94 } 95 getDebugInfoOffsetsPos()96 public int getDebugInfoOffsetsPos() { 97 return getBuffer().readSmallUint(CdexHeaderItem.DEBUG_INFO_OFFSETS_POS_OFFSET); 98 } 99 getDebugInfoOffsetsTableOffset()100 public int getDebugInfoOffsetsTableOffset() { 101 return getBuffer().readSmallUint(CdexHeaderItem.DEBUG_INFO_OFFSETS_TABLE_OFFSET); 102 } 103 getDebugInfoBase()104 public int getDebugInfoBase() { 105 return getBuffer().readSmallUint(CdexHeaderItem.DEBUG_INFO_BASE); 106 } 107 108 @Override createMethodImplementation( @onnull DexBackedDexFile dexFile, @Nonnull DexBackedMethod method, int codeOffset)109 protected DexBackedMethodImplementation createMethodImplementation( 110 @Nonnull DexBackedDexFile dexFile, @Nonnull DexBackedMethod method, int codeOffset) { 111 return new CDexBackedMethodImplementation(dexFile, method, codeOffset); 112 } 113 } 114