mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 04:10:13 +02:00
Decouple BaseDexBuffer from DexBackedDexFile
Instead of having DexBackedDexFile extend BaseDexBuffer itself, it is now a separate class, and can be accessed via DexBackedDexFile.getBuffer()
This commit is contained in:
parent
8faa4b31ec
commit
f8e5be6afe
@ -1,623 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, Google Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following disclaimer
|
|
||||||
* in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* * Neither the name of Google Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
|
||||||
|
|
||||||
import org.jf.util.ExceptionWithContext;
|
|
||||||
import org.jf.util.Utf8Utils;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public class BaseDexReader<T extends BaseDexBuffer> {
|
|
||||||
@Nonnull public final T dexBuf;
|
|
||||||
private int offset;
|
|
||||||
|
|
||||||
public BaseDexReader(@Nonnull T dexBuf, int offset) {
|
|
||||||
this.dexBuf = dexBuf;
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOffset() { return offset; }
|
|
||||||
public void setOffset(int offset) { this.offset = offset; }
|
|
||||||
|
|
||||||
public int readSleb128() {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result <= 0x7f) {
|
|
||||||
result = (result << 25) >> 25;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
|
||||||
if (currentByteValue <= 0x7f) {
|
|
||||||
result = (result << 18) >> 18;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 14;
|
|
||||||
if (currentByteValue <= 0x7f) {
|
|
||||||
result = (result << 11) >> 11;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 21;
|
|
||||||
if (currentByteValue <= 0x7f) {
|
|
||||||
result = (result << 4) >> 4;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
result |= currentByteValue << 28;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekSleb128Size() {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return end - (dexBuf.baseOffset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSmallUleb128() {
|
|
||||||
return readUleb128(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekSmallUleb128Size() {
|
|
||||||
return peekUleb128Size(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int readUleb128(boolean allowLarge) {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 14;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 21;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
|
|
||||||
// MSB shouldn't be set on last byte
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
} else if ((currentByteValue & 0xf) > 0x07) {
|
|
||||||
if (!allowLarge) {
|
|
||||||
// for non-large uleb128s, we assume most significant bit of the result will not be
|
|
||||||
// set, so that it can fit into a signed integer without wrapping
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result |= currentByteValue << 28;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int peekUleb128Size(boolean allowLarge) {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
|
|
||||||
// MSB shouldn't be set on last byte
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
} else if ((currentByteValue & 0xf) > 0x07) {
|
|
||||||
if (!allowLarge) {
|
|
||||||
// for non-large uleb128s, we assume most significant bit of the result will not be
|
|
||||||
// set, so that it can fit into a signed integer without wrapping
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return end - (dexBuf.baseOffset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a "large" uleb128. That is, one that may legitimately be greater than a signed int.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* caller to handle the value appropriately.
|
|
||||||
*/
|
|
||||||
public int readLargeUleb128() {
|
|
||||||
return readUleb128(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a "big" uleb128 that can legitimately be > 2^31. The value is returned as a signed integer, with the
|
|
||||||
* expected semantics of re-interpreting an unsigned value as a signed value.
|
|
||||||
*
|
|
||||||
* @return The unsigned value, reinterpreted as a signed int
|
|
||||||
*/
|
|
||||||
public int readBigUleb128() {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 14;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 21;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
|
|
||||||
// MSB shouldn't be set on last byte
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
result |= currentByteValue << 28;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekBigUleb128Size() {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
|
|
||||||
// MSB shouldn't be set on last byte
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return end - (dexBuf.baseOffset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void skipUleb128() {
|
|
||||||
int end = dexBuf.baseOffset + offset;
|
|
||||||
byte currentByteValue;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end - dexBuf.baseOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSmallUint() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readSmallUint(o);
|
|
||||||
offset = o + 4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readOptionalUint() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readOptionalUint(o);
|
|
||||||
offset = o + 4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekUshort() {
|
|
||||||
return dexBuf.readUshort(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readUshort() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readUshort(offset);
|
|
||||||
offset = o + 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekUbyte() {
|
|
||||||
return dexBuf.readUbyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readUbyte() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readUbyte(offset);
|
|
||||||
offset = o + 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readLong() {
|
|
||||||
int o = offset;
|
|
||||||
long result = dexBuf.readLong(offset);
|
|
||||||
offset = o + 8;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readInt() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readInt(offset);
|
|
||||||
offset = o + 4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readShort() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readShort(offset);
|
|
||||||
offset = o + 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readByte() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readByte(offset);
|
|
||||||
offset = o + 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void skipByte() { offset++; }
|
|
||||||
public void moveRelative(int i) { offset += i; }
|
|
||||||
|
|
||||||
public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
|
|
||||||
public int readUshort(int offset) { return dexBuf.readUshort(offset); }
|
|
||||||
public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
|
|
||||||
public long readLong(int offset) { return dexBuf.readLong(offset); }
|
|
||||||
public int readInt(int offset) { return dexBuf.readInt(offset); }
|
|
||||||
public int readShort(int offset) { return dexBuf.readShort(offset); }
|
|
||||||
public int readByte(int offset) { return dexBuf.readByte(offset); }
|
|
||||||
|
|
||||||
public int readSizedInt(int bytes) {
|
|
||||||
int o = dexBuf.baseOffset + offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
int result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 4:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
(buf[o+3] << 24);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2]) << 16);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1]) << 8);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = buf[o];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSizedSmallUint(int bytes) {
|
|
||||||
int o = dexBuf.baseOffset + offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
int result = 0;
|
|
||||||
switch (bytes) {
|
|
||||||
case 4:
|
|
||||||
int b = buf[o+3];
|
|
||||||
if (b < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Encountered valid sized uint that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
result = b << 24;
|
|
||||||
// fall-through
|
|
||||||
case 3:
|
|
||||||
result |= (buf[o+2] & 0xff) << 16;
|
|
||||||
// fall-through
|
|
||||||
case 2:
|
|
||||||
result |= (buf[o+1] & 0xff) << 8;
|
|
||||||
// fall-through
|
|
||||||
case 1:
|
|
||||||
result |= (buf[o] & 0xff);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSizedRightExtendedInt(int bytes) {
|
|
||||||
int o = dexBuf.baseOffset + offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
int result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 4:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
(buf[o+3] << 24);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = (buf[o] & 0xff) << 8 |
|
|
||||||
((buf[o+1] & 0xff) << 16) |
|
|
||||||
(buf[o+2] << 24);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = (buf[o] & 0xff) << 16 |
|
|
||||||
(buf[o+1] << 24);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = buf[o] << 24;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readSizedRightExtendedLong(int bytes) {
|
|
||||||
int o = dexBuf.baseOffset + offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
long result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 8:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((buf[o+5] & 0xffL) << 40) |
|
|
||||||
((buf[o+6] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+7]) << 56);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result = ((buf[o] & 0xff)) << 8 |
|
|
||||||
((buf[o+1] & 0xff) << 16) |
|
|
||||||
((buf[o+2] & 0xffL) << 24) |
|
|
||||||
((buf[o+3] & 0xffL) << 32) |
|
|
||||||
((buf[o+4] & 0xffL) << 40) |
|
|
||||||
((buf[o+5] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+6]) << 56);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
result = ((buf[o] & 0xff)) << 16 |
|
|
||||||
((buf[o+1] & 0xffL) << 24) |
|
|
||||||
((buf[o+2] & 0xffL) << 32) |
|
|
||||||
((buf[o+3] & 0xffL) << 40) |
|
|
||||||
((buf[o+4] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+5]) << 56);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result = ((buf[o] & 0xffL)) << 24 |
|
|
||||||
((buf[o+1] & 0xffL) << 32) |
|
|
||||||
((buf[o+2] & 0xffL) << 40) |
|
|
||||||
((buf[o+3] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+4]) << 56);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
result = ((buf[o] & 0xffL)) << 32 |
|
|
||||||
((buf[o+1] & 0xffL) << 40) |
|
|
||||||
((buf[o+2] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+3]) << 56);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = ((buf[o] & 0xffL)) << 40 |
|
|
||||||
((buf[o+1] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+2]) << 56);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = ((buf[o] & 0xffL)) << 48 |
|
|
||||||
(((long)buf[o+1]) << 56);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = ((long)buf[o]) << 56;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readSizedLong(int bytes) {
|
|
||||||
int o = dexBuf.baseOffset + offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
long result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 8:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((buf[o+5] & 0xffL) << 40) |
|
|
||||||
((buf[o+6] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+7]) << 56);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((buf[o+5] & 0xffL) << 40) |
|
|
||||||
((long)(buf[o+6]) << 48);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((long)(buf[o+5]) << 40);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((long)(buf[o+4]) << 32);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
(((long)buf[o+3]) << 24);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
(buf[o+2] << 16);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
(buf[o+1] << 8);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = buf[o];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = o + bytes - dexBuf.baseOffset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String readString(int utf16Length) {
|
|
||||||
int[] ret = new int[1];
|
|
||||||
String value = Utf8Utils.utf8BytesWithUtf16LengthToString(
|
|
||||||
dexBuf.buf, dexBuf.baseOffset + offset, utf16Length, ret);
|
|
||||||
offset += ret[0];
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekStringLength(int utf16Length) {
|
|
||||||
int[] ret = new int[1];
|
|
||||||
Utf8Utils.utf8BytesWithUtf16LengthToString(
|
|
||||||
dexBuf.buf, dexBuf.baseOffset + offset, utf16Length, ret);
|
|
||||||
return ret[0];
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,7 +48,7 @@ public class DexBackedAnnotation extends BaseAnnotation {
|
|||||||
int annotationOffset) {
|
int annotationOffset) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
|
|
||||||
DexReader reader = dexFile.readerAt(annotationOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(annotationOffset);
|
||||||
this.visibility = reader.readUbyte();
|
this.visibility = reader.readUbyte();
|
||||||
this.typeIndex = reader.readSmallUleb128();
|
this.typeIndex = reader.readSmallUleb128();
|
||||||
this.elementsOffset = reader.getOffset();
|
this.elementsOffset = reader.getOffset();
|
||||||
@ -60,14 +60,14 @@ public class DexBackedAnnotation extends BaseAnnotation {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends DexBackedAnnotationElement> getElements() {
|
public Set<? extends DexBackedAnnotationElement> getElements() {
|
||||||
DexReader reader = dexFile.readerAt(elementsOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(elementsOffset);
|
||||||
final int size = reader.readSmallUleb128();
|
final int size = reader.readSmallUleb128();
|
||||||
|
|
||||||
return new VariableSizeSet<DexBackedAnnotationElement>(dexFile, reader.getOffset(), size) {
|
return new VariableSizeSet<DexBackedAnnotationElement>(dexFile, reader.getOffset(), size) {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader reader, int index) {
|
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader reader, int index) {
|
||||||
return new DexBackedAnnotationElement(reader);
|
return new DexBackedAnnotationElement(dexFile, reader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ public class DexBackedAnnotationElement extends BaseAnnotationElement {
|
|||||||
public final int nameIndex;
|
public final int nameIndex;
|
||||||
@Nonnull public final EncodedValue value;
|
@Nonnull public final EncodedValue value;
|
||||||
|
|
||||||
public DexBackedAnnotationElement(@Nonnull DexReader reader) {
|
public DexBackedAnnotationElement(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.nameIndex = reader.readSmallUleb128();
|
this.nameIndex = reader.readSmallUleb128();
|
||||||
this.value = DexBackedEncodedValue.readFrom(reader);
|
this.value = DexBackedEncodedValue.readFrom(dexFile, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getName() { return dexFile.getStringSection().get(nameIndex); }
|
@Nonnull @Override public String getName() { return dexFile.getStringSection().get(nameIndex); }
|
||||||
|
@ -74,7 +74,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
this.classDefOffset = classDefOffset;
|
this.classDefOffset = classDefOffset;
|
||||||
|
|
||||||
int classDataOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET);
|
int classDataOffset = dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET);
|
||||||
if (classDataOffset == 0) {
|
if (classDataOffset == 0) {
|
||||||
staticFieldsOffset = -1;
|
staticFieldsOffset = -1;
|
||||||
staticFieldCount = 0;
|
staticFieldCount = 0;
|
||||||
@ -82,7 +82,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
directMethodCount = 0;
|
directMethodCount = 0;
|
||||||
virtualMethodCount = 0;
|
virtualMethodCount = 0;
|
||||||
} else {
|
} else {
|
||||||
DexReader reader = dexFile.readerAt(classDataOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(classDataOffset);
|
||||||
staticFieldCount = reader.readSmallUleb128();
|
staticFieldCount = reader.readSmallUleb128();
|
||||||
instanceFieldCount = reader.readSmallUleb128();
|
instanceFieldCount = reader.readSmallUleb128();
|
||||||
directMethodCount = reader.readSmallUleb128();
|
directMethodCount = reader.readSmallUleb128();
|
||||||
@ -95,38 +95,41 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return dexFile.getTypeSection().get(dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_OFFSET));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.CLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getSuperclass() {
|
public String getSuperclass() {
|
||||||
return dexFile.getTypeSection().getOptional(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SUPERCLASS_OFFSET));
|
return dexFile.getTypeSection().getOptional(
|
||||||
|
dexFile.getBuffer().readOptionalUint(classDefOffset + ClassDefItem.SUPERCLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAccessFlags() {
|
public int getAccessFlags() {
|
||||||
return dexFile.readSmallUint(classDefOffset + ClassDefItem.ACCESS_FLAGS_OFFSET);
|
return dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.ACCESS_FLAGS_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getSourceFile() {
|
public String getSourceFile() {
|
||||||
return dexFile.getStringSection().getOptional(
|
return dexFile.getStringSection().getOptional(
|
||||||
dexFile.readOptionalUint(classDefOffset + ClassDefItem.SOURCE_FILE_OFFSET));
|
dexFile.getBuffer().readOptionalUint(classDefOffset + ClassDefItem.SOURCE_FILE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<String> getInterfaces() {
|
public List<String> getInterfaces() {
|
||||||
final int interfacesOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.INTERFACES_OFFSET);
|
final int interfacesOffset = dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.INTERFACES_OFFSET);
|
||||||
if (interfacesOffset > 0) {
|
if (interfacesOffset > 0) {
|
||||||
final int size = dexFile.readSmallUint(interfacesOffset);
|
final int size = dexFile.getBuffer().readSmallUint(interfacesOffset);
|
||||||
return new AbstractList<String>() {
|
return new AbstractList<String>() {
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String get(int index) {
|
public String get(int index) {
|
||||||
return dexFile.getTypeSection().get(dexFile.readUshort(interfacesOffset + 4 + (2*index)));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.getBuffer().readUshort(interfacesOffset + 4 + (2*index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int size() { return size; }
|
@Override public int size() { return size; }
|
||||||
@ -150,11 +153,11 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public Iterable<? extends DexBackedField> getStaticFields(final boolean skipDuplicates) {
|
public Iterable<? extends DexBackedField> getStaticFields(final boolean skipDuplicates) {
|
||||||
if (staticFieldCount > 0) {
|
if (staticFieldCount > 0) {
|
||||||
DexReader reader = dexFile.readerAt(staticFieldsOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(staticFieldsOffset);
|
||||||
|
|
||||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||||
final int staticInitialValuesOffset =
|
final int staticInitialValuesOffset =
|
||||||
dexFile.readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
|
dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
|
||||||
final int fieldsStartOffset = reader.getOffset();
|
final int fieldsStartOffset = reader.getOffset();
|
||||||
|
|
||||||
return new Iterable<DexBackedField>() {
|
return new Iterable<DexBackedField>() {
|
||||||
@ -180,7 +183,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
return endOfData();
|
return endOfData();
|
||||||
}
|
}
|
||||||
|
|
||||||
DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this,
|
DexBackedField item = new DexBackedField(dexFile, reader, DexBackedClassDef.this,
|
||||||
previousIndex, staticInitialValueIterator, annotationIterator);
|
previousIndex, staticInitialValueIterator, annotationIterator);
|
||||||
FieldReference currentField = previousField;
|
FieldReference currentField = previousField;
|
||||||
FieldReference nextField = ImmutableFieldReference.of(item);
|
FieldReference nextField = ImmutableFieldReference.of(item);
|
||||||
@ -213,7 +216,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public Iterable<? extends DexBackedField> getInstanceFields(final boolean skipDuplicates) {
|
public Iterable<? extends DexBackedField> getInstanceFields(final boolean skipDuplicates) {
|
||||||
if (instanceFieldCount > 0) {
|
if (instanceFieldCount > 0) {
|
||||||
DexReader reader = dexFile.readerAt(getInstanceFieldsOffset());
|
DexReader reader = dexFile.getBuffer().readerAt(getInstanceFieldsOffset());
|
||||||
|
|
||||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||||
final int fieldsStartOffset = reader.getOffset();
|
final int fieldsStartOffset = reader.getOffset();
|
||||||
@ -239,7 +242,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
return endOfData();
|
return endOfData();
|
||||||
}
|
}
|
||||||
|
|
||||||
DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this,
|
DexBackedField item = new DexBackedField(dexFile, reader, DexBackedClassDef.this,
|
||||||
previousIndex, annotationIterator);
|
previousIndex, annotationIterator);
|
||||||
FieldReference currentField = previousField;
|
FieldReference currentField = previousField;
|
||||||
FieldReference nextField = ImmutableFieldReference.of(item);
|
FieldReference nextField = ImmutableFieldReference.of(item);
|
||||||
@ -280,7 +283,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public Iterable<? extends DexBackedMethod> getDirectMethods(final boolean skipDuplicates) {
|
public Iterable<? extends DexBackedMethod> getDirectMethods(final boolean skipDuplicates) {
|
||||||
if (directMethodCount > 0) {
|
if (directMethodCount > 0) {
|
||||||
DexReader reader = dexFile.readerAt(getDirectMethodsOffset());
|
DexReader reader = dexFile.getBuffer().readerAt(getDirectMethodsOffset());
|
||||||
|
|
||||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||||
final int methodsStartOffset = reader.getOffset();
|
final int methodsStartOffset = reader.getOffset();
|
||||||
@ -308,7 +311,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
return endOfData();
|
return endOfData();
|
||||||
}
|
}
|
||||||
|
|
||||||
DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this,
|
DexBackedMethod item = new DexBackedMethod(dexFile, reader, DexBackedClassDef.this,
|
||||||
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
|
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
|
||||||
MethodReference currentMethod = previousMethod;
|
MethodReference currentMethod = previousMethod;
|
||||||
MethodReference nextMethod = ImmutableMethodReference.of(item);
|
MethodReference nextMethod = ImmutableMethodReference.of(item);
|
||||||
@ -337,7 +340,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public Iterable<? extends DexBackedMethod> getVirtualMethods(final boolean skipDuplicates) {
|
public Iterable<? extends DexBackedMethod> getVirtualMethods(final boolean skipDuplicates) {
|
||||||
if (virtualMethodCount > 0) {
|
if (virtualMethodCount > 0) {
|
||||||
DexReader reader = dexFile.readerAt(getVirtualMethodsOffset());
|
DexReader reader = dexFile.getBuffer().readerAt(getVirtualMethodsOffset());
|
||||||
|
|
||||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||||
final int methodsStartOffset = reader.getOffset();
|
final int methodsStartOffset = reader.getOffset();
|
||||||
@ -364,7 +367,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
return endOfData();
|
return endOfData();
|
||||||
}
|
}
|
||||||
|
|
||||||
DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this,
|
DexBackedMethod item = new DexBackedMethod(dexFile, reader, DexBackedClassDef.this,
|
||||||
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
|
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
|
||||||
MethodReference currentMethod = previousMethod;
|
MethodReference currentMethod = previousMethod;
|
||||||
MethodReference nextMethod = ImmutableMethodReference.of(item);
|
MethodReference nextMethod = ImmutableMethodReference.of(item);
|
||||||
@ -400,7 +403,8 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
|
|
||||||
private AnnotationsDirectory getAnnotationsDirectory() {
|
private AnnotationsDirectory getAnnotationsDirectory() {
|
||||||
if (annotationsDirectory == null) {
|
if (annotationsDirectory == null) {
|
||||||
int annotationsDirectoryOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.ANNOTATIONS_OFFSET);
|
int annotationsDirectoryOffset =
|
||||||
|
dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.ANNOTATIONS_OFFSET);
|
||||||
annotationsDirectory = AnnotationsDirectory.newOrEmpty(dexFile, annotationsDirectoryOffset);
|
annotationsDirectory = AnnotationsDirectory.newOrEmpty(dexFile, annotationsDirectoryOffset);
|
||||||
}
|
}
|
||||||
return annotationsDirectory;
|
return annotationsDirectory;
|
||||||
@ -410,7 +414,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
if (instanceFieldsOffset > 0) {
|
if (instanceFieldsOffset > 0) {
|
||||||
return instanceFieldsOffset;
|
return instanceFieldsOffset;
|
||||||
}
|
}
|
||||||
DexReader reader = new DexReader(dexFile, staticFieldsOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(staticFieldsOffset);
|
||||||
DexBackedField.skipFields(reader, staticFieldCount);
|
DexBackedField.skipFields(reader, staticFieldCount);
|
||||||
instanceFieldsOffset = reader.getOffset();
|
instanceFieldsOffset = reader.getOffset();
|
||||||
return instanceFieldsOffset;
|
return instanceFieldsOffset;
|
||||||
@ -420,7 +424,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
if (directMethodsOffset > 0) {
|
if (directMethodsOffset > 0) {
|
||||||
return directMethodsOffset;
|
return directMethodsOffset;
|
||||||
}
|
}
|
||||||
DexReader reader = dexFile.readerAt(getInstanceFieldsOffset());
|
DexReader reader = dexFile.getBuffer().readerAt(getInstanceFieldsOffset());
|
||||||
DexBackedField.skipFields(reader, instanceFieldCount);
|
DexBackedField.skipFields(reader, instanceFieldCount);
|
||||||
directMethodsOffset = reader.getOffset();
|
directMethodsOffset = reader.getOffset();
|
||||||
return directMethodsOffset;
|
return directMethodsOffset;
|
||||||
@ -430,7 +434,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
if (virtualMethodsOffset > 0) {
|
if (virtualMethodsOffset > 0) {
|
||||||
return virtualMethodsOffset;
|
return virtualMethodsOffset;
|
||||||
}
|
}
|
||||||
DexReader reader = dexFile.readerAt(getDirectMethodsOffset());
|
DexReader reader = dexFile.getBuffer().readerAt(getDirectMethodsOffset());
|
||||||
DexBackedMethod.skipMethods(reader, directMethodCount);
|
DexBackedMethod.skipMethods(reader, directMethodCount);
|
||||||
virtualMethodsOffset = reader.getOffset();
|
virtualMethodsOffset = reader.getOffset();
|
||||||
return virtualMethodsOffset;
|
return virtualMethodsOffset;
|
||||||
@ -471,16 +475,16 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
|
|
||||||
//static values and/or metadata
|
//static values and/or metadata
|
||||||
int staticInitialValuesOffset =
|
int staticInitialValuesOffset =
|
||||||
dexFile.readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
|
dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
|
||||||
if (staticInitialValuesOffset != 0) {
|
if (staticInitialValuesOffset != 0) {
|
||||||
DexReader reader = dexFile.readerAt(staticInitialValuesOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(staticInitialValuesOffset);
|
||||||
size += reader.peekSmallUleb128Size(); //encoded_array size field
|
size += reader.peekSmallUleb128Size(); //encoded_array size field
|
||||||
}
|
}
|
||||||
|
|
||||||
//class_data_item
|
//class_data_item
|
||||||
int classDataOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET);
|
int classDataOffset = dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET);
|
||||||
if (classDataOffset > 0) {
|
if (classDataOffset > 0) {
|
||||||
DexReader reader = dexFile.readerAt(classDataOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(classDataOffset);
|
||||||
reader.readSmallUleb128(); //staticFieldCount
|
reader.readSmallUleb128(); //staticFieldCount
|
||||||
reader.readSmallUleb128(); //instanceFieldCount
|
reader.readSmallUleb128(); //instanceFieldCount
|
||||||
reader.readSmallUleb128(); //directMethodCount
|
reader.readSmallUleb128(); //directMethodCount
|
||||||
|
@ -50,7 +50,10 @@ import java.util.AbstractList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
public class DexBackedDexFile implements DexFile {
|
||||||
|
|
||||||
|
private final DexBuffer dexBuffer;
|
||||||
|
|
||||||
@Nonnull private final Opcodes opcodes;
|
@Nonnull private final Opcodes opcodes;
|
||||||
|
|
||||||
private final int stringCount;
|
private final int stringCount;
|
||||||
@ -68,7 +71,7 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
private final int mapOffset;
|
private final int mapOffset;
|
||||||
|
|
||||||
protected DexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) {
|
protected DexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) {
|
||||||
super(buf, offset);
|
dexBuffer = new DexBuffer(buf, offset);
|
||||||
|
|
||||||
int dexVersion;
|
int dexVersion;
|
||||||
if (verifyMagic) {
|
if (verifyMagic) {
|
||||||
@ -83,22 +86,26 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
this.opcodes = opcodes;
|
this.opcodes = opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
stringCount = readSmallUint(HeaderItem.STRING_COUNT_OFFSET);
|
stringCount = dexBuffer.readSmallUint(HeaderItem.STRING_COUNT_OFFSET);
|
||||||
stringStartOffset = readSmallUint(HeaderItem.STRING_START_OFFSET);
|
stringStartOffset = dexBuffer.readSmallUint(HeaderItem.STRING_START_OFFSET);
|
||||||
typeCount = readSmallUint(HeaderItem.TYPE_COUNT_OFFSET);
|
typeCount = dexBuffer.readSmallUint(HeaderItem.TYPE_COUNT_OFFSET);
|
||||||
typeStartOffset = readSmallUint(HeaderItem.TYPE_START_OFFSET);
|
typeStartOffset = dexBuffer.readSmallUint(HeaderItem.TYPE_START_OFFSET);
|
||||||
protoCount = readSmallUint(HeaderItem.PROTO_COUNT_OFFSET);
|
protoCount = dexBuffer.readSmallUint(HeaderItem.PROTO_COUNT_OFFSET);
|
||||||
protoStartOffset = readSmallUint(HeaderItem.PROTO_START_OFFSET);
|
protoStartOffset = dexBuffer.readSmallUint(HeaderItem.PROTO_START_OFFSET);
|
||||||
fieldCount = readSmallUint(HeaderItem.FIELD_COUNT_OFFSET);
|
fieldCount = dexBuffer.readSmallUint(HeaderItem.FIELD_COUNT_OFFSET);
|
||||||
fieldStartOffset = readSmallUint(HeaderItem.FIELD_START_OFFSET);
|
fieldStartOffset = dexBuffer.readSmallUint(HeaderItem.FIELD_START_OFFSET);
|
||||||
methodCount = readSmallUint(HeaderItem.METHOD_COUNT_OFFSET);
|
methodCount = dexBuffer.readSmallUint(HeaderItem.METHOD_COUNT_OFFSET);
|
||||||
methodStartOffset = readSmallUint(HeaderItem.METHOD_START_OFFSET);
|
methodStartOffset = dexBuffer.readSmallUint(HeaderItem.METHOD_START_OFFSET);
|
||||||
classCount = readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
|
classCount = dexBuffer.readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
|
||||||
classStartOffset = readSmallUint(HeaderItem.CLASS_START_OFFSET);
|
classStartOffset = dexBuffer.readSmallUint(HeaderItem.CLASS_START_OFFSET);
|
||||||
mapOffset = readSmallUint(HeaderItem.MAP_OFFSET);
|
mapOffset = dexBuffer.readSmallUint(HeaderItem.MAP_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull BaseDexBuffer buf) {
|
public DexBuffer getBuffer() {
|
||||||
|
return dexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull DexBuffer buf) {
|
||||||
this(opcodes, buf.buf, buf.baseOffset);
|
this(opcodes, buf.buf, buf.baseOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,14 +195,8 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public DexReader readerAt(int offset) {
|
|
||||||
return new DexReader(this, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MapItem> getMapItems() {
|
public List<MapItem> getMapItems() {
|
||||||
final int mapSize = readSmallUint(mapOffset);
|
final int mapSize = dexBuffer.readSmallUint(mapOffset);
|
||||||
|
|
||||||
return new FixedSizeList<MapItem>() {
|
return new FixedSizeList<MapItem>() {
|
||||||
@Override
|
@Override
|
||||||
@ -241,8 +242,8 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
@Override
|
@Override
|
||||||
public String get(int index) {
|
public String get(int index) {
|
||||||
int stringOffset = getOffset(index);
|
int stringOffset = getOffset(index);
|
||||||
int stringDataOffset = readSmallUint(stringOffset);
|
int stringDataOffset = dexBuffer.readSmallUint(stringOffset);
|
||||||
DexReader reader = readerAt(stringDataOffset);
|
DexReader reader = dexBuffer.readerAt(stringDataOffset);
|
||||||
int utf16Length = reader.readSmallUleb128();
|
int utf16Length = reader.readSmallUleb128();
|
||||||
return reader.readString(utf16Length);
|
return reader.readString(utf16Length);
|
||||||
}
|
}
|
||||||
@ -279,7 +280,7 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
@Override
|
@Override
|
||||||
public String get(int index) {
|
public String get(int index) {
|
||||||
int typeOffset = getOffset(index);
|
int typeOffset = getOffset(index);
|
||||||
int stringIndex = readSmallUint(typeOffset);
|
int stringIndex = dexBuffer.readSmallUint(typeOffset);
|
||||||
return getStringSection().get(stringIndex);
|
return getStringSection().get(stringIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,12 +59,13 @@ public class DexBackedField extends BaseFieldReference implements Field {
|
|||||||
|
|
||||||
private int fieldIdItemOffset;
|
private int fieldIdItemOffset;
|
||||||
|
|
||||||
public DexBackedField(@Nonnull DexReader reader,
|
public DexBackedField(@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull DexReader reader,
|
||||||
@Nonnull DexBackedClassDef classDef,
|
@Nonnull DexBackedClassDef classDef,
|
||||||
int previousFieldIndex,
|
int previousFieldIndex,
|
||||||
@Nonnull EncodedArrayItemIterator staticInitialValueIterator,
|
@Nonnull EncodedArrayItemIterator staticInitialValueIterator,
|
||||||
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
|
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.classDef = classDef;
|
this.classDef = classDef;
|
||||||
|
|
||||||
// large values may be used for the index delta, which cause the cumulative index to overflow upon
|
// large values may be used for the index delta, which cause the cumulative index to overflow upon
|
||||||
@ -79,11 +80,12 @@ public class DexBackedField extends BaseFieldReference implements Field {
|
|||||||
this.initialValue = staticInitialValueIterator.getNextOrNull();
|
this.initialValue = staticInitialValueIterator.getNextOrNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DexBackedField(@Nonnull DexReader reader,
|
public DexBackedField(@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull DexReader reader,
|
||||||
@Nonnull DexBackedClassDef classDef,
|
@Nonnull DexBackedClassDef classDef,
|
||||||
int previousFieldIndex,
|
int previousFieldIndex,
|
||||||
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
|
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.classDef = classDef;
|
this.classDef = classDef;
|
||||||
|
|
||||||
// large values may be used for the index delta, which cause the cumulative index to overflow upon
|
// large values may be used for the index delta, which cause the cumulative index to overflow upon
|
||||||
@ -101,13 +103,15 @@ public class DexBackedField extends BaseFieldReference implements Field {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getStringSection().get(dexFile.readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
|
return dexFile.getStringSection().get(
|
||||||
|
dexFile.getBuffer().readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return dexFile.getTypeSection().get(dexFile.readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.getBuffer().readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
|
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
|
||||||
@ -150,7 +154,7 @@ public class DexBackedField extends BaseFieldReference implements Field {
|
|||||||
*/
|
*/
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
DexReader reader = dexFile.readerAt(startOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(startOffset);
|
||||||
reader.readLargeUleb128(); //field_idx_diff
|
reader.readLargeUleb128(); //field_idx_diff
|
||||||
reader.readSmallUleb128(); //access_flags
|
reader.readSmallUleb128(); //access_flags
|
||||||
size += reader.getOffset() - startOffset;
|
size += reader.getOffset() - startOffset;
|
||||||
|
@ -69,10 +69,11 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
private int protoIdItemOffset;
|
private int protoIdItemOffset;
|
||||||
private int parametersOffset = -1;
|
private int parametersOffset = -1;
|
||||||
|
|
||||||
public DexBackedMethod(@Nonnull DexReader reader,
|
public DexBackedMethod(@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull DexReader reader,
|
||||||
@Nonnull DexBackedClassDef classDef,
|
@Nonnull DexBackedClassDef classDef,
|
||||||
int previousMethodIndex) {
|
int previousMethodIndex) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.classDef = classDef;
|
this.classDef = classDef;
|
||||||
startOffset = reader.getOffset();
|
startOffset = reader.getOffset();
|
||||||
|
|
||||||
@ -87,12 +88,13 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
this.parameterAnnotationSetListOffset = 0;
|
this.parameterAnnotationSetListOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DexBackedMethod(@Nonnull DexReader reader,
|
public DexBackedMethod(@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull DexReader reader,
|
||||||
@Nonnull DexBackedClassDef classDef,
|
@Nonnull DexBackedClassDef classDef,
|
||||||
int previousMethodIndex,
|
int previousMethodIndex,
|
||||||
@Nonnull AnnotationsDirectory.AnnotationIterator methodAnnotationIterator,
|
@Nonnull AnnotationsDirectory.AnnotationIterator methodAnnotationIterator,
|
||||||
@Nonnull AnnotationsDirectory.AnnotationIterator paramaterAnnotationIterator) {
|
@Nonnull AnnotationsDirectory.AnnotationIterator paramaterAnnotationIterator) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.classDef = classDef;
|
this.classDef = classDef;
|
||||||
startOffset = reader.getOffset();
|
startOffset = reader.getOffset();
|
||||||
|
|
||||||
@ -114,14 +116,15 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getStringSection().get(dexFile.readSmallUint(getMethodIdItemOffset() + MethodIdItem.NAME_OFFSET));
|
return dexFile.getStringSection().get(
|
||||||
|
dexFile.getBuffer().readSmallUint(getMethodIdItemOffset() + MethodIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getReturnType() {
|
public String getReturnType() {
|
||||||
return dexFile.getTypeSection().get(
|
return dexFile.getTypeSection().get(
|
||||||
dexFile.readSmallUint(getProtoIdItemOffset() + ProtoIdItem.RETURN_TYPE_OFFSET));
|
dexFile.getBuffer().readSmallUint(getProtoIdItemOffset() + ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -165,13 +168,13 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
public List<String> getParameterTypes() {
|
public List<String> getParameterTypes() {
|
||||||
final int parametersOffset = getParametersOffset();
|
final int parametersOffset = getParametersOffset();
|
||||||
if (parametersOffset > 0) {
|
if (parametersOffset > 0) {
|
||||||
final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
final int parameterCount = dexFile.getBuffer().readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
||||||
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
||||||
return new FixedSizeList<String>() {
|
return new FixedSizeList<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String readItem(final int index) {
|
public String readItem(final int index) {
|
||||||
return dexFile.getTypeSection().get(dexFile.readUshort(paramListStart + 2*index));
|
return dexFile.getTypeSection().get(dexFile.getBuffer().readUshort(paramListStart + 2*index));
|
||||||
}
|
}
|
||||||
@Override public int size() { return parameterCount; }
|
@Override public int size() { return parameterCount; }
|
||||||
};
|
};
|
||||||
@ -203,7 +206,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
|
|
||||||
private int getProtoIdItemOffset() {
|
private int getProtoIdItemOffset() {
|
||||||
if (protoIdItemOffset == 0) {
|
if (protoIdItemOffset == 0) {
|
||||||
int protoIndex = dexFile.readUshort(getMethodIdItemOffset() + MethodIdItem.PROTO_OFFSET);
|
int protoIndex = dexFile.getBuffer().readUshort(getMethodIdItemOffset() + MethodIdItem.PROTO_OFFSET);
|
||||||
protoIdItemOffset = dexFile.getProtoSection().getOffset(protoIndex);
|
protoIdItemOffset = dexFile.getProtoSection().getOffset(protoIndex);
|
||||||
}
|
}
|
||||||
return protoIdItemOffset;
|
return protoIdItemOffset;
|
||||||
@ -211,7 +214,8 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
|
|
||||||
private int getParametersOffset() {
|
private int getParametersOffset() {
|
||||||
if (parametersOffset == -1) {
|
if (parametersOffset == -1) {
|
||||||
parametersOffset = dexFile.readSmallUint(getProtoIdItemOffset() + ProtoIdItem.PARAMETERS_OFFSET);
|
parametersOffset = dexFile.getBuffer().readSmallUint(
|
||||||
|
getProtoIdItemOffset() + ProtoIdItem.PARAMETERS_OFFSET);
|
||||||
}
|
}
|
||||||
return parametersOffset;
|
return parametersOffset;
|
||||||
}
|
}
|
||||||
@ -241,7 +245,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
DexReader reader = dexFile.readerAt(startOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(startOffset);
|
||||||
reader.readLargeUleb128(); //method_idx_diff
|
reader.readLargeUleb128(); //method_idx_diff
|
||||||
reader.readSmallUleb128(); //access_flags
|
reader.readSmallUleb128(); //access_flags
|
||||||
reader.readSmallUleb128(); //code_off
|
reader.readSmallUleb128(); //code_off
|
||||||
|
@ -62,11 +62,11 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
this.codeOffset = codeOffset;
|
this.codeOffset = codeOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() { return dexFile.readUshort(codeOffset); }
|
@Override public int getRegisterCount() { return dexFile.getBuffer().readUshort(codeOffset); }
|
||||||
|
|
||||||
@Nonnull @Override public Iterable<? extends Instruction> getInstructions() {
|
@Nonnull @Override public Iterable<? extends Instruction> getInstructions() {
|
||||||
// instructionsSize is the number of 16-bit code units in the instruction list, not the number of instructions
|
// instructionsSize is the number of 16-bit code units in the instruction list, not the number of instructions
|
||||||
int instructionsSize = dexFile.readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET);
|
int instructionsSize = dexFile.getBuffer().readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET);
|
||||||
|
|
||||||
final int instructionsStartOffset = codeOffset + CodeItem.INSTRUCTION_START_OFFSET;
|
final int instructionsStartOffset = codeOffset + CodeItem.INSTRUCTION_START_OFFSET;
|
||||||
final int endOffset = instructionsStartOffset + (instructionsSize*2);
|
final int endOffset = instructionsStartOffset + (instructionsSize*2);
|
||||||
@ -80,7 +80,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
return endOfData();
|
return endOfData();
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction instruction = DexBackedInstruction.readFrom(reader);
|
Instruction instruction = DexBackedInstruction.readFrom(dexFile, reader);
|
||||||
|
|
||||||
// Does the instruction extend past the end of the method?
|
// Does the instruction extend past the end of the method?
|
||||||
int offset = reader.getOffset();
|
int offset = reader.getOffset();
|
||||||
@ -97,9 +97,9 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<? extends DexBackedTryBlock> getTryBlocks() {
|
public List<? extends DexBackedTryBlock> getTryBlocks() {
|
||||||
final int triesSize = dexFile.readUshort(codeOffset + CodeItem.TRIES_SIZE_OFFSET);
|
final int triesSize = dexFile.getBuffer().readUshort(codeOffset + CodeItem.TRIES_SIZE_OFFSET);
|
||||||
if (triesSize > 0) {
|
if (triesSize > 0) {
|
||||||
int instructionsSize = dexFile.readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET);
|
int instructionsSize = dexFile.getBuffer().readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET);
|
||||||
final int triesStartOffset = AlignmentUtils.alignOffset(
|
final int triesStartOffset = AlignmentUtils.alignOffset(
|
||||||
codeOffset + CodeItem.INSTRUCTION_START_OFFSET + (instructionsSize*2), 4);
|
codeOffset + CodeItem.INSTRUCTION_START_OFFSET + (instructionsSize*2), 4);
|
||||||
final int handlersStartOffset = triesStartOffset + triesSize*CodeItem.TryItem.ITEM_SIZE;
|
final int handlersStartOffset = triesStartOffset + triesSize*CodeItem.TryItem.ITEM_SIZE;
|
||||||
@ -124,7 +124,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private DebugInfo getDebugInfo() {
|
private DebugInfo getDebugInfo() {
|
||||||
int debugOffset = dexFile.readInt(codeOffset + CodeItem.DEBUG_INFO_OFFSET);
|
int debugOffset = dexFile.getBuffer().readInt(codeOffset + CodeItem.DEBUG_INFO_OFFSET);
|
||||||
|
|
||||||
if (debugOffset == -1 || debugOffset == 0) {
|
if (debugOffset == -1 || debugOffset == 0) {
|
||||||
return DebugInfo.newOrEmpty(dexFile, 0, this);
|
return DebugInfo.newOrEmpty(dexFile, 0, this);
|
||||||
@ -133,7 +133,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
System.err.println(String.format("%s: Invalid debug offset", method));
|
System.err.println(String.format("%s: Invalid debug offset", method));
|
||||||
return DebugInfo.newOrEmpty(dexFile, 0, this);
|
return DebugInfo.newOrEmpty(dexFile, 0, this);
|
||||||
}
|
}
|
||||||
if (debugOffset >= dexFile.buf.length) {
|
if (debugOffset >= dexFile.getBuffer().buf.length) {
|
||||||
System.err.println(String.format("%s: Invalid debug offset", method));
|
System.err.println(String.format("%s: Invalid debug offset", method));
|
||||||
return DebugInfo.newOrEmpty(dexFile, 0, this);
|
return DebugInfo.newOrEmpty(dexFile, 0, this);
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
int lastOffset = codeOffset + CodeItem.INSTRUCTION_START_OFFSET;
|
int lastOffset = codeOffset + CodeItem.INSTRUCTION_START_OFFSET;
|
||||||
|
|
||||||
//set code_item ending offset to the end of instructions list (insns_size * ushort)
|
//set code_item ending offset to the end of instructions list (insns_size * ushort)
|
||||||
lastOffset += dexFile.readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET) * 2;
|
lastOffset += dexFile.getBuffer().readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET) * 2;
|
||||||
|
|
||||||
//read any exception handlers and move code_item offset to the end
|
//read any exception handlers and move code_item offset to the end
|
||||||
for (DexBackedTryBlock tryBlock: getTryBlocks()) {
|
for (DexBackedTryBlock tryBlock: getTryBlocks()) {
|
||||||
|
@ -63,8 +63,8 @@ public class DexBackedOdexFile extends DexBackedDexFile {
|
|||||||
final int dexOffset = OdexHeaderItem.getDexOffset(odexBuf);
|
final int dexOffset = OdexHeaderItem.getDexOffset(odexBuf);
|
||||||
final int dependencyOffset = OdexHeaderItem.getDependenciesOffset(odexBuf) - dexOffset;
|
final int dependencyOffset = OdexHeaderItem.getDependenciesOffset(odexBuf) - dexOffset;
|
||||||
|
|
||||||
BaseDexBuffer buf = new BaseDexBuffer(this.buf);
|
DexBuffer fromStartBuffer = new DexBuffer(getBuffer().buf, 0);
|
||||||
int dependencyCount = buf.readInt(dependencyOffset + DEPENDENCY_COUNT_OFFSET);
|
int dependencyCount = fromStartBuffer.readInt(dependencyOffset + DEPENDENCY_COUNT_OFFSET);
|
||||||
|
|
||||||
return new VariableSizeList<String>(this, dependencyOffset + DEPENDENCY_START_OFFSET, dependencyCount) {
|
return new VariableSizeList<String>(this, dependencyOffset + DEPENDENCY_START_OFFSET, dependencyCount) {
|
||||||
@Override protected String readNextItem(@Nonnull DexReader reader, int index) {
|
@Override protected String readNextItem(@Nonnull DexReader reader, int index) {
|
||||||
@ -72,7 +72,7 @@ public class DexBackedOdexFile extends DexBackedDexFile {
|
|||||||
int offset = reader.getOffset();
|
int offset = reader.getOffset();
|
||||||
reader.moveRelative(length + 20);
|
reader.moveRelative(length + 20);
|
||||||
try {
|
try {
|
||||||
return new String(DexBackedOdexFile.this.buf, offset, length-1, "US-ASCII");
|
return new String(fromStartBuffer.buf, offset, length-1, "US-ASCII");
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
@ -52,18 +52,18 @@ public class DexBackedTryBlock extends BaseTryBlock<DexBackedExceptionHandler> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getStartCodeAddress() {
|
@Override public int getStartCodeAddress() {
|
||||||
return dexFile.readSmallUint(tryItemOffset + CodeItem.TryItem.START_ADDRESS_OFFSET);
|
return dexFile.getBuffer().readSmallUint(tryItemOffset + CodeItem.TryItem.START_ADDRESS_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getCodeUnitCount() {
|
@Override public int getCodeUnitCount() {
|
||||||
return dexFile.readUshort(tryItemOffset + CodeItem.TryItem.CODE_UNIT_COUNT_OFFSET);
|
return dexFile.getBuffer().readUshort(tryItemOffset + CodeItem.TryItem.CODE_UNIT_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<? extends DexBackedExceptionHandler> getExceptionHandlers() {
|
public List<? extends DexBackedExceptionHandler> getExceptionHandlers() {
|
||||||
DexReader reader = dexFile.readerAt(
|
DexReader reader = dexFile.getBuffer().readerAt(
|
||||||
handlersStartOffset + dexFile.readUshort(tryItemOffset + CodeItem.TryItem.HANDLER_OFFSET));
|
handlersStartOffset + dexFile.getBuffer().readUshort(tryItemOffset + CodeItem.TryItem.HANDLER_OFFSET));
|
||||||
final int encodedSize = reader.readSleb128();
|
final int encodedSize = reader.readSleb128();
|
||||||
|
|
||||||
if (encodedSize > 0) {
|
if (encodedSize > 0) {
|
||||||
@ -72,7 +72,7 @@ public class DexBackedTryBlock extends BaseTryBlock<DexBackedExceptionHandler> {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected DexBackedTypedExceptionHandler readNextItem(@Nonnull DexReader reader, int index) {
|
protected DexBackedTypedExceptionHandler readNextItem(@Nonnull DexReader reader, int index) {
|
||||||
return new DexBackedTypedExceptionHandler(reader);
|
return new DexBackedTypedExceptionHandler(dexFile, reader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -85,7 +85,7 @@ public class DexBackedTryBlock extends BaseTryBlock<DexBackedExceptionHandler> {
|
|||||||
if (index == sizeWithCatchAll-1) {
|
if (index == sizeWithCatchAll-1) {
|
||||||
return new DexBackedCatchAllExceptionHandler(dexReader);
|
return new DexBackedCatchAllExceptionHandler(dexReader);
|
||||||
} else {
|
} else {
|
||||||
return new DexBackedTypedExceptionHandler(dexReader);
|
return new DexBackedTypedExceptionHandler(dexFile, dexReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -38,8 +38,8 @@ public class DexBackedTypedExceptionHandler extends DexBackedExceptionHandler {
|
|||||||
private final int typeId;
|
private final int typeId;
|
||||||
private final int handlerCodeAddress;
|
private final int handlerCodeAddress;
|
||||||
|
|
||||||
public DexBackedTypedExceptionHandler(@Nonnull DexReader reader) {
|
public DexBackedTypedExceptionHandler(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.typeId = reader.readSmallUleb128();
|
this.typeId = reader.readSmallUleb128();
|
||||||
this.handlerCodeAddress = reader.readSmallUleb128();
|
this.handlerCodeAddress = reader.readSmallUleb128();
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,16 @@ package org.jf.dexlib2.dexbacked;
|
|||||||
import org.jf.util.ExceptionWithContext;
|
import org.jf.util.ExceptionWithContext;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class BaseDexBuffer {
|
public class DexBuffer {
|
||||||
@Nonnull final byte[] buf;
|
@Nonnull final byte[] buf;
|
||||||
final int baseOffset;
|
final int baseOffset;
|
||||||
|
|
||||||
public BaseDexBuffer(@Nonnull byte[] buf) {
|
public DexBuffer(@Nonnull byte[] buf) {
|
||||||
this(buf, 0);
|
this(buf, 0);
|
||||||
}
|
}
|
||||||
public BaseDexBuffer(@Nonnull byte[] buf, int offset) {
|
public DexBuffer(@Nonnull byte[] buf, int offset) {
|
||||||
this.buf = buf;
|
this.buf = buf;
|
||||||
this.baseOffset = offset;
|
this.baseOffset = offset;
|
||||||
}
|
}
|
||||||
@ -135,12 +136,17 @@ public class BaseDexBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public BaseDexReader readerAt(int offset) {
|
public byte[] readByteRange(int start, int length) {
|
||||||
return new BaseDexReader<BaseDexBuffer>(this, offset);
|
return Arrays.copyOfRange(buf, baseOffset + start, baseOffset + start + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
protected byte[] getBuf() {
|
public DexReader readerAt(int offset) {
|
||||||
|
return new DexReader<DexBuffer>(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public byte[] getBuf() {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
@ -31,10 +31,593 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
package org.jf.dexlib2.dexbacked;
|
||||||
|
|
||||||
|
import org.jf.util.ExceptionWithContext;
|
||||||
|
import org.jf.util.Utf8Utils;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class DexReader extends BaseDexReader<DexBackedDexFile> {
|
public class DexReader<T extends DexBuffer> {
|
||||||
public DexReader(@Nonnull DexBackedDexFile dexFile, int offset) {
|
@Nonnull public final T dexBuf;
|
||||||
super(dexFile, offset);
|
private int offset;
|
||||||
|
|
||||||
|
public DexReader(@Nonnull T dexBuf, int offset) {
|
||||||
|
this.dexBuf = dexBuf;
|
||||||
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public int getOffset() { return offset; }
|
||||||
|
public void setOffset(int offset) { this.offset = offset; }
|
||||||
|
|
||||||
|
public int readSleb128() {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result <= 0x7f) {
|
||||||
|
result = (result << 25) >> 25;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||||
|
if (currentByteValue <= 0x7f) {
|
||||||
|
result = (result << 18) >> 18;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 14;
|
||||||
|
if (currentByteValue <= 0x7f) {
|
||||||
|
result = (result << 11) >> 11;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 21;
|
||||||
|
if (currentByteValue <= 0x7f) {
|
||||||
|
result = (result << 4) >> 4;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
result |= currentByteValue << 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekSleb128Size() {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return end - (dexBuf.baseOffset + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSmallUleb128() {
|
||||||
|
return readUleb128(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekSmallUleb128Size() {
|
||||||
|
return peekUleb128Size(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int readUleb128(boolean allowLarge) {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 14;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 21;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
|
||||||
|
// MSB shouldn't be set on last byte
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
} else if ((currentByteValue & 0xf) > 0x07) {
|
||||||
|
if (!allowLarge) {
|
||||||
|
// for non-large uleb128s, we assume most significant bit of the result will not be
|
||||||
|
// set, so that it can fit into a signed integer without wrapping
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result |= currentByteValue << 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int peekUleb128Size(boolean allowLarge) {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
|
||||||
|
// MSB shouldn't be set on last byte
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
} else if ((currentByteValue & 0xf) > 0x07) {
|
||||||
|
if (!allowLarge) {
|
||||||
|
// for non-large uleb128s, we assume most significant bit of the result will not be
|
||||||
|
// set, so that it can fit into a signed integer without wrapping
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return end - (dexBuf.baseOffset + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a "large" uleb128. That is, one that may legitimately be greater than a signed int.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* caller to handle the value appropriately.
|
||||||
|
*/
|
||||||
|
public int readLargeUleb128() {
|
||||||
|
return readUleb128(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a "big" uleb128 that can legitimately be > 2^31. The value is returned as a signed integer, with the
|
||||||
|
* expected semantics of re-interpreting an unsigned value as a signed value.
|
||||||
|
*
|
||||||
|
* @return The unsigned value, reinterpreted as a signed int
|
||||||
|
*/
|
||||||
|
public int readBigUleb128() {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 14;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 21;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
|
||||||
|
// MSB shouldn't be set on last byte
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
result |= currentByteValue << 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekBigUleb128Size() {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
|
||||||
|
// MSB shouldn't be set on last byte
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return end - (dexBuf.baseOffset + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipUleb128() {
|
||||||
|
int end = dexBuf.baseOffset + offset;
|
||||||
|
byte currentByteValue;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end - dexBuf.baseOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSmallUint() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readSmallUint(o);
|
||||||
|
offset = o + 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readOptionalUint() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readOptionalUint(o);
|
||||||
|
offset = o + 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekUshort() {
|
||||||
|
return dexBuf.readUshort(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUshort() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readUshort(offset);
|
||||||
|
offset = o + 2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekUbyte() {
|
||||||
|
return dexBuf.readUbyte(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUbyte() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readUbyte(offset);
|
||||||
|
offset = o + 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readLong() {
|
||||||
|
int o = offset;
|
||||||
|
long result = dexBuf.readLong(offset);
|
||||||
|
offset = o + 8;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readInt(offset);
|
||||||
|
offset = o + 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readShort() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readShort(offset);
|
||||||
|
offset = o + 2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readByte() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readByte(offset);
|
||||||
|
offset = o + 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipByte() { offset++; }
|
||||||
|
public void moveRelative(int i) { offset += i; }
|
||||||
|
|
||||||
|
public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
|
||||||
|
public int readUshort(int offset) { return dexBuf.readUshort(offset); }
|
||||||
|
public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
|
||||||
|
public long readLong(int offset) { return dexBuf.readLong(offset); }
|
||||||
|
public int readInt(int offset) { return dexBuf.readInt(offset); }
|
||||||
|
public int readShort(int offset) { return dexBuf.readShort(offset); }
|
||||||
|
public int readByte(int offset) { return dexBuf.readByte(offset); }
|
||||||
|
|
||||||
|
public int readSizedInt(int bytes) {
|
||||||
|
int o = dexBuf.baseOffset + offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 4:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
(buf[o+3] << 24);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2]) << 16);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1]) << 8);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = buf[o];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSizedSmallUint(int bytes) {
|
||||||
|
int o = dexBuf.baseOffset + offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
switch (bytes) {
|
||||||
|
case 4:
|
||||||
|
int b = buf[o+3];
|
||||||
|
if (b < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Encountered valid sized uint that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
result = b << 24;
|
||||||
|
// fall-through
|
||||||
|
case 3:
|
||||||
|
result |= (buf[o+2] & 0xff) << 16;
|
||||||
|
// fall-through
|
||||||
|
case 2:
|
||||||
|
result |= (buf[o+1] & 0xff) << 8;
|
||||||
|
// fall-through
|
||||||
|
case 1:
|
||||||
|
result |= (buf[o] & 0xff);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSizedRightExtendedInt(int bytes) {
|
||||||
|
int o = dexBuf.baseOffset + offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 4:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
(buf[o+3] << 24);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = (buf[o] & 0xff) << 8 |
|
||||||
|
((buf[o+1] & 0xff) << 16) |
|
||||||
|
(buf[o+2] << 24);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = (buf[o] & 0xff) << 16 |
|
||||||
|
(buf[o+1] << 24);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = buf[o] << 24;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readSizedRightExtendedLong(int bytes) {
|
||||||
|
int o = dexBuf.baseOffset + offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
long result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 8:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((buf[o+5] & 0xffL) << 40) |
|
||||||
|
((buf[o+6] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+7]) << 56);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result = ((buf[o] & 0xff)) << 8 |
|
||||||
|
((buf[o+1] & 0xff) << 16) |
|
||||||
|
((buf[o+2] & 0xffL) << 24) |
|
||||||
|
((buf[o+3] & 0xffL) << 32) |
|
||||||
|
((buf[o+4] & 0xffL) << 40) |
|
||||||
|
((buf[o+5] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+6]) << 56);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
result = ((buf[o] & 0xff)) << 16 |
|
||||||
|
((buf[o+1] & 0xffL) << 24) |
|
||||||
|
((buf[o+2] & 0xffL) << 32) |
|
||||||
|
((buf[o+3] & 0xffL) << 40) |
|
||||||
|
((buf[o+4] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+5]) << 56);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result = ((buf[o] & 0xffL)) << 24 |
|
||||||
|
((buf[o+1] & 0xffL) << 32) |
|
||||||
|
((buf[o+2] & 0xffL) << 40) |
|
||||||
|
((buf[o+3] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+4]) << 56);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result = ((buf[o] & 0xffL)) << 32 |
|
||||||
|
((buf[o+1] & 0xffL) << 40) |
|
||||||
|
((buf[o+2] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+3]) << 56);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = ((buf[o] & 0xffL)) << 40 |
|
||||||
|
((buf[o+1] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+2]) << 56);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = ((buf[o] & 0xffL)) << 48 |
|
||||||
|
(((long)buf[o+1]) << 56);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = ((long)buf[o]) << 56;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readSizedLong(int bytes) {
|
||||||
|
int o = dexBuf.baseOffset + offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
long result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 8:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((buf[o+5] & 0xffL) << 40) |
|
||||||
|
((buf[o+6] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+7]) << 56);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((buf[o+5] & 0xffL) << 40) |
|
||||||
|
((long)(buf[o+6]) << 48);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((long)(buf[o+5]) << 40);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((long)(buf[o+4]) << 32);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
(((long)buf[o+3]) << 24);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
(buf[o+2] << 16);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
(buf[o+1] << 8);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = buf[o];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = o + bytes - dexBuf.baseOffset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readString(int utf16Length) {
|
||||||
|
int[] ret = new int[1];
|
||||||
|
String value = Utf8Utils.utf8BytesWithUtf16LengthToString(
|
||||||
|
dexBuf.buf, dexBuf.baseOffset + offset, utf16Length, ret);
|
||||||
|
offset += ret[0];
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekStringLength(int utf16Length) {
|
||||||
|
int[] ret = new int[1];
|
||||||
|
Utf8Utils.utf8BytesWithUtf16LengthToString(
|
||||||
|
dexBuf.buf, dexBuf.baseOffset + offset, utf16Length, ret);
|
||||||
|
return ret[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -53,7 +53,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OatFile extends BaseDexBuffer implements MultiDexContainer<OatDexFile> {
|
public class OatFile extends DexBuffer implements MultiDexContainer<OatDexFile> {
|
||||||
private static final byte[] ELF_MAGIC = new byte[] { 0x7f, 'E', 'L', 'F' };
|
private static final byte[] ELF_MAGIC = new byte[] { 0x7f, 'E', 'L', 'F' };
|
||||||
private static final byte[] OAT_MAGIC = new byte[] { 'o', 'a', 't', '\n' };
|
private static final byte[] OAT_MAGIC = new byte[] { 'o', 'a', 't', '\n' };
|
||||||
private static final int MIN_ELF_HEADER_SIZE = 52;
|
private static final int MIN_ELF_HEADER_SIZE = 52;
|
||||||
|
@ -54,8 +54,8 @@ public class DexBackedArrayPayload extends DexBackedInstruction implements Array
|
|||||||
int instructionStart) {
|
int instructionStart) {
|
||||||
super(dexFile, OPCODE, instructionStart);
|
super(dexFile, OPCODE, instructionStart);
|
||||||
|
|
||||||
elementWidth = dexFile.readUshort(instructionStart + ELEMENT_WIDTH_OFFSET);
|
elementWidth = dexFile.getBuffer().readUshort(instructionStart + ELEMENT_WIDTH_OFFSET);
|
||||||
elementCount = dexFile.readSmallUint(instructionStart + ELEMENT_COUNT_OFFSET);
|
elementCount = dexFile.getBuffer().readSmallUint(instructionStart + ELEMENT_COUNT_OFFSET);
|
||||||
if (((long)elementWidth) * elementCount > Integer.MAX_VALUE) {
|
if (((long)elementWidth) * elementCount > Integer.MAX_VALUE) {
|
||||||
throw new ExceptionWithContext("Invalid array-payload instruction: element width*count overflows");
|
throw new ExceptionWithContext("Invalid array-payload instruction: element width*count overflows");
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ public class DexBackedArrayPayload extends DexBackedInstruction implements Array
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Number readItem(int index) {
|
public Number readItem(int index) {
|
||||||
return dexFile.readByte(elementsStart + index);
|
return dexFile.getBuffer().readByte(elementsStart + index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case 2:
|
case 2:
|
||||||
@ -86,7 +86,7 @@ public class DexBackedArrayPayload extends DexBackedInstruction implements Array
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Number readItem(int index) {
|
public Number readItem(int index) {
|
||||||
return dexFile.readShort(elementsStart + index*2);
|
return dexFile.getBuffer().readShort(elementsStart + index*2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case 4:
|
case 4:
|
||||||
@ -94,7 +94,7 @@ public class DexBackedArrayPayload extends DexBackedInstruction implements Array
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Number readItem(int index) {
|
public Number readItem(int index) {
|
||||||
return dexFile.readInt(elementsStart + index*4);
|
return dexFile.getBuffer().readInt(elementsStart + index*4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case 8:
|
case 8:
|
||||||
@ -102,7 +102,7 @@ public class DexBackedArrayPayload extends DexBackedInstruction implements Array
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Number readItem(int index) {
|
public Number readItem(int index) {
|
||||||
return dexFile.readLong(elementsStart + index*8);
|
return dexFile.getBuffer().readLong(elementsStart + index*8);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
|
@ -57,16 +57,16 @@ public abstract class DexBackedInstruction implements Instruction {
|
|||||||
@Override public int getCodeUnits() { return opcode.format.size / 2; }
|
@Override public int getCodeUnits() { return opcode.format.size / 2; }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static Instruction readFrom(@Nonnull DexReader reader) {
|
public static Instruction readFrom(DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
int opcodeValue = reader.peekUbyte();
|
int opcodeValue = reader.peekUbyte();
|
||||||
|
|
||||||
if (opcodeValue == 0) {
|
if (opcodeValue == 0) {
|
||||||
opcodeValue = reader.peekUshort();
|
opcodeValue = reader.peekUshort();
|
||||||
}
|
}
|
||||||
|
|
||||||
Opcode opcode = reader.dexBuf.getOpcodes().getOpcodeByValue(opcodeValue);
|
Opcode opcode = dexFile.getOpcodes().getOpcodeByValue(opcodeValue);
|
||||||
|
|
||||||
Instruction instruction = buildInstruction(reader.dexBuf, opcode, reader.getOffset());
|
Instruction instruction = buildInstruction(dexFile, opcode, reader.getOffset());
|
||||||
reader.moveRelative(instruction.getCodeUnits()*2);
|
reader.moveRelative(instruction.getCodeUnits()*2);
|
||||||
return instruction;
|
return instruction;
|
||||||
}
|
}
|
||||||
|
@ -44,5 +44,5 @@ public class DexBackedInstruction10t extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getCodeOffset() { return dexFile.readByte(instructionStart + 1); }
|
@Override public int getCodeOffset() { return dexFile.getBuffer().readByte(instructionStart + 1); }
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ public class DexBackedInstruction11n extends DexBackedInstruction implements Ins
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterA() {
|
public int getRegisterA() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNarrowLiteral() {
|
public int getNarrowLiteral() {
|
||||||
return NibbleUtils.extractHighSignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractHighSignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||||
|
@ -44,5 +44,5 @@ public class DexBackedInstruction11x extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,11 @@ public class DexBackedInstruction12x extends DexBackedInstruction implements Ins
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterA() {
|
public int getRegisterA() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterB() {
|
public int getRegisterB() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ public class DexBackedInstruction20bc extends DexBackedInstruction implements In
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getVerificationError() { return dexFile.readUbyte(instructionStart + 1) & 0x3f; }
|
@Override public int getVerificationError() { return dexFile.getBuffer().readUbyte(instructionStart + 1) & 0x3f; }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
int referenceIndex = dexFile.readUshort(instructionStart + 2);
|
int referenceIndex = dexFile.getBuffer().readUshort(instructionStart + 2);
|
||||||
try {
|
try {
|
||||||
int referenceType = getReferenceType();
|
int referenceType = getReferenceType();
|
||||||
return DexBackedReference.makeReference(dexFile, referenceType, referenceIndex);
|
return DexBackedReference.makeReference(dexFile, referenceType, referenceIndex);
|
||||||
@ -68,7 +68,7 @@ public class DexBackedInstruction20bc extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getReferenceType() {
|
@Override public int getReferenceType() {
|
||||||
int referenceType = (dexFile.readUbyte(instructionStart + 1) >>> 6) + 1;
|
int referenceType = (dexFile.getBuffer().readUbyte(instructionStart + 1) >>> 6) + 1;
|
||||||
ReferenceType.validateReferenceType(referenceType);
|
ReferenceType.validateReferenceType(referenceType);
|
||||||
return referenceType;
|
return referenceType;
|
||||||
}
|
}
|
||||||
|
@ -44,5 +44,5 @@ public class DexBackedInstruction20t extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getCodeOffset() { return dexFile.readShort(instructionStart + 2); }
|
@Override public int getCodeOffset() { return dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -46,12 +46,13 @@ public class DexBackedInstruction21c extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType, dexFile.readUshort(instructionStart + 2));
|
return DexBackedReference.makeReference(
|
||||||
|
dexFile, opcode.referenceType, dexFile.getBuffer().readUshort(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,8 +44,8 @@ public class DexBackedInstruction21ih extends DexBackedInstruction implements In
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getNarrowLiteral() { return getHatLiteral() << 16; }
|
@Override public int getNarrowLiteral() { return getHatLiteral() << 16; }
|
||||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||||
@Override public short getHatLiteral() { return (short)dexFile.readShort(instructionStart + 2); }
|
@Override public short getHatLiteral() { return (short)dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class DexBackedInstruction21lh extends DexBackedInstruction implements In
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public long getWideLiteral() { return ((long)getHatLiteral()) << 48; }
|
@Override public long getWideLiteral() { return ((long)getHatLiteral()) << 48; }
|
||||||
@Override public short getHatLiteral() { return (short)dexFile.readShort(instructionStart + 2); }
|
@Override public short getHatLiteral() { return (short)dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class DexBackedInstruction21s extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getNarrowLiteral() { return dexFile.readShort(instructionStart + 2); }
|
@Override public int getNarrowLiteral() { return dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,6 @@ public class DexBackedInstruction21t extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getCodeOffset() { return dexFile.readShort(instructionStart + 2); }
|
@Override public int getCodeOffset() { return dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ public class DexBackedInstruction22b extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getRegisterB() { return dexFile.readUbyte(instructionStart + 2); }
|
@Override public int getRegisterB() { return dexFile.getBuffer().readUbyte(instructionStart + 2); }
|
||||||
@Override public int getNarrowLiteral() { return dexFile.readByte(instructionStart + 3); }
|
@Override public int getNarrowLiteral() { return dexFile.getBuffer().readByte(instructionStart + 3); }
|
||||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||||
}
|
}
|
||||||
|
@ -49,18 +49,19 @@ public class DexBackedInstruction22c extends DexBackedInstruction implements Ins
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterA() {
|
public int getRegisterA() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterB() {
|
public int getRegisterB() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType, dexFile.readUshort(instructionStart + 2));
|
return DexBackedReference.makeReference(
|
||||||
|
dexFile, opcode.referenceType, dexFile.getBuffer().readUshort(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,16 +47,16 @@ public class DexBackedInstruction22cs extends DexBackedInstruction implements In
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterA() {
|
public int getRegisterA() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterB() {
|
public int getRegisterB() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFieldOffset() {
|
public int getFieldOffset() {
|
||||||
return dexFile.readUshort(instructionStart + 2);
|
return dexFile.getBuffer().readUshort(instructionStart + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,14 +47,14 @@ public class DexBackedInstruction22s extends DexBackedInstruction implements Ins
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterA() {
|
public int getRegisterA() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterB() {
|
public int getRegisterB() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getNarrowLiteral() { return dexFile.readShort(instructionStart + 2); }
|
@Override public int getNarrowLiteral() { return dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,13 @@ public class DexBackedInstruction22t extends DexBackedInstruction implements Ins
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterA() {
|
public int getRegisterA() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterB() {
|
public int getRegisterB() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readByte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getCodeOffset() { return dexFile.readShort(instructionStart + 2); }
|
@Override public int getCodeOffset() { return dexFile.getBuffer().readShort(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,6 @@ public class DexBackedInstruction22x extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getRegisterB() { return dexFile.readUshort(instructionStart + 2); }
|
@Override public int getRegisterB() { return dexFile.getBuffer().readUshort(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class DexBackedInstruction23x extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getRegisterB() { return dexFile.readUbyte(instructionStart + 2); }
|
@Override public int getRegisterB() { return dexFile.getBuffer().readUbyte(instructionStart + 2); }
|
||||||
@Override public int getRegisterC() { return dexFile.readUbyte(instructionStart + 3); }
|
@Override public int getRegisterC() { return dexFile.getBuffer().readUbyte(instructionStart + 3); }
|
||||||
}
|
}
|
||||||
|
@ -44,5 +44,5 @@ public class DexBackedInstruction30t extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getCodeOffset() { return dexFile.readInt(instructionStart + 2); }
|
@Override public int getCodeOffset() { return dexFile.getBuffer().readInt(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -46,13 +46,13 @@ public class DexBackedInstruction31c extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
||||||
dexFile.readSmallUint(instructionStart + 2));
|
dexFile.getBuffer().readSmallUint(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,7 +44,7 @@ public class DexBackedInstruction31i extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getNarrowLiteral() { return dexFile.readInt(instructionStart + 2); }
|
@Override public int getNarrowLiteral() { return dexFile.getBuffer().readInt(instructionStart + 2); }
|
||||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,6 @@ public class DexBackedInstruction31t extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public int getCodeOffset() { return dexFile.readInt(instructionStart + 2); }
|
@Override public int getCodeOffset() { return dexFile.getBuffer().readInt(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,6 @@ public class DexBackedInstruction32x extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUshort(instructionStart + 2); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUshort(instructionStart + 2); }
|
||||||
@Override public int getRegisterB() { return dexFile.readUshort(instructionStart + 4); }
|
@Override public int getRegisterB() { return dexFile.getBuffer().readUshort(instructionStart + 4); }
|
||||||
}
|
}
|
||||||
|
@ -48,39 +48,39 @@ public class DexBackedInstruction35c extends DexBackedInstruction implements Ins
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterC() {
|
public int getRegisterC() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterD() {
|
public int getRegisterD() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterE() {
|
public int getRegisterE() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterF() {
|
public int getRegisterF() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterG() {
|
public int getRegisterG() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
||||||
dexFile.readUshort(instructionStart + 2));
|
dexFile.getBuffer().readUshort(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,36 +46,36 @@ public class DexBackedInstruction35mi extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterC() {
|
public int getRegisterC() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterD() {
|
public int getRegisterD() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterE() {
|
public int getRegisterE() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterF() {
|
public int getRegisterF() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterG() {
|
public int getRegisterG() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInlineIndex() {
|
public int getInlineIndex() {
|
||||||
return dexFile.readUshort(instructionStart + 2);
|
return dexFile.getBuffer().readUshort(instructionStart + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,36 +46,36 @@ public class DexBackedInstruction35ms extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterC() {
|
public int getRegisterC() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterD() {
|
public int getRegisterD() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterE() {
|
public int getRegisterE() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterF() {
|
public int getRegisterF() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterG() {
|
public int getRegisterG() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVtableIndex() {
|
public int getVtableIndex() {
|
||||||
return dexFile.readUshort(instructionStart + 2);
|
return dexFile.getBuffer().readUshort(instructionStart + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,19 +47,19 @@ public class DexBackedInstruction3rc extends DexBackedInstruction implements Ins
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return dexFile.readUbyte(instructionStart + 1);
|
return dexFile.getBuffer().readUbyte(instructionStart + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStartRegister() {
|
public int getStartRegister() {
|
||||||
return dexFile.readUshort(instructionStart + 4);
|
return dexFile.getBuffer().readUshort(instructionStart + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
||||||
dexFile.readUshort(instructionStart + 2));
|
dexFile.getBuffer().readUshort(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,16 +45,16 @@ public class DexBackedInstruction3rmi extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return dexFile.readUbyte(instructionStart + 1);
|
return dexFile.getBuffer().readUbyte(instructionStart + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStartRegister() {
|
public int getStartRegister() {
|
||||||
return dexFile.readUshort(instructionStart + 4);
|
return dexFile.getBuffer().readUshort(instructionStart + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInlineIndex() {
|
public int getInlineIndex() {
|
||||||
return dexFile.readUshort(instructionStart + 2);
|
return dexFile.getBuffer().readUshort(instructionStart + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,16 +45,16 @@ public class DexBackedInstruction3rms extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return dexFile.readUbyte(instructionStart + 1);
|
return dexFile.getBuffer().readUbyte(instructionStart + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStartRegister() {
|
public int getStartRegister() {
|
||||||
return dexFile.readUshort(instructionStart + 4);
|
return dexFile.getBuffer().readUshort(instructionStart + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVtableIndex() {
|
public int getVtableIndex() {
|
||||||
return dexFile.readUshort(instructionStart + 2);
|
return dexFile.getBuffer().readUshort(instructionStart + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,39 +48,39 @@ public class DexBackedInstruction45cc extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterC() {
|
public int getRegisterC() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterD() {
|
public int getRegisterD() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 4));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterE() {
|
public int getRegisterE() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterF() {
|
public int getRegisterF() {
|
||||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 5));
|
return NibbleUtils.extractHighUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRegisterG() {
|
public int getRegisterG() {
|
||||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1));
|
return NibbleUtils.extractLowUnsignedNibble(dexFile.getBuffer().readUbyte(instructionStart + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
||||||
dexFile.readUshort(instructionStart + 2));
|
dexFile.getBuffer().readUshort(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,7 +91,7 @@ public class DexBackedInstruction45cc extends DexBackedInstruction implements In
|
|||||||
@Override
|
@Override
|
||||||
public Reference getReference2() {
|
public Reference getReference2() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType2,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType2,
|
||||||
dexFile.readUshort(instructionStart + 6));
|
dexFile.getBuffer().readUshort(instructionStart + 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,19 +47,19 @@ public class DexBackedInstruction4rcc extends DexBackedInstruction implements In
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterCount() {
|
@Override public int getRegisterCount() {
|
||||||
return dexFile.readUbyte(instructionStart + 1);
|
return dexFile.getBuffer().readUbyte(instructionStart + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStartRegister() {
|
public int getStartRegister() {
|
||||||
return dexFile.readUshort(instructionStart + 4);
|
return dexFile.getBuffer().readUshort(instructionStart + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
||||||
dexFile.readUshort(instructionStart + 2));
|
dexFile.getBuffer().readUshort(instructionStart + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,7 +70,7 @@ public class DexBackedInstruction4rcc extends DexBackedInstruction implements In
|
|||||||
@Override
|
@Override
|
||||||
public Reference getReference2() {
|
public Reference getReference2() {
|
||||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType2,
|
return DexBackedReference.makeReference(dexFile, opcode.referenceType2,
|
||||||
dexFile.readUshort(instructionStart + 6));
|
dexFile.getBuffer().readUshort(instructionStart + 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,6 +44,6 @@ public class DexBackedInstruction51l extends DexBackedInstruction implements Ins
|
|||||||
super(dexFile, opcode, instructionStart);
|
super(dexFile, opcode, instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
@Override public int getRegisterA() { return dexFile.getBuffer().readUbyte(instructionStart + 1); }
|
||||||
@Override public long getWideLiteral() { return dexFile.readLong(instructionStart + 2); }
|
@Override public long getWideLiteral() { return dexFile.getBuffer().readLong(instructionStart + 2); }
|
||||||
}
|
}
|
||||||
|
@ -51,13 +51,13 @@ public class DexBackedPackedSwitchPayload extends DexBackedInstruction implement
|
|||||||
int instructionStart) {
|
int instructionStart) {
|
||||||
super(dexFile, Opcode.PACKED_SWITCH_PAYLOAD, instructionStart);
|
super(dexFile, Opcode.PACKED_SWITCH_PAYLOAD, instructionStart);
|
||||||
|
|
||||||
elementCount = dexFile.readUshort(instructionStart + ELEMENT_COUNT_OFFSET);
|
elementCount = dexFile.getBuffer().readUshort(instructionStart + ELEMENT_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<? extends SwitchElement> getSwitchElements() {
|
public List<? extends SwitchElement> getSwitchElements() {
|
||||||
final int firstKey = dexFile.readInt(instructionStart + FIRST_KEY_OFFSET);
|
final int firstKey = dexFile.getBuffer().readInt(instructionStart + FIRST_KEY_OFFSET);
|
||||||
return new FixedSizeList<SwitchElement>() {
|
return new FixedSizeList<SwitchElement>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
@ -70,7 +70,7 @@ public class DexBackedPackedSwitchPayload extends DexBackedInstruction implement
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOffset() {
|
public int getOffset() {
|
||||||
return dexFile.readInt(instructionStart + TARGETS_OFFSET + index*4);
|
return dexFile.getBuffer().readInt(instructionStart + TARGETS_OFFSET + index*4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class DexBackedSparseSwitchPayload extends DexBackedInstruction implement
|
|||||||
int instructionStart) {
|
int instructionStart) {
|
||||||
super(dexFile, Opcode.SPARSE_SWITCH_PAYLOAD, instructionStart);
|
super(dexFile, Opcode.SPARSE_SWITCH_PAYLOAD, instructionStart);
|
||||||
|
|
||||||
elementCount = dexFile.readUshort(instructionStart + ELEMENT_COUNT_OFFSET);
|
elementCount = dexFile.getBuffer().readUshort(instructionStart + ELEMENT_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -63,12 +63,12 @@ public class DexBackedSparseSwitchPayload extends DexBackedInstruction implement
|
|||||||
return new SwitchElement() {
|
return new SwitchElement() {
|
||||||
@Override
|
@Override
|
||||||
public int getKey() {
|
public int getKey() {
|
||||||
return dexFile.readInt(instructionStart + KEYS_OFFSET + index*4);
|
return dexFile.getBuffer().readInt(instructionStart + KEYS_OFFSET + index*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOffset() {
|
public int getOffset() {
|
||||||
return dexFile.readInt(instructionStart + KEYS_OFFSET + elementCount*4 + index*4);
|
return dexFile.getBuffer().readInt(instructionStart + KEYS_OFFSET + elementCount*4 + index*4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,9 @@ public class DexBackedUnknownInstruction extends DexBackedInstruction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getOriginalOpcode() {
|
@Override public int getOriginalOpcode() {
|
||||||
int opcode = dexFile.readUbyte(instructionStart);
|
int opcode = dexFile.getBuffer().readUbyte(instructionStart);
|
||||||
if (opcode == 0) {
|
if (opcode == 0) {
|
||||||
opcode = dexFile.readUshort(instructionStart);
|
opcode = dexFile.getBuffer().readUshort(instructionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
return opcode;
|
return opcode;
|
||||||
|
@ -56,17 +56,17 @@ public class AnnotationDirectoryItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int classAnnotationsOffset = dexFile.readSmallUint(out.getCursor());
|
int classAnnotationsOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "class_annotations_off = %s",
|
out.annotate(4, "class_annotations_off = %s",
|
||||||
AnnotationSetItem.getReferenceAnnotation(dexFile, classAnnotationsOffset));
|
AnnotationSetItem.getReferenceAnnotation(dexFile, classAnnotationsOffset));
|
||||||
|
|
||||||
int fieldsSize = dexFile.readSmallUint(out.getCursor());
|
int fieldsSize = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "fields_size = %d", fieldsSize);
|
out.annotate(4, "fields_size = %d", fieldsSize);
|
||||||
|
|
||||||
int annotatedMethodsSize = dexFile.readSmallUint(out.getCursor());
|
int annotatedMethodsSize = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "annotated_methods_size = %d", annotatedMethodsSize);
|
out.annotate(4, "annotated_methods_size = %d", annotatedMethodsSize);
|
||||||
|
|
||||||
int annotatedParameterSize = dexFile.readSmallUint(out.getCursor());
|
int annotatedParameterSize = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "annotated_parameters_size = %d", annotatedParameterSize);
|
out.annotate(4, "annotated_parameters_size = %d", annotatedParameterSize);
|
||||||
|
|
||||||
if (fieldsSize > 0) {
|
if (fieldsSize > 0) {
|
||||||
@ -75,9 +75,9 @@ public class AnnotationDirectoryItem {
|
|||||||
for (int i=0; i<fieldsSize; i++) {
|
for (int i=0; i<fieldsSize; i++) {
|
||||||
out.annotate(0, "field_annotation[%d]", i);
|
out.annotate(0, "field_annotation[%d]", i);
|
||||||
out.indent();
|
out.indent();
|
||||||
int fieldIndex = dexFile.readSmallUint(out.getCursor());
|
int fieldIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "%s", FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex));
|
out.annotate(4, "%s", FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex));
|
||||||
int annotationOffset = dexFile.readSmallUint(out.getCursor());
|
int annotationOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "%s", AnnotationSetItem.getReferenceAnnotation(dexFile, annotationOffset));
|
out.annotate(4, "%s", AnnotationSetItem.getReferenceAnnotation(dexFile, annotationOffset));
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
@ -90,9 +90,9 @@ public class AnnotationDirectoryItem {
|
|||||||
for (int i=0; i<annotatedMethodsSize; i++) {
|
for (int i=0; i<annotatedMethodsSize; i++) {
|
||||||
out.annotate(0, "method_annotation[%d]", i);
|
out.annotate(0, "method_annotation[%d]", i);
|
||||||
out.indent();
|
out.indent();
|
||||||
int methodIndex = dexFile.readSmallUint(out.getCursor());
|
int methodIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "%s", MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
|
out.annotate(4, "%s", MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
|
||||||
int annotationOffset = dexFile.readSmallUint(out.getCursor());
|
int annotationOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "%s", AnnotationSetItem.getReferenceAnnotation(dexFile, annotationOffset));
|
out.annotate(4, "%s", AnnotationSetItem.getReferenceAnnotation(dexFile, annotationOffset));
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
@ -105,9 +105,9 @@ public class AnnotationDirectoryItem {
|
|||||||
for (int i=0; i<annotatedParameterSize; i++) {
|
for (int i=0; i<annotatedParameterSize; i++) {
|
||||||
out.annotate(0, "parameter_annotation[%d]", i);
|
out.annotate(0, "parameter_annotation[%d]", i);
|
||||||
out.indent();
|
out.indent();
|
||||||
int methodIndex = dexFile.readSmallUint(out.getCursor());
|
int methodIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "%s", MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
|
out.annotate(4, "%s", MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
|
||||||
int annotationOffset = dexFile.readSmallUint(out.getCursor());
|
int annotationOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "%s", AnnotationSetRefList.getReferenceAnnotation(dexFile, annotationOffset));
|
out.annotate(4, "%s", AnnotationSetRefList.getReferenceAnnotation(dexFile, annotationOffset));
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
|
@ -52,12 +52,12 @@ public class AnnotationItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int visibility = dexFile.readUbyte(out.getCursor());
|
int visibility = dexFile.getBuffer().readUbyte(out.getCursor());
|
||||||
out.annotate(1, "visibility = %d: %s", visibility, getAnnotationVisibility(visibility));
|
out.annotate(1, "visibility = %d: %s", visibility, getAnnotationVisibility(visibility));
|
||||||
|
|
||||||
DexReader reader = dexFile.readerAt(out.getCursor());
|
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
|
||||||
|
|
||||||
EncodedValue.annotateEncodedAnnotation(out, reader);
|
EncodedValue.annotateEncodedAnnotation(dexFile, out, reader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ public class AnnotationItem {
|
|||||||
|
|
||||||
public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int annotationItemOffset) {
|
public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int annotationItemOffset) {
|
||||||
try {
|
try {
|
||||||
DexReader reader = dexFile.readerAt(annotationItemOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(annotationItemOffset);
|
||||||
reader.readUbyte();
|
reader.readUbyte();
|
||||||
int typeIndex = reader.readSmallUleb128();
|
int typeIndex = reader.readSmallUleb128();
|
||||||
String annotationType = dexFile.getTypeSection().get(typeIndex);
|
String annotationType = dexFile.getTypeSection().get(typeIndex);
|
||||||
|
@ -51,11 +51,11 @@ public class AnnotationSetItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int size = dexFile.readSmallUint(out.getCursor());
|
int size = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "size = %d", size);
|
out.annotate(4, "size = %d", size);
|
||||||
|
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
int annotationOffset = dexFile.readSmallUint(out.getCursor());
|
int annotationOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, AnnotationItem.getReferenceAnnotation(dexFile, annotationOffset));
|
out.annotate(4, AnnotationItem.getReferenceAnnotation(dexFile, annotationOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,11 @@ public class AnnotationSetRefList {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int size = dexFile.readSmallUint(out.getCursor());
|
int size = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "size = %d", size);
|
out.annotate(4, "size = %d", size);
|
||||||
|
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
int annotationSetOffset = dexFile.readSmallUint(out.getCursor());
|
int annotationSetOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "annotation_set_item[0x%x]", annotationSetOffset);
|
out.annotate(4, "annotation_set_item[0x%x]", annotationSetOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.dexbacked.raw;
|
package org.jf.dexlib2.dexbacked.raw;
|
||||||
|
|
||||||
import org.jf.dexlib2.dexbacked.DexReader;
|
|
||||||
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
|
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
|
||||||
import org.jf.dexlib2.dexbacked.value.DexBackedArrayEncodedValue;
|
import org.jf.dexlib2.dexbacked.value.DexBackedArrayEncodedValue;
|
||||||
import org.jf.dexlib2.util.AnnotatedBytes;
|
import org.jf.dexlib2.util.AnnotatedBytes;
|
||||||
@ -54,12 +53,12 @@ public class CallSiteIdItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int callSiteOffset = dexFile.readSmallUint(out.getCursor());
|
int callSiteOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
|
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
try {
|
try {
|
||||||
EncodedValueUtils.writeEncodedValue(writer,
|
EncodedValueUtils.writeEncodedValue(writer,
|
||||||
new DexBackedArrayEncodedValue(new DexReader(dexFile, callSiteOffset)));
|
new DexBackedArrayEncodedValue(dexFile, dexFile.getBuffer().readerAt(callSiteOffset)));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
// Shouldn't get an IOException from a StringWriter..
|
// Shouldn't get an IOException from a StringWriter..
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
|
@ -58,7 +58,7 @@ public class ClassDataItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
DexReader reader = dexFile.readerAt(out.getCursor());
|
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
|
||||||
|
|
||||||
int staticFieldsSize = reader.readSmallUleb128();
|
int staticFieldsSize = reader.readSmallUleb128();
|
||||||
out.annotateTo(reader.getOffset(), "static_fields_size = %d", staticFieldsSize);
|
out.annotateTo(reader.getOffset(), "static_fields_size = %d", staticFieldsSize);
|
||||||
|
@ -68,32 +68,32 @@ public class ClassDefItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int classIndex = dexFile.readSmallUint(out.getCursor());
|
int classIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
|
out.annotate(4, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
|
||||||
|
|
||||||
int accessFlags = dexFile.readInt(out.getCursor());
|
int accessFlags = dexFile.getBuffer().readInt(out.getCursor());
|
||||||
out.annotate(4, "access_flags = 0x%x: %s", accessFlags,
|
out.annotate(4, "access_flags = 0x%x: %s", accessFlags,
|
||||||
Joiner.on('|').join(AccessFlags.getAccessFlagsForClass(accessFlags)));
|
Joiner.on('|').join(AccessFlags.getAccessFlagsForClass(accessFlags)));
|
||||||
|
|
||||||
int superclassIndex = dexFile.readOptionalUint(out.getCursor());
|
int superclassIndex = dexFile.getBuffer().readOptionalUint(out.getCursor());
|
||||||
out.annotate(4, "superclass_idx = %s",
|
out.annotate(4, "superclass_idx = %s",
|
||||||
TypeIdItem.getOptionalReferenceAnnotation(dexFile, superclassIndex));
|
TypeIdItem.getOptionalReferenceAnnotation(dexFile, superclassIndex));
|
||||||
|
|
||||||
int interfacesOffset = dexFile.readSmallUint(out.getCursor());
|
int interfacesOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "interfaces_off = %s", TypeListItem.getReferenceAnnotation(dexFile, interfacesOffset));
|
out.annotate(4, "interfaces_off = %s", TypeListItem.getReferenceAnnotation(dexFile, interfacesOffset));
|
||||||
|
|
||||||
int sourceFileIdx = dexFile.readOptionalUint(out.getCursor());
|
int sourceFileIdx = dexFile.getBuffer().readOptionalUint(out.getCursor());
|
||||||
out.annotate(4, "source_file_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile,
|
out.annotate(4, "source_file_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile,
|
||||||
sourceFileIdx));
|
sourceFileIdx));
|
||||||
|
|
||||||
int annotationsOffset = dexFile.readSmallUint(out.getCursor());
|
int annotationsOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
if (annotationsOffset == 0) {
|
if (annotationsOffset == 0) {
|
||||||
out.annotate(4, "annotations_off = annotations_directory_item[NO_OFFSET]");
|
out.annotate(4, "annotations_off = annotations_directory_item[NO_OFFSET]");
|
||||||
} else {
|
} else {
|
||||||
out.annotate(4, "annotations_off = annotations_directory_item[0x%x]", annotationsOffset);
|
out.annotate(4, "annotations_off = annotations_directory_item[0x%x]", annotationsOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int classDataOffset = dexFile.readSmallUint(out.getCursor());
|
int classDataOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
if (classDataOffset == 0) {
|
if (classDataOffset == 0) {
|
||||||
out.annotate(4, "class_data_off = class_data_item[NO_OFFSET]");
|
out.annotate(4, "class_data_off = class_data_item[NO_OFFSET]");
|
||||||
} else {
|
} else {
|
||||||
@ -101,7 +101,7 @@ public class ClassDefItem {
|
|||||||
addClassDataIdentity(classDataOffset, dexFile.getTypeSection().get(classIndex));
|
addClassDataIdentity(classDataOffset, dexFile.getTypeSection().get(classIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int staticValuesOffset = dexFile.readSmallUint(out.getCursor());
|
int staticValuesOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
if (staticValuesOffset == 0) {
|
if (staticValuesOffset == 0) {
|
||||||
out.annotate(4, "static_values_off = encoded_array_item[NO_OFFSET]");
|
out.annotate(4, "static_values_off = encoded_array_item[NO_OFFSET]");
|
||||||
} else {
|
} else {
|
||||||
@ -120,7 +120,7 @@ public class ClassDefItem {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int classIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int classIndex) {
|
||||||
int offset = dexFile.getClassSection().getOffset(classIndex);
|
int offset = dexFile.getClassSection().getOffset(classIndex);
|
||||||
int typeIndex = dexFile.readSmallUint(offset + CLASS_OFFSET);
|
int typeIndex = dexFile.getBuffer().readSmallUint(offset + CLASS_OFFSET);
|
||||||
return dexFile.getTypeSection().get(typeIndex);
|
return dexFile.getTypeSection().get(typeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public class CodeItem {
|
|||||||
@Override
|
@Override
|
||||||
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
try {
|
try {
|
||||||
DexReader reader = dexFile.readerAt(out.getCursor());
|
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
|
||||||
|
|
||||||
int registers = reader.readUshort();
|
int registers = reader.readUshort();
|
||||||
out.annotate(2, "registers_size = %d", registers);
|
out.annotate(2, "registers_size = %d", registers);
|
||||||
@ -118,7 +118,7 @@ public class CodeItem {
|
|||||||
int end = reader.getOffset() + instructionSize*2;
|
int end = reader.getOffset() + instructionSize*2;
|
||||||
try {
|
try {
|
||||||
while (reader.getOffset() < end) {
|
while (reader.getOffset() < end) {
|
||||||
Instruction instruction = DexBackedInstruction.readFrom(reader);
|
Instruction instruction = DexBackedInstruction.readFrom(dexFile, reader);
|
||||||
|
|
||||||
// if we read past the end of the instruction list
|
// if we read past the end of the instruction list
|
||||||
if (reader.getOffset() > end) {
|
if (reader.getOffset() > end) {
|
||||||
|
@ -50,7 +50,7 @@ public class DebugInfoItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
DexReader reader = dexFile.readerAt(out.getCursor());
|
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
|
||||||
|
|
||||||
int lineStart = reader.readBigUleb128();
|
int lineStart = reader.readBigUleb128();
|
||||||
out.annotateTo(reader.getOffset(), "line_start = %d", lineStart & 0xFFFFFFFFL);
|
out.annotateTo(reader.getOffset(), "line_start = %d", lineStart & 0xFFFFFFFFL);
|
||||||
|
@ -48,8 +48,8 @@ public class EncodedArrayItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
DexReader reader = dexFile.readerAt(out.getCursor());
|
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
|
||||||
EncodedValue.annotateEncodedArray(out, reader);
|
EncodedValue.annotateEncodedArray(dexFile, out, reader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
package org.jf.dexlib2.dexbacked.raw;
|
package org.jf.dexlib2.dexbacked.raw;
|
||||||
|
|
||||||
import org.jf.dexlib2.ValueType;
|
import org.jf.dexlib2.ValueType;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||||
import org.jf.dexlib2.dexbacked.DexReader;
|
import org.jf.dexlib2.dexbacked.DexReader;
|
||||||
import org.jf.dexlib2.dexbacked.value.DexBackedEncodedValue;
|
import org.jf.dexlib2.dexbacked.value.DexBackedEncodedValue;
|
||||||
import org.jf.dexlib2.util.AnnotatedBytes;
|
import org.jf.dexlib2.util.AnnotatedBytes;
|
||||||
@ -42,7 +43,10 @@ import java.io.IOException;
|
|||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
|
||||||
public class EncodedValue {
|
public class EncodedValue {
|
||||||
public static void annotateEncodedValue(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) {
|
public static void annotateEncodedValue(
|
||||||
|
@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull AnnotatedBytes out,
|
||||||
|
@Nonnull DexReader reader) {
|
||||||
int valueArgType = reader.readUbyte();
|
int valueArgType = reader.readUbyte();
|
||||||
|
|
||||||
int valueArg = valueArgType >>> 5;
|
int valueArg = valueArgType >>> 5;
|
||||||
@ -66,15 +70,15 @@ public class EncodedValue {
|
|||||||
out.annotate(1, "valueArg = %d, valueType = 0x%x: %s", valueArg, valueType,
|
out.annotate(1, "valueArg = %d, valueType = 0x%x: %s", valueArg, valueType,
|
||||||
ValueType.getValueTypeName(valueType));
|
ValueType.getValueTypeName(valueType));
|
||||||
reader.setOffset(reader.getOffset() - 1);
|
reader.setOffset(reader.getOffset() - 1);
|
||||||
out.annotate(valueArg + 1, "value = %s", asString(reader));
|
out.annotate(valueArg + 1, "value = %s", asString(dexFile, reader));
|
||||||
break;
|
break;
|
||||||
case ValueType.ARRAY:
|
case ValueType.ARRAY:
|
||||||
out.annotate(1, "valueArg = %d, valueType = 0x%x: array", valueArg, valueType);
|
out.annotate(1, "valueArg = %d, valueType = 0x%x: array", valueArg, valueType);
|
||||||
annotateEncodedArray(out, reader);
|
annotateEncodedArray(dexFile, out, reader);
|
||||||
break;
|
break;
|
||||||
case ValueType.ANNOTATION:
|
case ValueType.ANNOTATION:
|
||||||
out.annotate(1, "valueArg = %d, valueType = 0x%x: annotation", valueArg, valueType);
|
out.annotate(1, "valueArg = %d, valueType = 0x%x: annotation", valueArg, valueType);
|
||||||
annotateEncodedAnnotation(out, reader);
|
annotateEncodedAnnotation(dexFile, out, reader);
|
||||||
break;
|
break;
|
||||||
case ValueType.NULL:
|
case ValueType.NULL:
|
||||||
out.annotate(1, "valueArg = %d, valueType = 0x%x: null", valueArg, valueType);
|
out.annotate(1, "valueArg = %d, valueType = 0x%x: null", valueArg, valueType);
|
||||||
@ -88,11 +92,14 @@ public class EncodedValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void annotateEncodedAnnotation(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) {
|
public static void annotateEncodedAnnotation(
|
||||||
|
@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull AnnotatedBytes out,
|
||||||
|
@Nonnull DexReader reader) {
|
||||||
assert out.getCursor() == reader.getOffset();
|
assert out.getCursor() == reader.getOffset();
|
||||||
|
|
||||||
int typeIndex = reader.readSmallUleb128();
|
int typeIndex = reader.readSmallUleb128();
|
||||||
out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(reader.dexBuf, typeIndex));
|
out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
|
||||||
|
|
||||||
int size = reader.readSmallUleb128();
|
int size = reader.readSmallUleb128();
|
||||||
out.annotateTo(reader.getOffset(), "size: %d", size);
|
out.annotateTo(reader.getOffset(), "size: %d", size);
|
||||||
@ -103,15 +110,18 @@ public class EncodedValue {
|
|||||||
|
|
||||||
int nameIndex = reader.readSmallUleb128();
|
int nameIndex = reader.readSmallUleb128();
|
||||||
out.annotateTo(reader.getOffset(), "name = %s",
|
out.annotateTo(reader.getOffset(), "name = %s",
|
||||||
StringIdItem.getReferenceAnnotation(reader.dexBuf, nameIndex));
|
StringIdItem.getReferenceAnnotation(dexFile, nameIndex));
|
||||||
|
|
||||||
annotateEncodedValue(out, reader);
|
annotateEncodedValue(dexFile, out, reader);
|
||||||
|
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void annotateEncodedArray(@Nonnull AnnotatedBytes out, @Nonnull DexReader reader) {
|
public static void annotateEncodedArray(
|
||||||
|
@Nonnull DexBackedDexFile dexFile,
|
||||||
|
@Nonnull AnnotatedBytes out,
|
||||||
|
@Nonnull DexReader reader) {
|
||||||
assert out.getCursor() == reader.getOffset();
|
assert out.getCursor() == reader.getOffset();
|
||||||
|
|
||||||
int size = reader.readSmallUleb128();
|
int size = reader.readSmallUleb128();
|
||||||
@ -121,13 +131,13 @@ public class EncodedValue {
|
|||||||
out.annotate(0, "element[%d]", i);
|
out.annotate(0, "element[%d]", i);
|
||||||
out.indent();
|
out.indent();
|
||||||
|
|
||||||
annotateEncodedValue(out, reader);
|
annotateEncodedValue(dexFile, out, reader);
|
||||||
|
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String asString(@Nonnull DexReader reader) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
int valueArgType = reader.readUbyte();
|
int valueArgType = reader.readUbyte();
|
||||||
|
|
||||||
int valueArg = valueArgType >>> 5;
|
int valueArg = valueArgType >>> 5;
|
||||||
@ -157,29 +167,29 @@ public class EncodedValue {
|
|||||||
return String.format("%f", doubleValue);
|
return String.format("%f", doubleValue);
|
||||||
case ValueType.METHOD_TYPE:
|
case ValueType.METHOD_TYPE:
|
||||||
int protoIndex = reader.readSizedSmallUint(valueArg + 1);
|
int protoIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
return ProtoIdItem.getReferenceAnnotation(reader.dexBuf, protoIndex);
|
return ProtoIdItem.getReferenceAnnotation(dexFile, protoIndex);
|
||||||
case ValueType.STRING:
|
case ValueType.STRING:
|
||||||
int stringIndex = reader.readSizedSmallUint(valueArg + 1);
|
int stringIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
return StringIdItem.getReferenceAnnotation(reader.dexBuf, stringIndex, true);
|
return StringIdItem.getReferenceAnnotation(dexFile, stringIndex, true);
|
||||||
case ValueType.TYPE:
|
case ValueType.TYPE:
|
||||||
int typeIndex = reader.readSizedSmallUint(valueArg+1);
|
int typeIndex = reader.readSizedSmallUint(valueArg+1);
|
||||||
return TypeIdItem.getReferenceAnnotation(reader.dexBuf, typeIndex);
|
return TypeIdItem.getReferenceAnnotation(dexFile, typeIndex);
|
||||||
case ValueType.FIELD:
|
case ValueType.FIELD:
|
||||||
int fieldIndex = reader.readSizedSmallUint(valueArg+1);
|
int fieldIndex = reader.readSizedSmallUint(valueArg+1);
|
||||||
return FieldIdItem.getReferenceAnnotation(reader.dexBuf, fieldIndex);
|
return FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex);
|
||||||
case ValueType.METHOD:
|
case ValueType.METHOD:
|
||||||
int methodIndex = reader.readSizedSmallUint(valueArg+1);
|
int methodIndex = reader.readSizedSmallUint(valueArg+1);
|
||||||
return MethodIdItem.getReferenceAnnotation(reader.dexBuf, methodIndex);
|
return MethodIdItem.getReferenceAnnotation(dexFile, methodIndex);
|
||||||
case ValueType.ENUM:
|
case ValueType.ENUM:
|
||||||
fieldIndex = reader.readSizedSmallUint(valueArg+1);
|
fieldIndex = reader.readSizedSmallUint(valueArg+1);
|
||||||
return FieldIdItem.getReferenceAnnotation(reader.dexBuf, fieldIndex);
|
return FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex);
|
||||||
case ValueType.ARRAY:
|
case ValueType.ARRAY:
|
||||||
case ValueType.ANNOTATION:
|
case ValueType.ANNOTATION:
|
||||||
case ValueType.METHOD_HANDLE:
|
case ValueType.METHOD_HANDLE:
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
reader.setOffset(reader.getOffset() - 1);
|
reader.setOffset(reader.getOffset() - 1);
|
||||||
try {
|
try {
|
||||||
EncodedValueUtils.writeEncodedValue(writer, DexBackedEncodedValue.readFrom(reader));
|
EncodedValueUtils.writeEncodedValue(writer, DexBackedEncodedValue.readFrom(dexFile, reader));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
// Shouldn't happen with a StringWriter...
|
// Shouldn't happen with a StringWriter...
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
|
@ -54,13 +54,13 @@ public class FieldIdItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int classIndex = dexFile.readUshort(out.getCursor());
|
int classIndex = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
|
out.annotate(2, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
|
||||||
|
|
||||||
int typeIndex = dexFile.readUshort(out.getCursor());
|
int typeIndex = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, "return_type_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
|
out.annotate(2, "return_type_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
|
||||||
|
|
||||||
int nameIndex = dexFile.readSmallUint(out.getCursor());
|
int nameIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "name_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, nameIndex));
|
out.annotate(4, "name_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, nameIndex));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -69,13 +69,13 @@ public class FieldIdItem {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int fieldIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int fieldIndex) {
|
||||||
int fieldOffset = dexFile.getFieldSection().getOffset(fieldIndex);
|
int fieldOffset = dexFile.getFieldSection().getOffset(fieldIndex);
|
||||||
int classIndex = dexFile.readUshort(fieldOffset + CLASS_OFFSET);
|
int classIndex = dexFile.getBuffer().readUshort(fieldOffset + CLASS_OFFSET);
|
||||||
String classType = dexFile.getTypeSection().get(classIndex);
|
String classType = dexFile.getTypeSection().get(classIndex);
|
||||||
|
|
||||||
int typeIndex = dexFile.readUshort(fieldOffset + TYPE_OFFSET);
|
int typeIndex = dexFile.getBuffer().readUshort(fieldOffset + TYPE_OFFSET);
|
||||||
String fieldType = dexFile.getTypeSection().get(typeIndex);
|
String fieldType = dexFile.getTypeSection().get(typeIndex);
|
||||||
|
|
||||||
int nameIndex = dexFile.readSmallUint(fieldOffset + NAME_OFFSET);
|
int nameIndex = dexFile.getBuffer().readSmallUint(fieldOffset + NAME_OFFSET);
|
||||||
String fieldName = dexFile.getStringSection().get(nameIndex);
|
String fieldName = dexFile.getStringSection().get(nameIndex);
|
||||||
|
|
||||||
return String.format("%s->%s:%s", classType, fieldName, fieldType);
|
return String.format("%s->%s:%s", classType, fieldName, fieldType);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
package org.jf.dexlib2.dexbacked.raw;
|
package org.jf.dexlib2.dexbacked.raw;
|
||||||
|
|
||||||
import org.jf.dexlib2.VersionMap;
|
import org.jf.dexlib2.VersionMap;
|
||||||
import org.jf.dexlib2.dexbacked.BaseDexBuffer;
|
import org.jf.dexlib2.dexbacked.DexBuffer;
|
||||||
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
|
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
|
||||||
import org.jf.dexlib2.util.AnnotatedBytes;
|
import org.jf.dexlib2.util.AnnotatedBytes;
|
||||||
import org.jf.util.StringUtils;
|
import org.jf.util.StringUtils;
|
||||||
@ -90,67 +90,67 @@ public class HeaderItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getChecksum() {
|
public int getChecksum() {
|
||||||
return dexFile.readSmallUint(CHECKSUM_OFFSET);
|
return dexFile.getBuffer().readSmallUint(CHECKSUM_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull public byte[] getSignature() {
|
@Nonnull public byte[] getSignature() {
|
||||||
return dexFile.readByteRange(SIGNATURE_OFFSET, SIGNATURE_SIZE);
|
return dexFile.getBuffer().readByteRange(SIGNATURE_OFFSET, SIGNATURE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMapOffset() {
|
public int getMapOffset() {
|
||||||
return dexFile.readSmallUint(MAP_OFFSET);
|
return dexFile.getBuffer().readSmallUint(MAP_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeaderSize() {
|
public int getHeaderSize() {
|
||||||
return dexFile.readSmallUint(HEADER_SIZE_OFFSET);
|
return dexFile.getBuffer().readSmallUint(HEADER_SIZE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStringCount() {
|
public int getStringCount() {
|
||||||
return dexFile.readSmallUint(STRING_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(STRING_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStringOffset() {
|
public int getStringOffset() {
|
||||||
return dexFile.readSmallUint(STRING_START_OFFSET);
|
return dexFile.getBuffer().readSmallUint(STRING_START_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTypeCount() {
|
public int getTypeCount() {
|
||||||
return dexFile.readSmallUint(TYPE_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(TYPE_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTypeOffset() {
|
public int getTypeOffset() {
|
||||||
return dexFile.readSmallUint(TYPE_START_OFFSET);
|
return dexFile.getBuffer().readSmallUint(TYPE_START_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getProtoCount() {
|
public int getProtoCount() {
|
||||||
return dexFile.readSmallUint(PROTO_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(PROTO_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getProtoOffset() {
|
public int getProtoOffset() {
|
||||||
return dexFile.readSmallUint(PROTO_START_OFFSET);
|
return dexFile.getBuffer().readSmallUint(PROTO_START_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFieldCount() {
|
public int getFieldCount() {
|
||||||
return dexFile.readSmallUint(FIELD_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(FIELD_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFieldOffset() {
|
public int getFieldOffset() {
|
||||||
return dexFile.readSmallUint(FIELD_START_OFFSET);
|
return dexFile.getBuffer().readSmallUint(FIELD_START_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMethodCount() {
|
public int getMethodCount() {
|
||||||
return dexFile.readSmallUint(METHOD_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(METHOD_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMethodOffset() {
|
public int getMethodOffset() {
|
||||||
return dexFile.readSmallUint(METHOD_START_OFFSET);
|
return dexFile.getBuffer().readSmallUint(METHOD_START_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getClassCount() {
|
public int getClassCount() {
|
||||||
return dexFile.readSmallUint(CLASS_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(CLASS_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getClassOffset() {
|
public int getClassOffset() {
|
||||||
return dexFile.readSmallUint(CLASS_START_OFFSET);
|
return dexFile.getBuffer().readSmallUint(CLASS_START_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -167,45 +167,45 @@ public class HeaderItem {
|
|||||||
|
|
||||||
StringBuilder magicBuilder = new StringBuilder();
|
StringBuilder magicBuilder = new StringBuilder();
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
magicBuilder.append((char)dexFile.readUbyte(startOffset + i));
|
magicBuilder.append((char)dexFile.getBuffer().readUbyte(startOffset + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.annotate(8, "magic: %s", StringUtils.escapeString(magicBuilder.toString()));
|
out.annotate(8, "magic: %s", StringUtils.escapeString(magicBuilder.toString()));
|
||||||
out.annotate(4, "checksum");
|
out.annotate(4, "checksum");
|
||||||
out.annotate(20, "signature");
|
out.annotate(20, "signature");
|
||||||
out.annotate(4, "file_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "file_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
headerSize = dexFile.readInt(out.getCursor());
|
headerSize = dexFile.getBuffer().readInt(out.getCursor());
|
||||||
out.annotate(4, "header_size: %d", headerSize);
|
out.annotate(4, "header_size: %d", headerSize);
|
||||||
|
|
||||||
int endianTag = dexFile.readInt(out.getCursor());
|
int endianTag = dexFile.getBuffer().readInt(out.getCursor());
|
||||||
out.annotate(4, "endian_tag: 0x%x (%s)", endianTag, getEndianText(endianTag));
|
out.annotate(4, "endian_tag: 0x%x (%s)", endianTag, getEndianText(endianTag));
|
||||||
|
|
||||||
out.annotate(4, "link_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "link_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "link_offset: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "link_offset: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "map_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "map_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "string_ids_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "string_ids_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "string_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "string_ids_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "type_ids_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "type_ids_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "type_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "type_ids_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "proto_ids_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "proto_ids_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "proto_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "proto_ids_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "field_ids_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "field_ids_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "field_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "field_ids_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "method_ids_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "method_ids_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "method_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "method_ids_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "class_defs_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "class_defs_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "class_defs_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "class_defs_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
out.annotate(4, "data_size: %d", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "data_size: %d", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
out.annotate(4, "data_off: 0x%x", dexFile.readInt(out.getCursor()));
|
out.annotate(4, "data_off: 0x%x", dexFile.getBuffer().readInt(out.getCursor()));
|
||||||
|
|
||||||
if (headerSize > ITEM_SIZE) {
|
if (headerSize > ITEM_SIZE) {
|
||||||
out.annotateTo(headerSize, "header padding");
|
out.annotateTo(headerSize, "header padding");
|
||||||
@ -306,7 +306,7 @@ public class HeaderItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int getEndian(byte[] buf, int offset) {
|
public static int getEndian(byte[] buf, int offset) {
|
||||||
BaseDexBuffer bdb = new BaseDexBuffer(buf);
|
DexBuffer bdb = new DexBuffer(buf);
|
||||||
return bdb.readInt(offset + ENDIAN_TAG_OFFSET);
|
return bdb.readInt(offset + ENDIAN_TAG_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public class MapItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getType() {
|
public int getType() {
|
||||||
return dexFile.readUshort(offset + TYPE_OFFSET);
|
return dexFile.getBuffer().readUshort(offset + TYPE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -63,11 +63,11 @@ public class MapItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return dexFile.readSmallUint(offset + SIZE_OFFSET);
|
return dexFile.getBuffer().readSmallUint(offset + SIZE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOffset() {
|
public int getOffset() {
|
||||||
return dexFile.readSmallUint(offset + OFFSET_OFFSET);
|
return dexFile.getBuffer().readSmallUint(offset + OFFSET_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -79,21 +79,21 @@ public class MapItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int itemType = dexFile.readUshort(out.getCursor());
|
int itemType = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, "type = 0x%x: %s", itemType, ItemType.getItemTypeName(itemType));
|
out.annotate(2, "type = 0x%x: %s", itemType, ItemType.getItemTypeName(itemType));
|
||||||
|
|
||||||
out.annotate(2, "unused");
|
out.annotate(2, "unused");
|
||||||
|
|
||||||
int size = dexFile.readSmallUint(out.getCursor());
|
int size = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "size = %d", size);
|
out.annotate(4, "size = %d", size);
|
||||||
|
|
||||||
int offset = dexFile.readSmallUint(out.getCursor());
|
int offset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "offset = 0x%x", offset);
|
out.annotate(4, "offset = 0x%x", offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void annotateSection(@Nonnull AnnotatedBytes out) {
|
@Override public void annotateSection(@Nonnull AnnotatedBytes out) {
|
||||||
out.moveTo(sectionOffset);
|
out.moveTo(sectionOffset);
|
||||||
int mapItemCount = dexFile.readSmallUint(out.getCursor());
|
int mapItemCount = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "size = %d", mapItemCount);
|
out.annotate(4, "size = %d", mapItemCount);
|
||||||
|
|
||||||
super.annotateSectionInner(out, mapItemCount);
|
super.annotateSectionInner(out, mapItemCount);
|
||||||
|
@ -54,11 +54,11 @@ public class MethodHandleItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int methodHandleType = dexFile.readUshort(out.getCursor());
|
int methodHandleType = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, "type = %s", MethodHandleType.toString(methodHandleType));
|
out.annotate(2, "type = %s", MethodHandleType.toString(methodHandleType));
|
||||||
out.annotate(2, "unused");
|
out.annotate(2, "unused");
|
||||||
|
|
||||||
int fieldOrMethodId = dexFile.readUshort(out.getCursor());
|
int fieldOrMethodId = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
String fieldOrMethodDescriptor;
|
String fieldOrMethodDescriptor;
|
||||||
switch (methodHandleType) {
|
switch (methodHandleType) {
|
||||||
case MethodHandleType.STATIC_PUT:
|
case MethodHandleType.STATIC_PUT:
|
||||||
|
@ -54,13 +54,13 @@ public class MethodIdItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int classIndex = dexFile.readUshort(out.getCursor());
|
int classIndex = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
|
out.annotate(2, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
|
||||||
|
|
||||||
int protoIndex = dexFile.readUshort(out.getCursor());
|
int protoIndex = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, "proto_idx = %s", ProtoIdItem.getReferenceAnnotation(dexFile, protoIndex));
|
out.annotate(2, "proto_idx = %s", ProtoIdItem.getReferenceAnnotation(dexFile, protoIndex));
|
||||||
|
|
||||||
int nameIndex = dexFile.readSmallUint(out.getCursor());
|
int nameIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "name_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, nameIndex));
|
out.annotate(4, "name_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, nameIndex));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -69,13 +69,13 @@ public class MethodIdItem {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int methodIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int methodIndex) {
|
||||||
int methodOffset = dexFile.getMethodSection().getOffset(methodIndex);
|
int methodOffset = dexFile.getMethodSection().getOffset(methodIndex);
|
||||||
int classIndex = dexFile.readUshort(methodOffset + CLASS_OFFSET);
|
int classIndex = dexFile.getBuffer().readUshort(methodOffset + CLASS_OFFSET);
|
||||||
String classType = dexFile.getTypeSection().get(classIndex);
|
String classType = dexFile.getTypeSection().get(classIndex);
|
||||||
|
|
||||||
int protoIndex = dexFile.readUshort(methodOffset + PROTO_OFFSET);
|
int protoIndex = dexFile.getBuffer().readUshort(methodOffset + PROTO_OFFSET);
|
||||||
String protoString = ProtoIdItem.asString(dexFile, protoIndex);
|
String protoString = ProtoIdItem.asString(dexFile, protoIndex);
|
||||||
|
|
||||||
int nameIndex = dexFile.readSmallUint(methodOffset + NAME_OFFSET);
|
int nameIndex = dexFile.getBuffer().readSmallUint(methodOffset + NAME_OFFSET);
|
||||||
String methodName = dexFile.getStringSection().get(nameIndex);
|
String methodName = dexFile.getStringSection().get(nameIndex);
|
||||||
|
|
||||||
return String.format("%s->%s%s", classType, methodName, protoString);
|
return String.format("%s->%s%s", classType, methodName, protoString);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.dexbacked.raw;
|
package org.jf.dexlib2.dexbacked.raw;
|
||||||
|
|
||||||
import org.jf.dexlib2.dexbacked.BaseDexBuffer;
|
import org.jf.dexlib2.dexbacked.DexBuffer;
|
||||||
|
|
||||||
public class OdexHeaderItem {
|
public class OdexHeaderItem {
|
||||||
public static final int ITEM_SIZE = 40;
|
public static final int ITEM_SIZE = 40;
|
||||||
@ -112,12 +112,12 @@ public class OdexHeaderItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int getDexOffset(byte[] buf) {
|
public static int getDexOffset(byte[] buf) {
|
||||||
BaseDexBuffer bdb = new BaseDexBuffer(buf);
|
DexBuffer bdb = new DexBuffer(buf);
|
||||||
return bdb.readSmallUint(DEX_OFFSET);
|
return bdb.readSmallUint(DEX_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getDependenciesOffset(byte[] buf) {
|
public static int getDependenciesOffset(byte[] buf) {
|
||||||
BaseDexBuffer bdb = new BaseDexBuffer(buf);
|
DexBuffer bdb = new DexBuffer(buf);
|
||||||
return bdb.readSmallUint(DEPENDENCIES_OFFSET);
|
return bdb.readSmallUint(DEPENDENCIES_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,13 +54,13 @@ public class ProtoIdItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int shortyIndex = dexFile.readSmallUint(out.getCursor());
|
int shortyIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "shorty_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, shortyIndex));
|
out.annotate(4, "shorty_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, shortyIndex));
|
||||||
|
|
||||||
int returnTypeIndex = dexFile.readSmallUint(out.getCursor());
|
int returnTypeIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "return_type_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, returnTypeIndex));
|
out.annotate(4, "return_type_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, returnTypeIndex));
|
||||||
|
|
||||||
int parametersOffset = dexFile.readSmallUint(out.getCursor());
|
int parametersOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "parameters_off = %s", TypeListItem.getReferenceAnnotation(dexFile, parametersOffset));
|
out.annotate(4, "parameters_off = %s", TypeListItem.getReferenceAnnotation(dexFile, parametersOffset));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -84,11 +84,11 @@ public class ProtoIdItem {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("(");
|
sb.append("(");
|
||||||
|
|
||||||
int parametersOffset = dexFile.readSmallUint(offset + PARAMETERS_OFFSET);
|
int parametersOffset = dexFile.getBuffer().readSmallUint(offset + PARAMETERS_OFFSET);
|
||||||
sb.append(TypeListItem.asString(dexFile, parametersOffset));
|
sb.append(TypeListItem.asString(dexFile, parametersOffset));
|
||||||
sb.append(")");
|
sb.append(")");
|
||||||
|
|
||||||
int returnTypeIndex = dexFile.readSmallUint(offset + RETURN_TYPE_OFFSET);
|
int returnTypeIndex = dexFile.getBuffer().readSmallUint(offset + RETURN_TYPE_OFFSET);
|
||||||
String returnType = dexFile.getTypeSection().get(returnTypeIndex);
|
String returnType = dexFile.getTypeSection().get(returnTypeIndex);
|
||||||
sb.append(returnType);
|
sb.append(returnType);
|
||||||
|
|
||||||
|
@ -32,20 +32,18 @@
|
|||||||
package org.jf.dexlib2.dexbacked.raw;
|
package org.jf.dexlib2.dexbacked.raw;
|
||||||
|
|
||||||
import org.jf.dexlib2.Opcodes;
|
import org.jf.dexlib2.Opcodes;
|
||||||
import org.jf.dexlib2.dexbacked.BaseDexBuffer;
|
|
||||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||||
import org.jf.dexlib2.util.AnnotatedBytes;
|
import org.jf.dexlib2.util.AnnotatedBytes;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class RawDexFile extends DexBackedDexFile {
|
public class RawDexFile extends DexBackedDexFile {
|
||||||
@Nonnull public final HeaderItem headerItem;
|
@Nonnull public final HeaderItem headerItem;
|
||||||
|
|
||||||
public RawDexFile(@Nonnull Opcodes opcodes, @Nonnull BaseDexBuffer buf) {
|
public RawDexFile(@Nonnull Opcodes opcodes, @Nonnull DexBackedDexFile dexFile) {
|
||||||
super(opcodes, buf);
|
super(opcodes, dexFile.getBuffer());
|
||||||
this.headerItem = new HeaderItem(this);
|
this.headerItem = new HeaderItem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,13 +52,8 @@ public class RawDexFile extends DexBackedDexFile {
|
|||||||
this.headerItem = new HeaderItem(this);
|
this.headerItem = new HeaderItem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public byte[] readByteRange(int start, int length) {
|
|
||||||
return Arrays.copyOfRange(getBuf(), getBaseOffset() + start, getBaseOffset() + start + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeAnnotations(@Nonnull Writer out, @Nonnull AnnotatedBytes annotatedBytes) throws IOException {
|
public void writeAnnotations(@Nonnull Writer out, @Nonnull AnnotatedBytes annotatedBytes) throws IOException {
|
||||||
// TODO: need to pass in the offset
|
// TODO: need to pass in the offset
|
||||||
annotatedBytes.writeAnnotations(out, getBuf());
|
annotatedBytes.writeAnnotations(out, getBuffer().getBuf());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public class StringDataItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
DexReader reader = dexFile.readerAt(out.getCursor());
|
DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
|
||||||
int utf16Length = reader.readSmallUleb128();
|
int utf16Length = reader.readSmallUleb128();
|
||||||
out.annotateTo(reader.getOffset(), "utf16_size = %d", utf16Length);
|
out.annotateTo(reader.getOffset(), "utf16_size = %d", utf16Length);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public class StringIdItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int stringDataOffset = dexFile.readSmallUint(out.getCursor());
|
int stringDataOffset = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
try {
|
try {
|
||||||
String stringValue = dexFile.getStringSection().get(itemIndex);
|
String stringValue = dexFile.getStringSection().get(itemIndex);
|
||||||
out.annotate(4, "string_data_item[0x%x]: \"%s\"", stringDataOffset,
|
out.annotate(4, "string_data_item[0x%x]: \"%s\"", stringDataOffset,
|
||||||
@ -91,7 +91,6 @@ public class StringIdItem {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static String getOptionalReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int stringIndex) {
|
public static String getOptionalReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int stringIndex) {
|
||||||
return getOptionalReferenceAnnotation(dexFile, stringIndex, false);
|
return getOptionalReferenceAnnotation(dexFile, stringIndex, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getOptionalReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int stringIndex,
|
public static String getOptionalReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int stringIndex,
|
||||||
|
@ -50,7 +50,7 @@ public class TypeIdItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int stringIndex = dexFile.readSmallUint(out.getCursor());
|
int stringIndex = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, StringIdItem.getReferenceAnnotation(dexFile, stringIndex));
|
out.annotate(4, StringIdItem.getReferenceAnnotation(dexFile, stringIndex));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -51,11 +51,11 @@ public class TypeListItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int size = dexFile.readSmallUint(out.getCursor());
|
int size = dexFile.getBuffer().readSmallUint(out.getCursor());
|
||||||
out.annotate(4, "size: %d", size);
|
out.annotate(4, "size: %d", size);
|
||||||
|
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
int typeIndex = dexFile.readUshort(out.getCursor());
|
int typeIndex = dexFile.getBuffer().readUshort(out.getCursor());
|
||||||
out.annotate(2, TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
|
out.annotate(2, TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,9 +89,9 @@ public class TypeListItem {
|
|||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
int size = dexFile.readSmallUint(typeListOffset);
|
int size = dexFile.getBuffer().readSmallUint(typeListOffset);
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
int typeIndex = dexFile.readUshort(typeListOffset + 4 + i*2);
|
int typeIndex = dexFile.getBuffer().readUshort(typeListOffset + 4 + i*2);
|
||||||
String type = dexFile.getTypeSection().get(typeIndex);
|
String type = dexFile.getTypeSection().get(typeIndex);
|
||||||
sb.append(type);
|
sb.append(type);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ public class DexBackedCallSiteReference extends BaseCallSiteReference {
|
|||||||
|
|
||||||
private int getCallSiteOffset() {
|
private int getCallSiteOffset() {
|
||||||
if (callSiteOffset < 0) {
|
if (callSiteOffset < 0) {
|
||||||
callSiteOffset = dexFile.readSmallUint(callSiteIdOffset);
|
callSiteOffset = dexFile.getBuffer().readSmallUint(callSiteIdOffset);
|
||||||
}
|
}
|
||||||
return callSiteOffset;
|
return callSiteOffset;
|
||||||
}
|
}
|
||||||
|
@ -50,21 +50,22 @@ public class DexBackedFieldReference extends BaseFieldReference {
|
|||||||
@Override
|
@Override
|
||||||
public String getDefiningClass() {
|
public String getDefiningClass() {
|
||||||
return dexFile.getTypeSection().get(
|
return dexFile.getTypeSection().get(
|
||||||
dexFile.readUshort(dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.CLASS_OFFSET));
|
dexFile.getBuffer().readUshort(
|
||||||
|
dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.CLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getStringSection().get(dexFile.readSmallUint(dexFile.getFieldSection().getOffset(fieldIndex) +
|
return dexFile.getStringSection().get(dexFile.getBuffer().readSmallUint(
|
||||||
FieldIdItem.NAME_OFFSET));
|
dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return dexFile.getTypeSection().get(
|
return dexFile.getTypeSection().get(dexFile.getBuffer().readUshort(
|
||||||
dexFile.readUshort(dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.TYPE_OFFSET));
|
dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,13 +53,13 @@ public class DexBackedMethodHandleReference extends BaseMethodHandleReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMethodHandleType() {
|
public int getMethodHandleType() {
|
||||||
return dexFile.readUshort(methodHandleOffset + MethodHandleItem.METHOD_HANDLE_TYPE_OFFSET);
|
return dexFile.getBuffer().readUshort(methodHandleOffset + MethodHandleItem.METHOD_HANDLE_TYPE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Reference getMemberReference() {
|
public Reference getMemberReference() {
|
||||||
int memberIndex = dexFile.readUshort(methodHandleOffset + MethodHandleItem.MEMBER_ID_OFFSET);
|
int memberIndex = dexFile.getBuffer().readUshort(methodHandleOffset + MethodHandleItem.MEMBER_ID_OFFSET);
|
||||||
switch (getMethodHandleType()) {
|
switch (getMethodHandleType()) {
|
||||||
case MethodHandleType.STATIC_PUT:
|
case MethodHandleType.STATIC_PUT:
|
||||||
case MethodHandleType.STATIC_GET:
|
case MethodHandleType.STATIC_GET:
|
||||||
|
@ -53,16 +53,16 @@ public class DexBackedMethodProtoReference extends BaseMethodProtoReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<String> getParameterTypes() {
|
public List<String> getParameterTypes() {
|
||||||
final int parametersOffset = dexFile.readSmallUint(dexFile.getProtoSection().getOffset(protoIndex) +
|
final int parametersOffset = dexFile.getBuffer().readSmallUint(dexFile.getProtoSection().getOffset(protoIndex) +
|
||||||
ProtoIdItem.PARAMETERS_OFFSET);
|
ProtoIdItem.PARAMETERS_OFFSET);
|
||||||
if (parametersOffset > 0) {
|
if (parametersOffset > 0) {
|
||||||
final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
final int parameterCount = dexFile.getBuffer().readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
||||||
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
||||||
return new FixedSizeList<String>() {
|
return new FixedSizeList<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String readItem(final int index) {
|
public String readItem(final int index) {
|
||||||
return dexFile.getTypeSection().get(dexFile.readUshort(paramListStart + 2*index));
|
return dexFile.getTypeSection().get(dexFile.getBuffer().readUshort(paramListStart + 2*index));
|
||||||
}
|
}
|
||||||
@Override public int size() { return parameterCount; }
|
@Override public int size() { return parameterCount; }
|
||||||
};
|
};
|
||||||
@ -73,8 +73,8 @@ public class DexBackedMethodProtoReference extends BaseMethodProtoReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getReturnType() {
|
public String getReturnType() {
|
||||||
return dexFile.getTypeSection().get(dexFile.readSmallUint(dexFile.getProtoSection().getOffset(protoIndex) +
|
return dexFile.getTypeSection().get(dexFile.getBuffer().readSmallUint(
|
||||||
ProtoIdItem.RETURN_TYPE_OFFSET));
|
dexFile.getProtoSection().getOffset(protoIndex) + ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,30 +55,31 @@ public class DexBackedMethodReference extends BaseMethodReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getDefiningClass() {
|
public String getDefiningClass() {
|
||||||
return dexFile.getTypeSection().get(dexFile.readUshort(dexFile.getMethodSection().getOffset(methodIndex) +
|
return dexFile.getTypeSection().get(dexFile.getBuffer().readUshort(
|
||||||
MethodIdItem.CLASS_OFFSET));
|
dexFile.getMethodSection().getOffset(methodIndex) + MethodIdItem.CLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getStringSection().get(dexFile.readSmallUint(dexFile.getMethodSection().getOffset(methodIndex) +
|
return dexFile.getStringSection().get(dexFile.getBuffer().readSmallUint(
|
||||||
MethodIdItem.NAME_OFFSET));
|
dexFile.getMethodSection().getOffset(methodIndex) + MethodIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<String> getParameterTypes() {
|
public List<String> getParameterTypes() {
|
||||||
int protoIdItemOffset = getProtoIdItemOffset();
|
int protoIdItemOffset = getProtoIdItemOffset();
|
||||||
final int parametersOffset = dexFile.readSmallUint(protoIdItemOffset + ProtoIdItem.PARAMETERS_OFFSET);
|
final int parametersOffset = dexFile.getBuffer().readSmallUint(
|
||||||
|
protoIdItemOffset + ProtoIdItem.PARAMETERS_OFFSET);
|
||||||
if (parametersOffset > 0) {
|
if (parametersOffset > 0) {
|
||||||
final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
final int parameterCount = dexFile.getBuffer().readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
||||||
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
||||||
return new FixedSizeList<String>() {
|
return new FixedSizeList<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String readItem(final int index) {
|
public String readItem(final int index) {
|
||||||
return dexFile.getTypeSection().get(dexFile.readUshort(paramListStart + 2*index));
|
return dexFile.getTypeSection().get(dexFile.getBuffer().readUshort(paramListStart + 2*index));
|
||||||
}
|
}
|
||||||
@Override public int size() { return parameterCount; }
|
@Override public int size() { return parameterCount; }
|
||||||
};
|
};
|
||||||
@ -90,13 +91,14 @@ public class DexBackedMethodReference extends BaseMethodReference {
|
|||||||
@Override
|
@Override
|
||||||
public String getReturnType() {
|
public String getReturnType() {
|
||||||
int protoIdItemOffset = getProtoIdItemOffset();
|
int protoIdItemOffset = getProtoIdItemOffset();
|
||||||
return dexFile.getTypeSection().get(dexFile.readSmallUint(protoIdItemOffset + ProtoIdItem.RETURN_TYPE_OFFSET));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.getBuffer().readSmallUint(protoIdItemOffset + ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getProtoIdItemOffset() {
|
private int getProtoIdItemOffset() {
|
||||||
if (protoIdItemOffset == 0) {
|
if (protoIdItemOffset == 0) {
|
||||||
protoIdItemOffset = dexFile.getProtoSection().getOffset(
|
protoIdItemOffset = dexFile.getProtoSection().getOffset(dexFile.getBuffer().readUshort(
|
||||||
dexFile.readUshort(dexFile.getMethodSection().getOffset(methodIndex) + MethodIdItem.PROTO_OFFSET));
|
dexFile.getMethodSection().getOffset(methodIndex) + MethodIdItem.PROTO_OFFSET));
|
||||||
}
|
}
|
||||||
return protoIdItemOffset;
|
return protoIdItemOffset;
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,8 @@ public class DexBackedStringReference extends BaseStringReference {
|
|||||||
int size = StringIdItem.ITEM_SIZE; //uint for string_data_off
|
int size = StringIdItem.ITEM_SIZE; //uint for string_data_off
|
||||||
//add the string data length:
|
//add the string data length:
|
||||||
int stringOffset = dexFile.getStringSection().getOffset(stringIndex);
|
int stringOffset = dexFile.getStringSection().getOffset(stringIndex);
|
||||||
int stringDataOffset = dexFile.readSmallUint(stringOffset);
|
int stringDataOffset = dexFile.getBuffer().readSmallUint(stringOffset);
|
||||||
DexReader reader = dexFile.readerAt(stringDataOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(stringDataOffset);
|
||||||
size += reader.peekSmallUleb128Size();
|
size += reader.peekSmallUleb128Size();
|
||||||
int utf16Length = reader.readSmallUleb128();
|
int utf16Length = reader.readSmallUleb128();
|
||||||
//and string data itself:
|
//and string data itself:
|
||||||
|
@ -99,12 +99,12 @@ public abstract class AnnotationsDirectory {
|
|||||||
public static Set<? extends DexBackedAnnotation> getAnnotations(@Nonnull final DexBackedDexFile dexFile,
|
public static Set<? extends DexBackedAnnotation> getAnnotations(@Nonnull final DexBackedDexFile dexFile,
|
||||||
final int annotationSetOffset) {
|
final int annotationSetOffset) {
|
||||||
if (annotationSetOffset != 0) {
|
if (annotationSetOffset != 0) {
|
||||||
final int size = dexFile.readSmallUint(annotationSetOffset);
|
final int size = dexFile.getBuffer().readSmallUint(annotationSetOffset);
|
||||||
return new FixedSizeSet<DexBackedAnnotation>() {
|
return new FixedSizeSet<DexBackedAnnotation>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public DexBackedAnnotation readItem(int index) {
|
public DexBackedAnnotation readItem(int index) {
|
||||||
int annotationOffset = dexFile.readSmallUint(annotationSetOffset + 4 + (4*index));
|
int annotationOffset = dexFile.getBuffer().readSmallUint(annotationSetOffset + 4 + (4*index));
|
||||||
return new DexBackedAnnotation(dexFile, annotationOffset);
|
return new DexBackedAnnotation(dexFile, annotationOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,13 +119,14 @@ public abstract class AnnotationsDirectory {
|
|||||||
public static List<Set<? extends DexBackedAnnotation>> getParameterAnnotations(
|
public static List<Set<? extends DexBackedAnnotation>> getParameterAnnotations(
|
||||||
@Nonnull final DexBackedDexFile dexFile, final int annotationSetListOffset) {
|
@Nonnull final DexBackedDexFile dexFile, final int annotationSetListOffset) {
|
||||||
if (annotationSetListOffset > 0) {
|
if (annotationSetListOffset > 0) {
|
||||||
final int size = dexFile.readSmallUint(annotationSetListOffset);
|
final int size = dexFile.getBuffer().readSmallUint(annotationSetListOffset);
|
||||||
|
|
||||||
return new FixedSizeList<Set<? extends DexBackedAnnotation>>() {
|
return new FixedSizeList<Set<? extends DexBackedAnnotation>>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends DexBackedAnnotation> readItem(int index) {
|
public Set<? extends DexBackedAnnotation> readItem(int index) {
|
||||||
int annotationSetOffset = dexFile.readSmallUint(annotationSetListOffset + 4 + index * 4);
|
int annotationSetOffset = dexFile.getBuffer().readSmallUint(
|
||||||
|
annotationSetListOffset + 4 + index * 4);
|
||||||
return getAnnotations(dexFile, annotationSetOffset);
|
return getAnnotations(dexFile, annotationSetOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,20 +157,20 @@ public abstract class AnnotationsDirectory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getFieldAnnotationCount() {
|
public int getFieldAnnotationCount() {
|
||||||
return dexFile.readSmallUint(directoryOffset + FIELD_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(directoryOffset + FIELD_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMethodAnnotationCount() {
|
public int getMethodAnnotationCount() {
|
||||||
return dexFile.readSmallUint(directoryOffset + METHOD_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(directoryOffset + METHOD_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getParameterAnnotationCount() {
|
public int getParameterAnnotationCount() {
|
||||||
return dexFile.readSmallUint(directoryOffset + PARAMETER_COUNT_OFFSET);
|
return dexFile.getBuffer().readSmallUint(directoryOffset + PARAMETER_COUNT_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Set<? extends DexBackedAnnotation> getClassAnnotations() {
|
public Set<? extends DexBackedAnnotation> getClassAnnotations() {
|
||||||
return getAnnotations(dexFile, dexFile.readSmallUint(directoryOffset));
|
return getAnnotations(dexFile, dexFile.getBuffer().readSmallUint(directoryOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -216,24 +217,24 @@ public abstract class AnnotationsDirectory {
|
|||||||
public AnnotationIteratorImpl(int startOffset, int size) {
|
public AnnotationIteratorImpl(int startOffset, int size) {
|
||||||
this.startOffset = startOffset;
|
this.startOffset = startOffset;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.currentItemIndex = dexFile.readSmallUint(startOffset);
|
this.currentItemIndex = dexFile.getBuffer().readSmallUint(startOffset);
|
||||||
this.currentIndex = 0;
|
this.currentIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int seekTo(int itemIndex) {
|
public int seekTo(int itemIndex) {
|
||||||
while (currentItemIndex < itemIndex && (currentIndex+1) < size) {
|
while (currentItemIndex < itemIndex && (currentIndex+1) < size) {
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
currentItemIndex = dexFile.readSmallUint(startOffset + (currentIndex*8));
|
currentItemIndex = dexFile.getBuffer().readSmallUint(startOffset + (currentIndex*8));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentItemIndex == itemIndex) {
|
if (currentItemIndex == itemIndex) {
|
||||||
return dexFile.readSmallUint(startOffset + (currentIndex*8)+4);
|
return dexFile.getBuffer().readSmallUint(startOffset + (currentIndex*8)+4);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
this.currentItemIndex = dexFile.readSmallUint(startOffset);
|
this.currentItemIndex = dexFile.getBuffer().readSmallUint(startOffset);
|
||||||
this.currentIndex = 0;
|
this.currentIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Iterator<DebugItem> iterator() {
|
public Iterator<DebugItem> iterator() {
|
||||||
DexReader reader = dexFile.readerAt(debugInfoOffset);
|
DexReader reader = dexFile.getBuffer().readerAt(debugInfoOffset);
|
||||||
final int lineNumberStart = reader.readBigUleb128();
|
final int lineNumberStart = reader.readBigUleb128();
|
||||||
int registerCount = methodImpl.getRegisterCount();
|
int registerCount = methodImpl.getRegisterCount();
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
|
|||||||
@Override
|
@Override
|
||||||
public VariableSizeIterator<String> getParameterNames(@Nullable DexReader reader) {
|
public VariableSizeIterator<String> getParameterNames(@Nullable DexReader reader) {
|
||||||
if (reader == null) {
|
if (reader == null) {
|
||||||
reader = dexFile.readerAt(debugInfoOffset);
|
reader = dexFile.getBuffer().readerAt(debugInfoOffset);
|
||||||
reader.skipUleb128();
|
reader.skipUleb128();
|
||||||
}
|
}
|
||||||
//TODO: make sure dalvik doesn't allow more parameter names than we have parameters
|
//TODO: make sure dalvik doesn't allow more parameter names than we have parameters
|
||||||
|
@ -62,11 +62,13 @@ public abstract class EncodedArrayItemIterator {
|
|||||||
|
|
||||||
private static class EncodedArrayItemIteratorImpl extends EncodedArrayItemIterator {
|
private static class EncodedArrayItemIteratorImpl extends EncodedArrayItemIterator {
|
||||||
@Nonnull private final DexReader reader;
|
@Nonnull private final DexReader reader;
|
||||||
|
@Nonnull private final DexBackedDexFile dexFile;
|
||||||
private final int size;
|
private final int size;
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
|
|
||||||
public EncodedArrayItemIteratorImpl(@Nonnull DexBackedDexFile dexFile, int offset) {
|
public EncodedArrayItemIteratorImpl(@Nonnull DexBackedDexFile dexFile, int offset) {
|
||||||
this.reader = dexFile.readerAt(offset);
|
this.dexFile = dexFile;
|
||||||
|
this.reader = dexFile.getBuffer().readerAt(offset);
|
||||||
this.size = reader.readSmallUleb128();
|
this.size = reader.readSmallUleb128();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ public abstract class EncodedArrayItemIterator {
|
|||||||
public EncodedValue getNextOrNull() {
|
public EncodedValue getNextOrNull() {
|
||||||
if (index < size) {
|
if (index < size) {
|
||||||
index++;
|
index++;
|
||||||
return DexBackedEncodedValue.readFrom(reader);
|
return DexBackedEncodedValue.readFrom(dexFile, reader);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public abstract class VariableSizeIterator<T> implements Iterator<T> {
|
|||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
protected VariableSizeIterator(@Nonnull DexBackedDexFile dexFile, int offset, int size) {
|
protected VariableSizeIterator(@Nonnull DexBackedDexFile dexFile, int offset, int size) {
|
||||||
this.reader = dexFile.readerAt(offset);
|
this.reader = dexFile.getBuffer().readerAt(offset);
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public abstract class VariableSizeListIterator<T> implements ListIterator<T> {
|
|||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
protected VariableSizeListIterator(@Nonnull DexBackedDexFile dexFile, int offset, int size) {
|
protected VariableSizeListIterator(@Nonnull DexBackedDexFile dexFile, int offset, int size) {
|
||||||
this.reader = dexFile.readerAt(offset);
|
this.reader = dexFile.getBuffer().readerAt(offset);
|
||||||
this.startOffset = offset;
|
this.startOffset = offset;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public abstract class VariableSizeLookaheadIterator<T> extends AbstractIterator<
|
|||||||
@Nonnull private final DexReader reader;
|
@Nonnull private final DexReader reader;
|
||||||
|
|
||||||
protected VariableSizeLookaheadIterator(@Nonnull DexBackedDexFile dexFile, int offset) {
|
protected VariableSizeLookaheadIterator(@Nonnull DexBackedDexFile dexFile, int offset) {
|
||||||
this.reader = dexFile.readerAt(offset);
|
this.reader = dexFile.getBuffer().readerAt(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,8 +47,8 @@ public class DexBackedAnnotationEncodedValue extends BaseAnnotationEncodedValue
|
|||||||
private final int elementCount;
|
private final int elementCount;
|
||||||
private final int elementsOffset;
|
private final int elementsOffset;
|
||||||
|
|
||||||
public DexBackedAnnotationEncodedValue(@Nonnull DexReader reader) {
|
public DexBackedAnnotationEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.type = dexFile.getTypeSection().get(reader.readSmallUleb128());
|
this.type = dexFile.getTypeSection().get(reader.readSmallUleb128());
|
||||||
this.elementCount = reader.readSmallUleb128();
|
this.elementCount = reader.readSmallUleb128();
|
||||||
this.elementsOffset = reader.getOffset();
|
this.elementsOffset = reader.getOffset();
|
||||||
@ -77,7 +77,7 @@ public class DexBackedAnnotationEncodedValue extends BaseAnnotationEncodedValue
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader dexReader, int index) {
|
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader dexReader, int index) {
|
||||||
return new DexBackedAnnotationElement(dexReader);
|
return new DexBackedAnnotationElement(dexFile, dexReader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@ public class DexBackedArrayEncodedValue extends BaseArrayEncodedValue implements
|
|||||||
private final int elementCount;
|
private final int elementCount;
|
||||||
private final int encodedArrayOffset;
|
private final int encodedArrayOffset;
|
||||||
|
|
||||||
public DexBackedArrayEncodedValue(@Nonnull DexReader reader) {
|
public DexBackedArrayEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.elementCount = reader.readSmallUleb128();
|
this.elementCount = reader.readSmallUleb128();
|
||||||
this.encodedArrayOffset = reader.getOffset();
|
this.encodedArrayOffset = reader.getOffset();
|
||||||
skipElementsFrom(reader, elementCount);
|
skipElementsFrom(reader, elementCount);
|
||||||
@ -71,7 +71,7 @@ public class DexBackedArrayEncodedValue extends BaseArrayEncodedValue implements
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected EncodedValue readNextItem(@Nonnull DexReader dexReader, int index) {
|
protected EncodedValue readNextItem(@Nonnull DexReader dexReader, int index) {
|
||||||
return DexBackedEncodedValue.readFrom(dexReader);
|
return DexBackedEncodedValue.readFrom(dexFile, dexReader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
package org.jf.dexlib2.dexbacked.value;
|
package org.jf.dexlib2.dexbacked.value;
|
||||||
|
|
||||||
import org.jf.dexlib2.ValueType;
|
import org.jf.dexlib2.ValueType;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||||
import org.jf.dexlib2.dexbacked.DexReader;
|
import org.jf.dexlib2.dexbacked.DexReader;
|
||||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||||
import org.jf.dexlib2.immutable.value.*;
|
import org.jf.dexlib2.immutable.value.*;
|
||||||
@ -42,7 +43,7 @@ import javax.annotation.Nonnull;
|
|||||||
|
|
||||||
public abstract class DexBackedEncodedValue {
|
public abstract class DexBackedEncodedValue {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static EncodedValue readFrom(@Nonnull DexReader reader) {
|
public static EncodedValue readFrom(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader) {
|
||||||
int startOffset = reader.getOffset();
|
int startOffset = reader.getOffset();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -76,25 +77,25 @@ public abstract class DexBackedEncodedValue {
|
|||||||
reader.readSizedRightExtendedLong(valueArg + 1)));
|
reader.readSizedRightExtendedLong(valueArg + 1)));
|
||||||
case ValueType.STRING:
|
case ValueType.STRING:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedStringEncodedValue(reader, valueArg);
|
return new DexBackedStringEncodedValue(dexFile, reader, valueArg);
|
||||||
case ValueType.TYPE:
|
case ValueType.TYPE:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedTypeEncodedValue(reader, valueArg);
|
return new DexBackedTypeEncodedValue(dexFile, reader, valueArg);
|
||||||
case ValueType.FIELD:
|
case ValueType.FIELD:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedFieldEncodedValue(reader, valueArg);
|
return new DexBackedFieldEncodedValue(dexFile, reader, valueArg);
|
||||||
case ValueType.METHOD:
|
case ValueType.METHOD:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedMethodEncodedValue(reader, valueArg);
|
return new DexBackedMethodEncodedValue(dexFile, reader, valueArg);
|
||||||
case ValueType.ENUM:
|
case ValueType.ENUM:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedEnumEncodedValue(reader, valueArg);
|
return new DexBackedEnumEncodedValue(dexFile, reader, valueArg);
|
||||||
case ValueType.ARRAY:
|
case ValueType.ARRAY:
|
||||||
Preconditions.checkValueArg(valueArg, 0);
|
Preconditions.checkValueArg(valueArg, 0);
|
||||||
return new DexBackedArrayEncodedValue(reader);
|
return new DexBackedArrayEncodedValue(dexFile, reader);
|
||||||
case ValueType.ANNOTATION:
|
case ValueType.ANNOTATION:
|
||||||
Preconditions.checkValueArg(valueArg, 0);
|
Preconditions.checkValueArg(valueArg, 0);
|
||||||
return new DexBackedAnnotationEncodedValue(reader);
|
return new DexBackedAnnotationEncodedValue(dexFile, reader);
|
||||||
case ValueType.NULL:
|
case ValueType.NULL:
|
||||||
Preconditions.checkValueArg(valueArg, 0);
|
Preconditions.checkValueArg(valueArg, 0);
|
||||||
return ImmutableNullEncodedValue.INSTANCE;
|
return ImmutableNullEncodedValue.INSTANCE;
|
||||||
@ -103,10 +104,10 @@ public abstract class DexBackedEncodedValue {
|
|||||||
return ImmutableBooleanEncodedValue.forBoolean(valueArg == 1);
|
return ImmutableBooleanEncodedValue.forBoolean(valueArg == 1);
|
||||||
case ValueType.METHOD_HANDLE:
|
case ValueType.METHOD_HANDLE:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedMethodHandleEncodedValue(reader, valueArg);
|
return new DexBackedMethodHandleEncodedValue(dexFile, reader, valueArg);
|
||||||
case ValueType.METHOD_TYPE:
|
case ValueType.METHOD_TYPE:
|
||||||
Preconditions.checkValueArg(valueArg, 3);
|
Preconditions.checkValueArg(valueArg, 3);
|
||||||
return new DexBackedMethodTypeEncodedValue(reader, valueArg);
|
return new DexBackedMethodTypeEncodedValue(dexFile, reader, valueArg);
|
||||||
default:
|
default:
|
||||||
throw new ExceptionWithContext("Invalid encoded_value type: 0x%x", valueType);
|
throw new ExceptionWithContext("Invalid encoded_value type: 0x%x", valueType);
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,8 @@ public class DexBackedEnumEncodedValue extends BaseEnumEncodedValue {
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int fieldIndex;
|
private final int fieldIndex;
|
||||||
|
|
||||||
public DexBackedEnumEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedEnumEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
fieldIndex = reader.readSizedSmallUint(valueArg + 1);
|
fieldIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ public class DexBackedFieldEncodedValue extends BaseFieldEncodedValue {
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int fieldIndex;
|
private final int fieldIndex;
|
||||||
|
|
||||||
public DexBackedFieldEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedFieldEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
fieldIndex = reader.readSizedSmallUint(valueArg + 1);
|
fieldIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ public class DexBackedMethodEncodedValue extends BaseMethodEncodedValue {
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int methodIndex;
|
private final int methodIndex;
|
||||||
|
|
||||||
public DexBackedMethodEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedMethodEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
methodIndex = reader.readSizedSmallUint(valueArg + 1);
|
methodIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,9 @@ public class DexBackedMethodHandleEncodedValue extends BaseMethodHandleEncodedVa
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int methodHandleIndex;
|
private final int methodHandleIndex;
|
||||||
|
|
||||||
public DexBackedMethodHandleEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedMethodHandleEncodedValue(
|
||||||
this.dexFile = reader.dexBuf;
|
@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
|
this.dexFile = dexFile;
|
||||||
this.methodHandleIndex = reader.readSizedSmallUint(valueArg + 1);
|
this.methodHandleIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ public class DexBackedMethodTypeEncodedValue extends BaseMethodTypeEncodedValue
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int methodProtoIndex;
|
private final int methodProtoIndex;
|
||||||
|
|
||||||
public DexBackedMethodTypeEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedMethodTypeEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
this.methodProtoIndex = reader.readSizedSmallUint(valueArg + 1);
|
this.methodProtoIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ public class DexBackedStringEncodedValue extends BaseStringEncodedValue {
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int stringIndex;
|
private final int stringIndex;
|
||||||
|
|
||||||
public DexBackedStringEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedStringEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
stringIndex = reader.readSizedSmallUint(valueArg + 1);
|
stringIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ public class DexBackedTypeEncodedValue extends BaseTypeEncodedValue {
|
|||||||
@Nonnull public final DexBackedDexFile dexFile;
|
@Nonnull public final DexBackedDexFile dexFile;
|
||||||
private final int typeIndex;
|
private final int typeIndex;
|
||||||
|
|
||||||
public DexBackedTypeEncodedValue(@Nonnull DexReader reader, int valueArg) {
|
public DexBackedTypeEncodedValue(@Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int valueArg) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = dexFile;
|
||||||
typeIndex = reader.readSizedSmallUint(valueArg + 1);
|
typeIndex = reader.readSizedSmallUint(valueArg + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,89 +42,89 @@ import java.util.Random;
|
|||||||
public class BaseDexBufferTest {
|
public class BaseDexBufferTest {
|
||||||
@Test
|
@Test
|
||||||
public void testReadSmallUintSuccess() {
|
public void testReadSmallUintSuccess() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
||||||
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadSmallUintTooLarge1() {
|
public void testReadSmallUintTooLarge1() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadSmallUintTooLarge2() {
|
public void testReadSmallUintTooLarge2() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadSmallUintTooLarge3() {
|
public void testReadSmallUintTooLarge3() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadOptionalUintSuccess() {
|
public void testReadOptionalUintSuccess() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
||||||
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(-1, dexBuf.readOptionalUint(0));
|
Assert.assertEquals(-1, dexBuf.readOptionalUint(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadOptionalUintTooLarge1() {
|
public void testReadOptionalUintTooLarge1() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadOptionalUintTooLarge2() {
|
public void testReadOptionalUintTooLarge2() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadOptionalUintTooLarge3() {
|
public void testReadOptionalUintTooLarge3() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {(byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadUshort() {
|
public void testReadUshort() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x11, 0x22});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0x2211);
|
Assert.assertEquals(dexBuf.readUshort(0), 0x2211);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0);
|
Assert.assertEquals(dexBuf.readUshort(0), 0);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0xffff);
|
Assert.assertEquals(dexBuf.readUshort(0), 0xffff);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
dexBuf = new DexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0x8000);
|
Assert.assertEquals(dexBuf.readUshort(0), 0x8000);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0x7fff);
|
Assert.assertEquals(dexBuf.readUshort(0), 0x7fff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadUbyte() {
|
public void testReadUbyte() {
|
||||||
byte[] buf = new byte[1];
|
byte[] buf = new byte[1];
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<=0xff; i++) {
|
for (int i=0; i<=0xff; i++) {
|
||||||
buf[0] = (byte)i;
|
buf[0] = (byte)i;
|
||||||
@ -134,24 +134,24 @@ public class BaseDexBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadLong() {
|
public void testReadLong() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77});
|
||||||
Assert.assertEquals(0x7766554433221100L, dexBuf.readLong(0));
|
Assert.assertEquals(0x7766554433221100L, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readLong(0));
|
Assert.assertEquals(0, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(Long.MAX_VALUE, dexBuf.readLong(0));
|
Assert.assertEquals(Long.MAX_VALUE, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80});
|
||||||
Assert.assertEquals(Long.MIN_VALUE, dexBuf.readLong(0));
|
Assert.assertEquals(Long.MIN_VALUE, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
Assert.assertEquals(0x80ffffffffffffffL, dexBuf.readLong(0));
|
Assert.assertEquals(0x80ffffffffffffffL, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(-1, dexBuf.readLong(0));
|
Assert.assertEquals(-1, dexBuf.readLong(0));
|
||||||
|
|
||||||
@ -159,50 +159,50 @@ public class BaseDexBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInt() {
|
public void testReadInt() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
||||||
Assert.assertEquals(0x44332211, dexBuf.readInt(0));
|
Assert.assertEquals(0x44332211, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readInt(0));
|
Assert.assertEquals(0, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(Integer.MAX_VALUE, dexBuf.readInt(0));
|
Assert.assertEquals(Integer.MAX_VALUE, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
||||||
Assert.assertEquals(Integer.MIN_VALUE, dexBuf.readInt(0));
|
Assert.assertEquals(Integer.MIN_VALUE, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
Assert.assertEquals(0x80ffffff, dexBuf.readInt(0));
|
Assert.assertEquals(0x80ffffff, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(-1, dexBuf.readInt(0));
|
Assert.assertEquals(-1, dexBuf.readInt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadShort() {
|
public void testReadShort() {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22});
|
DexBuffer dexBuf = new DexBuffer(new byte[] {0x11, 0x22});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0x2211);
|
Assert.assertEquals(dexBuf.readShort(0), 0x2211);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00});
|
dexBuf = new DexBuffer(new byte[] {0x00, 0x00});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0);
|
Assert.assertEquals(dexBuf.readShort(0), 0);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), -1);
|
Assert.assertEquals(dexBuf.readShort(0), -1);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
dexBuf = new DexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), Short.MIN_VALUE);
|
Assert.assertEquals(dexBuf.readShort(0), Short.MIN_VALUE);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0x7fff);
|
Assert.assertEquals(dexBuf.readShort(0), 0x7fff);
|
||||||
|
|
||||||
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0x80});
|
dexBuf = new DexBuffer(new byte[] {(byte)0xff, (byte)0x80});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0xffff80ff);
|
Assert.assertEquals(dexBuf.readShort(0), 0xffff80ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadByte() {
|
public void testReadByte() {
|
||||||
byte[] buf = new byte[1];
|
byte[] buf = new byte[1];
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<=0xff; i++) {
|
for (int i=0; i<=0xff; i++) {
|
||||||
buf[0] = (byte)i;
|
buf[0] = (byte)i;
|
||||||
@ -215,7 +215,7 @@ public class BaseDexBufferTest {
|
|||||||
Random r = new Random(1234567890);
|
Random r = new Random(1234567890);
|
||||||
ByteBuffer byteBuf = ByteBuffer.allocateDirect(4).order(ByteOrder.LITTLE_ENDIAN);
|
ByteBuffer byteBuf = ByteBuffer.allocateDirect(4).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
byte[] buf = new byte[4];
|
byte[] buf = new byte[4];
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<10000; i++) {
|
for (int i=0; i<10000; i++) {
|
||||||
int val = r.nextInt();
|
int val = r.nextInt();
|
||||||
@ -249,7 +249,7 @@ public class BaseDexBufferTest {
|
|||||||
Random r = new Random(1234567890);
|
Random r = new Random(1234567890);
|
||||||
ByteBuffer byteBuf = ByteBuffer.allocateDirect(8).order(ByteOrder.LITTLE_ENDIAN);
|
ByteBuffer byteBuf = ByteBuffer.allocateDirect(8).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
byte[] buf = new byte[8];
|
byte[] buf = new byte[8];
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<10000; i++) {
|
for (int i=0; i<10000; i++) {
|
||||||
int val = r.nextInt();
|
int val = r.nextInt();
|
||||||
|
@ -246,8 +246,8 @@ public class BaseDexReaderLeb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSmallUleb128());
|
Assert.assertEquals(expectedValue, reader.readSmallUleb128());
|
||||||
Assert.assertEquals(expectedLength, reader.getOffset());
|
Assert.assertEquals(expectedLength, reader.getOffset());
|
||||||
|
|
||||||
@ -260,8 +260,8 @@ public class BaseDexReaderLeb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performFailureTest(byte[] buf) {
|
private void performFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.peekSmallUleb128Size();
|
reader.peekSmallUleb128Size();
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
|
@ -253,8 +253,8 @@ public class BaseDexReaderSleb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSleb128());
|
Assert.assertEquals(expectedValue, reader.readSleb128());
|
||||||
Assert.assertEquals(expectedLength, reader.getOffset());
|
Assert.assertEquals(expectedLength, reader.getOffset());
|
||||||
|
|
||||||
@ -263,8 +263,8 @@ public class BaseDexReaderSleb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performFailureTest(byte[] buf) {
|
private void performFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.peekSleb128Size();
|
reader.peekSleb128Size();
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
|
@ -67,8 +67,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedIntTest(int expectedValue, byte[] buf) {
|
private void performSizedIntTest(int expectedValue, byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedInt(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedInt(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +82,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedIntFailureTest(byte[] buf) {
|
private void performSizedIntFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedInt(buf.length);
|
reader.readSizedInt(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -122,8 +122,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedSmallUintTest(int expectedValue, byte[] buf) {
|
private void performSizedSmallUintTest(int expectedValue, byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedSmallUint(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedSmallUint(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +141,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedSmallUintFailureTest(byte[] buf) {
|
private void performSizedSmallUintFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedSmallUint(buf.length);
|
reader.readSizedSmallUint(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -192,8 +192,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedIntTest(int expectedValue, byte[] buf) {
|
private void performSizedRightExtendedIntTest(int expectedValue, byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedInt(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedInt(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,8 +207,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedIntFailureTest(byte[] buf) {
|
private void performSizedRightExtendedIntFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedRightExtendedInt(buf.length);
|
reader.readSizedRightExtendedInt(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -301,8 +301,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedLongTest(long expectedValue, byte[] buf) {
|
private void performSizedRightExtendedLongTest(long expectedValue, byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedLong(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedLong(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,8 +316,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedLongFailureTest(byte[] buf) {
|
private void performSizedRightExtendedLongFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedRightExtendedLong(buf.length);
|
reader.readSizedRightExtendedLong(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -410,8 +410,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedLongTest(long expectedValue, byte[] buf) {
|
private void performSizedLongTest(long expectedValue, byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedLong(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedLong(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,8 +425,8 @@ public class BaseDexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedLongFailureTest(byte[] buf) {
|
private void performSizedLongFailureTest(byte[] buf) {
|
||||||
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
DexBuffer dexBuf = new DexBuffer(buf);
|
||||||
BaseDexReader reader = dexBuf.readerAt(0);
|
DexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedLong(buf.length);
|
reader.readSizedLong(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user