• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.dexbacked.raw;
33 
34 import org.jf.dexlib2.dexbacked.BaseDexBuffer;
35 
36 public class OdexHeaderItem {
37     public static final int ITEM_SIZE = 40;
38 
39     private static final byte[] MAGIC_VALUE = new byte[] { 0x64, 0x65, 0x79, 0x0A, 0x00, 0x00, 0x00, 0x00 };
40     private static final int[] SUPPORTED_ODEX_VERSIONS = new int[] { 35, 36 };
41 
42     public static final int MAGIC_OFFSET = 0;
43     public static final int MAGIC_LENGTH = 8;
44     public static final int DEX_OFFSET = 8;
45     public static final int DEX_LENGTH_OFFSET = 12;
46     public static final int DEPENDENCIES_OFFSET = 16;
47     public static final int DEPENDENCIES_LENGTH_OFFSET = 20;
48     public static final int AUX_OFFSET = 24;
49     public static final int AUX_LENGTH_OFFSET = 28;
50     public static final int FLAGS_OFFSET = 32;
51 
52     /**
53      * Verifies the magic value at the beginning of an odex file
54      *
55      * @param buf A byte array containing at least the first 8 bytes of an odex file
56      * @param offset The offset within the buffer to the beginning of the odex header
57      * @return True if the magic value is valid
58      */
verifyMagic(byte[] buf, int offset)59     public static boolean verifyMagic(byte[] buf, int offset) {
60         if (buf.length - offset < 8) {
61             return false;
62         }
63 
64         for (int i=0; i<4; i++) {
65             if (buf[offset + i] != MAGIC_VALUE[i]) {
66                 return false;
67             }
68         }
69         for (int i=4; i<7; i++) {
70             if (buf[offset + i] < '0' ||
71                     buf[offset + i] > '9') {
72                 return false;
73             }
74         }
75         if (buf[offset + 7] != MAGIC_VALUE[7]) {
76             return false;
77         }
78 
79         return true;
80     }
81 
82     /**
83      * Gets the dex version from an odex header
84      *
85      * @param buf A byte array containing at least the first 7 bytes of an odex file
86      * @param offset The offset within the buffer to the beginning of the odex header
87      * @return The odex version if the header is valid or -1 if the header is invalid
88      */
getVersion(byte[] buf, int offset)89     public static int getVersion(byte[] buf, int offset) {
90         if (!verifyMagic(buf, offset)) {
91             return -1;
92         }
93 
94         return getVersionUnchecked(buf, offset);
95     }
96 
getVersionUnchecked(byte[] buf, int offset)97     private static int getVersionUnchecked(byte[] buf, int offset) {
98         int version = (buf[offset + 4] - '0') * 100;
99         version += (buf[offset + 5] - '0') * 10;
100         version += buf[offset + 6] - '0';
101 
102         return version;
103     }
104 
isSupportedOdexVersion(int version)105     public static boolean isSupportedOdexVersion(int version) {
106         for (int i=0; i<SUPPORTED_ODEX_VERSIONS.length; i++) {
107             if (SUPPORTED_ODEX_VERSIONS[i] == version) {
108                 return true;
109             }
110         }
111         return false;
112     }
113 
getDexOffset(byte[] buf)114     public static int getDexOffset(byte[] buf) {
115         BaseDexBuffer bdb = new BaseDexBuffer(buf);
116         return bdb.readSmallUint(DEX_OFFSET);
117     }
118 
getDependenciesOffset(byte[] buf)119     public static int getDependenciesOffset(byte[] buf) {
120         BaseDexBuffer bdb = new BaseDexBuffer(buf);
121         return bdb.readSmallUint(DEPENDENCIES_OFFSET);
122     }
123 }
124