1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Functions to deal with class definition structures in DEX files 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "DexClass.h" 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Leb128.h" 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Helper for verification which reads and verifies a given number 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of uleb128 values. */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool verifyUlebs(const u1* pData, const u1* pLimit, u4 count) { 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool okay = true; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (okay && (count-- != 0)) { 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project readAndVerifyUnsignedLeb128(&pData, pLimit, &okay); 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return okay; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Read and verify the header of a class_data_item. This updates the 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given data pointer to point past the end of the read data and 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns an "okay" flag (that is, false == failure). */ 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dexReadAndVerifyClassDataHeader(const u1** pData, const u1* pLimit, 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexClassDataHeader *pHeader) { 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! verifyUlebs(*pData, pLimit, 4)) { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexReadClassDataHeader(pData, pHeader); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Read and verify an encoded_field. This updates the 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given data pointer to point past the end of the read data and 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns an "okay" flag (that is, false == failure). 55de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The lastIndex value should be set to 0 before the first field in 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a list is read. It is updated as fields are read and used in the 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * decode process. 59de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The verification done by this function is of the raw data format 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only; it does not verify that access flags or indices 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are valid. */ 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dexReadAndVerifyClassDataField(const u1** pData, const u1* pLimit, 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexField* pField, u4* lastIndex) { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! verifyUlebs(*pData, pLimit, 2)) { 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexReadClassDataField(pData, pField, lastIndex); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Read and verify an encoded_method. This updates the 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given data pointer to point past the end of the read data and 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns an "okay" flag (that is, false == failure). 76de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The lastIndex value should be set to 0 before the first method in 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a list is read. It is updated as fields are read and used in the 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * decode process. 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The verification done by this function is of the raw data format 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only; it does not verify that access flags, indices, or offsets 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are valid. */ 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dexReadAndVerifyClassDataMethod(const u1** pData, const u1* pLimit, 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexMethod* pMethod, u4* lastIndex) { 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! verifyUlebs(*pData, pLimit, 3)) { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexReadClassDataMethod(pData, pMethod, lastIndex); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Read, verify, and return an entire class_data_item. This updates 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the given data pointer to point past the end of the read data. This 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * function allocates a single chunk of memory for the result, which 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must subsequently be free()d. This function returns NULL if there 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * was trouble parsing the data. If this function is passed NULL, it 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns an initialized empty DexClassData structure. 100de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The verification done by this function is of the raw data format 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only; it does not verify that access flags, indices, or offsets 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are valid. */ 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDexClassData* dexReadAndVerifyClassData(const u1** pData, const u1* pLimit) { 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexClassDataHeader header; 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 lastIndex; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*pData == NULL) { 109a70a3d8faa8f7332549fa0c9ae2008d428e28606Dan Bornstein DexClassData* result = (DexClassData*) malloc(sizeof(DexClassData)); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(result, 0, sizeof(*result)); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 113de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! dexReadAndVerifyClassDataHeader(pData, pLimit, &header)) { 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t resultSize = sizeof(DexClassData) + 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (header.staticFieldsSize * sizeof(DexField)) + 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (header.instanceFieldsSize * sizeof(DexField)) + 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (header.directMethodsSize * sizeof(DexMethod)) + 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (header.virtualMethodsSize * sizeof(DexMethod)); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124a70a3d8faa8f7332549fa0c9ae2008d428e28606Dan Bornstein DexClassData* result = (DexClassData*) malloc(resultSize); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1* ptr = ((u1*) result) + sizeof(DexClassData); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool okay = true; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == NULL) { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->header = header; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (header.staticFieldsSize != 0) { 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->staticFields = (DexField*) ptr; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += header.staticFieldsSize * sizeof(DexField); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->staticFields = NULL; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 141de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (header.instanceFieldsSize != 0) { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->instanceFields = (DexField*) ptr; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += header.instanceFieldsSize * sizeof(DexField); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->instanceFields = NULL; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 148de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (header.directMethodsSize != 0) { 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->directMethods = (DexMethod*) ptr; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += header.directMethodsSize * sizeof(DexMethod); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->directMethods = NULL; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 155de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (header.virtualMethodsSize != 0) { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->virtualMethods = (DexMethod*) ptr; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result->virtualMethods = NULL; 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastIndex = 0; 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; okay && (i < header.staticFieldsSize); i++) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = dexReadAndVerifyClassDataField(pData, pLimit, 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &result->staticFields[i], &lastIndex); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastIndex = 0; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; okay && (i < header.instanceFieldsSize); i++) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = dexReadAndVerifyClassDataField(pData, pLimit, 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &result->instanceFields[i], &lastIndex); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastIndex = 0; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; okay && (i < header.directMethodsSize); i++) { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = dexReadAndVerifyClassDataMethod(pData, pLimit, 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &result->directMethods[i], &lastIndex); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastIndex = 0; 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; okay && (i < header.virtualMethodsSize); i++) { 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project okay = dexReadAndVerifyClassDataMethod(pData, pLimit, 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &result->virtualMethods[i], &lastIndex); 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! okay) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(result); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 193