1 /* 2 * Copyright 2012, 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; 33 34 import org.jf.util.ExceptionWithContext; 35 import org.jf.util.Utf8Utils; 36 37 import javax.annotation.Nonnull; 38 39 public class BaseDexReader<T extends BaseDexBuffer> { 40 @Nonnull public final T dexBuf; 41 private int offset; 42 43 public BaseDexReader(@Nonnull T dexBuf, int offset) { 44 this.dexBuf = dexBuf; 45 this.offset = offset; 46 } 47 48 public int getOffset() { return offset; } 49 public void setOffset(int offset) { this.offset = offset; } 50 51 /** {@inheritDoc} */ 52 public int readSleb128() { 53 int end = offset; 54 int currentByteValue; 55 int result; 56 byte[] buf = dexBuf.buf; 57 58 result = buf[end++] & 0xff; 59 if (result <= 0x7f) { 60 result = (result << 25) >> 25; 61 } else { 62 currentByteValue = buf[end++] & 0xff; 63 result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 64 if (currentByteValue <= 0x7f) { 65 result = (result << 18) >> 18; 66 } else { 67 currentByteValue = buf[end++] & 0xff; 68 result |= (currentByteValue & 0x7f) << 14; 69 if (currentByteValue <= 0x7f) { 70 result = (result << 11) >> 11; 71 } else { 72 currentByteValue = buf[end++] & 0xff; 73 result |= (currentByteValue & 0x7f) << 21; 74 if (currentByteValue <= 0x7f) { 75 result = (result << 4) >> 4; 76 } else { 77 currentByteValue = buf[end++] & 0xff; 78 if (currentByteValue > 0x7f) { 79 throw new ExceptionWithContext( 80 "Invalid sleb128 integer encountered at offset 0x%x", offset); 81 } 82 result |= currentByteValue << 28; 83 } 84 } 85 } 86 } 87 88 offset = end; 89 return result; 90 } 91 92 public int readSmallUleb128() { 93 return readUleb128(false); 94 } 95 96 private int readUleb128(boolean allowLarge) { 97 int end = offset; 98 int currentByteValue; 99 int result; 100 byte[] buf = dexBuf.buf; 101 102 result = buf[end++] & 0xff; 103 if (result > 0x7f) { 104 currentByteValue = buf[end++] & 0xff; 105 result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 106 if (currentByteValue > 0x7f) { 107 currentByteValue = buf[end++] & 0xff; 108 result |= (currentByteValue & 0x7f) << 14; 109 if (currentByteValue > 0x7f) { 110 currentByteValue = buf[end++] & 0xff; 111 result |= (currentByteValue & 0x7f) << 21; 112 if (currentByteValue > 0x7f) { 113 currentByteValue = buf[end++]; 114 115 // MSB shouldn't be set on last byte 116 if (currentByteValue < 0) { 117 throw new ExceptionWithContext( 118 "Invalid uleb128 integer encountered at offset 0x%x", offset); 119 } else if ((currentByteValue & 0xf) > 0x07) { 120 if (!allowLarge) { 121 // for non-large uleb128s, we assume most significant bit of the result will not be 122 // set, so that it can fit into a signed integer without wrapping 123 throw new ExceptionWithContext( 124 "Encountered valid uleb128 that is out of range at offset 0x%x", offset); 125 } 126 } 127 result |= currentByteValue << 28; 128 } 129 } 130 } 131 } 132 133 offset = end; 134 return result; 135 } 136 137 /** 138 * Reads a "large" uleb128. That is, one that may legitimately be greater than a signed int. 139 * 140 * The value is returned as if it were signed. i.e. a value of 0xFFFFFFFF would be returned as -1. It is up to the 141 * caller to handle the value appropriately. 142 */ 143 public int readLargeUleb128() { 144 return readUleb128(true); 145 } 146 147 /** 148 * Reads a "big" uleb128 that can legitimately be > 2^31. The value is returned as a signed integer, with the 149 * expected semantics of re-interpreting an unsigned value as a signed value. 150 * 151 * @return The unsigned value, reinterpreted as a signed int 152 */ 153 public int readBigUleb128() { 154 int end = offset; 155 int currentByteValue; 156 int result; 157 byte[] buf = dexBuf.buf; 158 159 result = buf[end++] & 0xff; 160 if (result > 0x7f) { 161 currentByteValue = buf[end++] & 0xff; 162 result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 163 if (currentByteValue > 0x7f) { 164 currentByteValue = buf[end++] & 0xff; 165 result |= (currentByteValue & 0x7f) << 14; 166 if (currentByteValue > 0x7f) { 167 currentByteValue = buf[end++] & 0xff; 168 result |= (currentByteValue & 0x7f) << 21; 169 if (currentByteValue > 0x7f) { 170 currentByteValue = buf[end++]; 171 172 // MSB shouldn't be set on last byte 173 if (currentByteValue < 0) { 174 throw new ExceptionWithContext( 175 "Invalid uleb128 integer encountered at offset 0x%x", offset); 176 } 177 result |= currentByteValue << 28; 178 } 179 } 180 } 181 } 182 183 offset = end; 184 return result; 185 } 186 187 public void skipUleb128() { 188 int end = offset; 189 byte currentByteValue; 190 byte[] buf = dexBuf.buf; 191 192 currentByteValue = buf[end++]; 193 if (currentByteValue < 0) { // if the MSB is set 194 currentByteValue = buf[end++]; 195 if (currentByteValue < 0) { // if the MSB is set 196 currentByteValue = buf[end++]; 197 if (currentByteValue < 0) { // if the MSB is set 198 currentByteValue = buf[end++]; 199 if (currentByteValue < 0) { // if the MSB is set 200 currentByteValue = buf[end++]; 201 if (currentByteValue < 0) { 202 throw new ExceptionWithContext( 203 "Invalid uleb128 integer encountered at offset 0x%x", offset); 204 } 205 } 206 } 207 } 208 } 209 210 offset = end; 211 } 212 213 public int readSmallUint() { 214 int o = offset; 215 int result = dexBuf.readSmallUint(o); 216 offset = o + 4; 217 return result; 218 } 219 220 public int readOptionalUint() { 221 int o = offset; 222 int result = dexBuf.readOptionalUint(o); 223 offset = o + 4; 224 return result; 225 } 226 227 public int peekUshort() { 228 return dexBuf.readUshort(offset); 229 } 230 231 public int readUshort() { 232 int o = offset; 233 int result = dexBuf.readUshort(offset); 234 offset = o + 2; 235 return result; 236 } 237 238 public int peekUbyte() { 239 return dexBuf.readUbyte(offset); 240 } 241 242 public int readUbyte() { 243 int o = offset; 244 int result = dexBuf.readUbyte(offset); 245 offset = o + 1; 246 return result; 247 } 248 249 public long readLong() { 250 int o = offset; 251 long result = dexBuf.readLong(offset); 252 offset = o + 8; 253 return result; 254 } 255 256 public int readInt() { 257 int o = offset; 258 int result = dexBuf.readInt(offset); 259 offset = o + 4; 260 return result; 261 } 262 263 public int readShort() { 264 int o = offset; 265 int result = dexBuf.readShort(offset); 266 offset = o + 2; 267 return result; 268 } 269 270 public int readByte() { 271 int o = offset; 272 int result = dexBuf.readByte(offset); 273 offset = o + 1; 274 return result; 275 } 276 277 public void skipByte() { offset++; } 278 public void moveRelative(int i) { offset += i; } 279 280 public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); } 281 public int readUshort(int offset) { return dexBuf.readUshort(offset); } 282 public int readUbyte(int offset) { return dexBuf.readUbyte(offset); } 283 public long readLong(int offset) { return dexBuf.readLong(offset); } 284 public int readInt(int offset) { return dexBuf.readInt(offset); } 285 public int readShort(int offset) { return dexBuf.readShort(offset); } 286 public int readByte(int offset) { return dexBuf.readByte(offset); } 287 288 public int readSizedInt(int bytes) { 289 int o = offset; 290 byte[] buf = dexBuf.buf; 291 292 int result; 293 switch (bytes) { 294 case 4: 295 result = (buf[o] & 0xff) | 296 ((buf[o+1] & 0xff) << 8) | 297 ((buf[o+2] & 0xff) << 16) | 298 (buf[o+3] << 24); 299 break; 300 case 3: 301 result = (buf[o] & 0xff) | 302 ((buf[o+1] & 0xff) << 8) | 303 ((buf[o+2]) << 16); 304 break; 305 case 2: 306 result = (buf[o] & 0xff) | 307 ((buf[o+1]) << 8); 308 break; 309 case 1: 310 result = buf[o]; 311 break; 312 default: 313 throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset); 314 } 315 offset = o + bytes; 316 return result; 317 } 318 319 public int readSizedSmallUint(int bytes) { 320 int o = offset; 321 byte[] buf = dexBuf.buf; 322 323 int result = 0; 324 switch (bytes) { 325 case 4: 326 int b = buf[o+3]; 327 if (b < 0) { 328 throw new ExceptionWithContext( 329 "Encountered valid sized uint that is out of range at offset 0x%x", offset); 330 } 331 result = b << 24; 332 // fall-through 333 case 3: 334 result |= (buf[o+2] & 0xff) << 16; 335 // fall-through 336 case 2: 337 result |= (buf[o+1] & 0xff) << 8; 338 // fall-through 339 case 1: 340 result |= (buf[o] & 0xff); 341 break; 342 default: 343 throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset); 344 } 345 offset = o + bytes; 346 return result; 347 } 348 349 public int readSizedRightExtendedInt(int bytes) { 350 int o = offset; 351 byte[] buf = dexBuf.buf; 352 353 int result; 354 switch (bytes) { 355 case 4: 356 result = (buf[o] & 0xff) | 357 ((buf[o+1] & 0xff) << 8) | 358 ((buf[o+2] & 0xff) << 16) | 359 (buf[o+3] << 24); 360 break; 361 case 3: 362 result = (buf[o] & 0xff) << 8 | 363 ((buf[o+1] & 0xff) << 16) | 364 (buf[o+2] << 24); 365 break; 366 case 2: 367 result = (buf[o] & 0xff) << 16 | 368 (buf[o+1] << 24); 369 break; 370 case 1: 371 result = buf[o] << 24; 372 break; 373 default: 374 throw new ExceptionWithContext( 375 "Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset); 376 } 377 offset = o + bytes; 378 return result; 379 } 380 381 public long readSizedRightExtendedLong(int bytes) { 382 int o = offset; 383 byte[] buf = dexBuf.buf; 384 385 long result; 386 switch (bytes) { 387 case 8: 388 result = (buf[o] & 0xff) | 389 ((buf[o+1] & 0xff) << 8) | 390 ((buf[o+2] & 0xff) << 16) | 391 ((buf[o+3] & 0xffL) << 24) | 392 ((buf[o+4] & 0xffL) << 32) | 393 ((buf[o+5] & 0xffL) << 40) | 394 ((buf[o+6] & 0xffL) << 48) | 395 (((long)buf[o+7]) << 56); 396 break; 397 case 7: 398 result = ((buf[o] & 0xff)) << 8 | 399 ((buf[o+1] & 0xff) << 16) | 400 ((buf[o+2] & 0xffL) << 24) | 401 ((buf[o+3] & 0xffL) << 32) | 402 ((buf[o+4] & 0xffL) << 40) | 403 ((buf[o+5] & 0xffL) << 48) | 404 (((long)buf[o+6]) << 56); 405 break; 406 case 6: 407 result = ((buf[o] & 0xff)) << 16 | 408 ((buf[o+1] & 0xffL) << 24) | 409 ((buf[o+2] & 0xffL) << 32) | 410 ((buf[o+3] & 0xffL) << 40) | 411 ((buf[o+4] & 0xffL) << 48) | 412 (((long)buf[o+5]) << 56); 413 break; 414 case 5: 415 result = ((buf[o] & 0xffL)) << 24 | 416 ((buf[o+1] & 0xffL) << 32) | 417 ((buf[o+2] & 0xffL) << 40) | 418 ((buf[o+3] & 0xffL) << 48) | 419 (((long)buf[o+4]) << 56); 420 break; 421 case 4: 422 result = ((buf[o] & 0xffL)) << 32 | 423 ((buf[o+1] & 0xffL) << 40) | 424 ((buf[o+2] & 0xffL) << 48) | 425 (((long)buf[o+3]) << 56); 426 break; 427 case 3: 428 result = ((buf[o] & 0xffL)) << 40 | 429 ((buf[o+1] & 0xffL) << 48) | 430 (((long)buf[o+2]) << 56); 431 break; 432 case 2: 433 result = ((buf[o] & 0xffL)) << 48 | 434 (((long)buf[o+1]) << 56); 435 break; 436 case 1: 437 result = ((long)buf[o]) << 56; 438 break; 439 default: 440 throw new ExceptionWithContext( 441 "Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset); 442 } 443 offset = o + bytes; 444 return result; 445 } 446 447 public long readSizedLong(int bytes) { 448 int o = offset; 449 byte[] buf = dexBuf.buf; 450 451 long result; 452 switch (bytes) { 453 case 8: 454 result = (buf[o] & 0xff) | 455 ((buf[o+1] & 0xff) << 8) | 456 ((buf[o+2] & 0xff) << 16) | 457 ((buf[o+3] & 0xffL) << 24) | 458 ((buf[o+4] & 0xffL) << 32) | 459 ((buf[o+5] & 0xffL) << 40) | 460 ((buf[o+6] & 0xffL) << 48) | 461 (((long)buf[o+7]) << 56); 462 break; 463 case 7: 464 result = (buf[o] & 0xff) | 465 ((buf[o+1] & 0xff) << 8) | 466 ((buf[o+2] & 0xff) << 16) | 467 ((buf[o+3] & 0xffL) << 24) | 468 ((buf[o+4] & 0xffL) << 32) | 469 ((buf[o+5] & 0xffL) << 40) | 470 ((long)(buf[o+6]) << 48); 471 break; 472 case 6: 473 result = (buf[o] & 0xff) | 474 ((buf[o+1] & 0xff) << 8) | 475 ((buf[o+2] & 0xff) << 16) | 476 ((buf[o+3] & 0xffL) << 24) | 477 ((buf[o+4] & 0xffL) << 32) | 478 ((long)(buf[o+5]) << 40); 479 break; 480 case 5: 481 result = (buf[o] & 0xff) | 482 ((buf[o+1] & 0xff) << 8) | 483 ((buf[o+2] & 0xff) << 16) | 484 ((buf[o+3] & 0xffL) << 24) | 485 ((long)(buf[o+4]) << 32); 486 break; 487 case 4: 488 result = (buf[o] & 0xff) | 489 ((buf[o+1] & 0xff) << 8) | 490 ((buf[o+2] & 0xff) << 16) | 491 (((long)buf[o+3]) << 24); 492 break; 493 case 3: 494 result = (buf[o] & 0xff) | 495 ((buf[o+1] & 0xff) << 8) | 496 (buf[o+2] << 16); 497 break; 498 case 2: 499 result = (buf[o] & 0xff) | 500 (buf[o+1] << 8); 501 break; 502 case 1: 503 result = buf[o]; 504 break; 505 default: 506 throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset); 507 } 508 509 offset = o + bytes; 510 return result; 511 } 512 513 public String readString(int utf16Length) { 514 int[] ret = new int[1]; 515 String value = Utf8Utils.utf8BytesWithUtf16LengthToString(dexBuf.buf, offset, utf16Length, ret); 516 offset += ret[0]; 517 return value; 518 } 519 } 520