• 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.DexReader;
35 import org.jf.dexlib2.util.AnnotatedBytes;
36 import org.jf.util.ExceptionWithContext;
37 
38 import javax.annotation.Nonnull;
39 
40 public class EncodedValue {
annotateEncodedValue(@onnull AnnotatedBytes out, @Nonnull DexReader reader)41     public static void annotateEncodedValue(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) {
42         int valueArgType = reader.readUbyte();
43 
44         int valueArg = valueArgType >>> 5;
45         int valueType = valueArgType & 0x1f;
46 
47         switch (valueType) {
48             case 0x00:
49                 out.annotate(1, "valueArg = %d, valueType = 0x%x: byte", valueArg, valueType);
50                 int intValue = reader.readByte();
51                 out.annotate(1, "value = 0x%x", intValue);
52                 break;
53             case 0x02:
54                 out.annotate(1, "valueArg = %d, valueType = 0x%x: short", valueArg, valueType);
55                 intValue = reader.readSizedInt(valueArg+1);
56                 out.annotate(valueArg + 1, "value = 0x%x", intValue);
57                 break;
58             case 0x03:
59                 out.annotate(1, "valueArg = %d, valueType = 0x%x: char", valueArg, valueType);
60                 intValue = reader.readSizedSmallUint(valueArg+1);
61                 out.annotate(valueArg+1, "value = 0x%x", intValue);
62                 break;
63             case 0x04:
64                 out.annotate(1, "valueArg = %d, valueType = 0x%x: int", valueArg, valueType);
65                 intValue = reader.readSizedInt(valueArg+1);
66                 out.annotate(valueArg+1, "value = 0x%x", intValue);
67                 break;
68             case 0x06:
69                 out.annotate(1, "valueArg = %d, valueType = 0x%x: long", valueArg, valueType);
70                 long longValue = reader.readSizedLong(valueArg+1);
71                 out.annotate(valueArg+1, "value = 0x%x", longValue);
72                 break;
73             case 0x10:
74                 out.annotate(1, "valueArg = %d, valueType = 0x%x: float", valueArg, valueType);
75                 float floatValue = Float.intBitsToFloat(reader.readSizedRightExtendedInt(valueArg + 1));
76                 out.annotate(valueArg+1, "value = %f", floatValue);
77                 break;
78             case 0x11:
79                 out.annotate(1, "valueArg = %d, valueType = 0x%x: double", valueArg, valueType);
80                 double doubleValue = Double.longBitsToDouble(reader.readSizedRightExtendedLong(valueArg + 1));
81                 out.annotate(valueArg+1, "value = %f", doubleValue);
82                 break;
83             case 0x17:
84                 out.annotate(1, "valueArg = %d, valueType = 0x%x: string", valueArg, valueType);
85                 int stringIndex = reader.readSizedSmallUint(valueArg + 1);
86                 out.annotate(valueArg+1, "value = %s",
87                         StringIdItem.getReferenceAnnotation(reader.dexBuf, stringIndex, true));
88                 break;
89             case 0x18:
90                 out.annotate(1, "valueArg = %d, valueType = 0x%x: type", valueArg, valueType);
91                 int typeIndex = reader.readSizedSmallUint(valueArg+1);
92                 out.annotate(valueArg+1, "value = %s", TypeIdItem.getReferenceAnnotation(reader.dexBuf, typeIndex));
93                 break;
94             case 0x19:
95                 out.annotate(1, "valueArg = %d, valueType = 0x%x: field", valueArg, valueType);
96                 int fieldIndex = reader.readSizedSmallUint(valueArg+1);
97                 out.annotate(valueArg+1, "value = %s", FieldIdItem.getReferenceAnnotation(reader.dexBuf, fieldIndex));
98                 break;
99             case 0x1a:
100                 out.annotate(1, "valueArg = %d, valueType = 0x%x: method", valueArg, valueType);
101                 int methodIndex = reader.readSizedSmallUint(valueArg+1);
102                 out.annotate(valueArg+1, "value = %s", MethodIdItem.getReferenceAnnotation(reader.dexBuf, methodIndex));
103                 break;
104             case 0x1b:
105                 out.annotate(1, "valueArg = %d, valueType = 0x%x: enum", valueArg, valueType);
106                 fieldIndex = reader.readSizedSmallUint(valueArg+1);
107                 out.annotate(valueArg+1, "value = %s", FieldIdItem.getReferenceAnnotation(reader.dexBuf, fieldIndex));
108                 break;
109             case 0x1c:
110                 out.annotate(1, "valueArg = %d, valueType = 0x%x: array", valueArg, valueType);
111                 annotateEncodedArray(out, reader);
112                 break;
113             case 0x1d:
114                 out.annotate(1, "valueArg = %d, valueType = 0x%x: annotation", valueArg, valueType);
115                 annotateEncodedAnnotation(out, reader);
116                 break;
117             case 0x1e:
118                 out.annotate(1, "valueArg = %d, valueType = 0x%x: null", valueArg, valueType);
119                 break;
120             case 0x1f:
121                 out.annotate(1, "valueArg = %d, valueType = 0x%x: boolean, value=%s", valueArg, valueType, valueArg==1);
122                 break;
123             default:
124                 throw new ExceptionWithContext("Invalid encoded value type 0x%x at offset 0x%x", valueType,
125                         out.getCursor());
126         }
127     }
128 
annotateEncodedAnnotation(@onnull AnnotatedBytes out, @Nonnull DexReader reader)129     public static void annotateEncodedAnnotation(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) {
130         assert out.getCursor() == reader.getOffset();
131 
132         int typeIndex = reader.readSmallUleb128();
133         out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(reader.dexBuf, typeIndex));
134 
135         int size = reader.readSmallUleb128();
136         out.annotateTo(reader.getOffset(), "size: %d", size);
137 
138         for (int i=0; i<size; i++) {
139             out.annotate(0, "element[%d]", i);
140             out.indent();
141 
142             int nameIndex = reader.readSmallUleb128();
143             out.annotateTo(reader.getOffset(), "name = %s",
144                     StringIdItem.getReferenceAnnotation(reader.dexBuf, nameIndex));
145 
146             annotateEncodedValue(out, reader);
147 
148             out.deindent();
149         }
150     }
151 
annotateEncodedArray(@onnull AnnotatedBytes out, @Nonnull DexReader reader)152     public static void annotateEncodedArray(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) {
153         assert out.getCursor() == reader.getOffset();
154 
155         int size = reader.readSmallUleb128();
156         out.annotateTo(reader.getOffset(), "size: %d", size);
157 
158         for (int i=0; i<size; i++) {
159             out.annotate(0, "element[%d]", i);
160             out.indent();
161 
162             annotateEncodedValue(out, reader);
163 
164             out.deindent();
165         }
166     }
167 }
168