1d5f47bae4902560746db40e65874db68d95ee742Ben Gruver/* 2d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * Copyright 2013, Google Inc. 3d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * All rights reserved. 4d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * 5d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * Redistribution and use in source and binary forms, with or without 6d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * modification, are permitted provided that the following conditions are 7d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * met: 8d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * 9d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * * Redistributions of source code must retain the above copyright 10d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * notice, this list of conditions and the following disclaimer. 11d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * * Redistributions in binary form must reproduce the above 12d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * copyright notice, this list of conditions and the following disclaimer 13d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * in the documentation and/or other materials provided with the 14d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * distribution. 15d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * * Neither the name of Google Inc. nor the names of its 16d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * contributors may be used to endorse or promote products derived from 17d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * this software without specific prior written permission. 18d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * 19d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29d5f47bae4902560746db40e65874db68d95ee742Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30d5f47bae4902560746db40e65874db68d95ee742Ben Gruver */ 31d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 32d5f47bae4902560746db40e65874db68d95ee742Ben Gruverpackage org.jf.dexlib2.dexbacked.raw; 33d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 34d5f47bae4902560746db40e65874db68d95ee742Ben Gruverimport org.jf.dexlib2.dexbacked.DexReader; 35d5f47bae4902560746db40e65874db68d95ee742Ben Gruverimport org.jf.dexlib2.util.AnnotatedBytes; 36d5f47bae4902560746db40e65874db68d95ee742Ben Gruverimport org.jf.util.ExceptionWithContext; 37d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 38d5f47bae4902560746db40e65874db68d95ee742Ben Gruverimport javax.annotation.Nonnull; 39d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 40d5f47bae4902560746db40e65874db68d95ee742Ben Gruverpublic class EncodedValue { 41d5f47bae4902560746db40e65874db68d95ee742Ben Gruver public static void annotateEncodedValue(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) { 42d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int valueArgType = reader.readUbyte(); 43d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 44d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int valueArg = valueArgType >>> 5; 45d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int valueType = valueArgType & 0x1f; 46d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 47d5f47bae4902560746db40e65874db68d95ee742Ben Gruver switch (valueType) { 48d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x00: 49d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: byte", valueArg, valueType); 50d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int intValue = reader.readByte(); 51d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "value = 0x%x", intValue); 52d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 53d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x02: 54d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: short", valueArg, valueType); 55d5f47bae4902560746db40e65874db68d95ee742Ben Gruver intValue = reader.readSizedInt(valueArg+1); 56d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg + 1, "value = 0x%x", intValue); 57d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 58d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x03: 59d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: char", valueArg, valueType); 60d5f47bae4902560746db40e65874db68d95ee742Ben Gruver intValue = reader.readSizedSmallUint(valueArg+1); 61d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = 0x%x", intValue); 62d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 63d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x04: 64d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: int", valueArg, valueType); 65d5f47bae4902560746db40e65874db68d95ee742Ben Gruver intValue = reader.readSizedInt(valueArg+1); 66d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = 0x%x", intValue); 67d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 68d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x06: 69d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: long", valueArg, valueType); 70d5f47bae4902560746db40e65874db68d95ee742Ben Gruver long longValue = reader.readSizedLong(valueArg+1); 71d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = 0x%x", longValue); 72d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 73d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x10: 74d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: float", valueArg, valueType); 75d5f47bae4902560746db40e65874db68d95ee742Ben Gruver float floatValue = Float.intBitsToFloat(reader.readSizedRightExtendedInt(valueArg + 1)); 76d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %f", floatValue); 77d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 78d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x11: 79d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: double", valueArg, valueType); 80d5f47bae4902560746db40e65874db68d95ee742Ben Gruver double doubleValue = Double.longBitsToDouble(reader.readSizedRightExtendedLong(valueArg + 1)); 81d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %f", doubleValue); 82d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 83d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x17: 84d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: string", valueArg, valueType); 85d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int stringIndex = reader.readSizedSmallUint(valueArg + 1); 86d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %s", 87d5f47bae4902560746db40e65874db68d95ee742Ben Gruver StringIdItem.getReferenceAnnotation(reader.dexBuf, stringIndex, true)); 88d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 89d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x18: 90d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: type", valueArg, valueType); 91d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int typeIndex = reader.readSizedSmallUint(valueArg+1); 92d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %s", TypeIdItem.getReferenceAnnotation(reader.dexBuf, typeIndex)); 93d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 94d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x19: 95d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: field", valueArg, valueType); 96d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int fieldIndex = reader.readSizedSmallUint(valueArg+1); 97d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %s", FieldIdItem.getReferenceAnnotation(reader.dexBuf, fieldIndex)); 98d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 99d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x1a: 100d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: method", valueArg, valueType); 101d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int methodIndex = reader.readSizedSmallUint(valueArg+1); 102d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %s", MethodIdItem.getReferenceAnnotation(reader.dexBuf, methodIndex)); 103d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 104d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x1b: 105d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: enum", valueArg, valueType); 106d5f47bae4902560746db40e65874db68d95ee742Ben Gruver fieldIndex = reader.readSizedSmallUint(valueArg+1); 107d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(valueArg+1, "value = %s", FieldIdItem.getReferenceAnnotation(reader.dexBuf, fieldIndex)); 108d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 109d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x1c: 110d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: array", valueArg, valueType); 111d5f47bae4902560746db40e65874db68d95ee742Ben Gruver annotateEncodedArray(out, reader); 112d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 113d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x1d: 114d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: annotation", valueArg, valueType); 115d5f47bae4902560746db40e65874db68d95ee742Ben Gruver annotateEncodedAnnotation(out, reader); 116d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 117d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x1e: 118d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: null", valueArg, valueType); 119d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 120d5f47bae4902560746db40e65874db68d95ee742Ben Gruver case 0x1f: 121d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(1, "valueArg = %d, valueType = 0x%x: boolean, value=%s", valueArg, valueType, valueArg==1); 122d5f47bae4902560746db40e65874db68d95ee742Ben Gruver break; 123d5f47bae4902560746db40e65874db68d95ee742Ben Gruver default: 124d5f47bae4902560746db40e65874db68d95ee742Ben Gruver throw new ExceptionWithContext("Invalid encoded value type 0x%x at offset 0x%x", valueType, 125d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.getCursor()); 126d5f47bae4902560746db40e65874db68d95ee742Ben Gruver } 127d5f47bae4902560746db40e65874db68d95ee742Ben Gruver } 128d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 129d5f47bae4902560746db40e65874db68d95ee742Ben Gruver public static void annotateEncodedAnnotation(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) { 130d5f47bae4902560746db40e65874db68d95ee742Ben Gruver assert out.getCursor() == reader.getOffset(); 131d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 132d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int typeIndex = reader.readSmallUleb128(); 13331d87776c459972f311a3527694e0d630d92a84bBen Gruver out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(reader.dexBuf, typeIndex)); 134d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 135d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int size = reader.readSmallUleb128(); 13631d87776c459972f311a3527694e0d630d92a84bBen Gruver out.annotateTo(reader.getOffset(), "size: %d", size); 137d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 138d5f47bae4902560746db40e65874db68d95ee742Ben Gruver for (int i=0; i<size; i++) { 139d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(0, "element[%d]", i); 140d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.indent(); 141d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 142d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int nameIndex = reader.readSmallUleb128(); 14331d87776c459972f311a3527694e0d630d92a84bBen Gruver out.annotateTo(reader.getOffset(), "name = %s", 144d5f47bae4902560746db40e65874db68d95ee742Ben Gruver StringIdItem.getReferenceAnnotation(reader.dexBuf, nameIndex)); 145d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 146d5f47bae4902560746db40e65874db68d95ee742Ben Gruver annotateEncodedValue(out, reader); 147d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 148d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.deindent(); 149d5f47bae4902560746db40e65874db68d95ee742Ben Gruver } 150d5f47bae4902560746db40e65874db68d95ee742Ben Gruver } 151d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 152d5f47bae4902560746db40e65874db68d95ee742Ben Gruver public static void annotateEncodedArray(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) { 153d5f47bae4902560746db40e65874db68d95ee742Ben Gruver assert out.getCursor() == reader.getOffset(); 154d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 155d5f47bae4902560746db40e65874db68d95ee742Ben Gruver int size = reader.readSmallUleb128(); 15631d87776c459972f311a3527694e0d630d92a84bBen Gruver out.annotateTo(reader.getOffset(), "size: %d", size); 157d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 158d5f47bae4902560746db40e65874db68d95ee742Ben Gruver for (int i=0; i<size; i++) { 159d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.annotate(0, "element[%d]", i); 160d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.indent(); 161d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 162d5f47bae4902560746db40e65874db68d95ee742Ben Gruver annotateEncodedValue(out, reader); 163d5f47bae4902560746db40e65874db68d95ee742Ben Gruver 164d5f47bae4902560746db40e65874db68d95ee742Ben Gruver out.deindent(); 165d5f47bae4902560746db40e65874db68d95ee742Ben Gruver } 166d5f47bae4902560746db40e65874db68d95ee742Ben Gruver } 167d5f47bae4902560746db40e65874db68d95ee742Ben Gruver} 168