mirror of
https://github.com/revanced/smali.git
synced 2025-06-12 04:17:36 +02:00
Initial commit of deodex functionality in dexlib and baksmali
git-svn-id: https://smali.googlecode.com/svn/trunk@435 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
@ -44,6 +44,8 @@ public enum Format {
|
||||
Format22b(Instruction22b.Factory, 4),
|
||||
Format22c(Instruction22c.Factory, 4),
|
||||
Format22cs(Instruction22cs.Factory, 4),
|
||||
Format22csf(null, 4),
|
||||
Format22csn(null, 4),
|
||||
Format22s(Instruction22s.Factory, 4),
|
||||
Format22t(Instruction22t.Factory, 4),
|
||||
Format22x(Instruction22x.Factory, 4),
|
||||
@ -55,9 +57,13 @@ public enum Format {
|
||||
Format32x(Instruction32x.Factory, 6),
|
||||
Format35c(Instruction35c.Factory, 6),
|
||||
Format35s(Instruction35s.Factory, 6),
|
||||
Format35sf(null, 6),
|
||||
Format35ms(Instruction35ms.Factory, 6),
|
||||
Format35msf(null, 6),
|
||||
Format35msn(null, 6),
|
||||
Format3rc(Instruction3rc.Factory, 6),
|
||||
Format3rms(Instruction3rms.Factory, 6),
|
||||
Format3rmsf(null, 6),
|
||||
Format51l(Instruction51l.Factory, 10),
|
||||
ArrayData(null, -1, true),
|
||||
PackedSwitchData(null, -1, true),
|
||||
|
@ -30,10 +30,11 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction10t extends Instruction {
|
||||
public class Instruction10t extends Instruction implements OffsetInstruction {
|
||||
public static final InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte offA) {
|
||||
@ -57,7 +58,7 @@ public class Instruction10t extends Instruction {
|
||||
return Format.Format10t;
|
||||
}
|
||||
|
||||
public byte getOffset() {
|
||||
public int getOffset() {
|
||||
return buffer[bufferIndex + 1];
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,13 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.Code.LiteralInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction11n extends Instruction {
|
||||
public class Instruction11n extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
|
||||
public static final InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte regA, byte litB) {
|
||||
@ -59,11 +61,11 @@ public class Instruction11n extends Instruction {
|
||||
return Format.Format11n;
|
||||
}
|
||||
|
||||
public byte getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public byte getLiteral() {
|
||||
public long getLiteral() {
|
||||
return NumberUtils.decodeHighSignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction11x extends Instruction {
|
||||
public class Instruction11x extends Instruction implements SingleRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA) {
|
||||
@ -54,7 +55,7 @@ public class Instruction11x extends Instruction {
|
||||
return Format.Format11x;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction12x extends Instruction {
|
||||
public class Instruction12x extends Instruction implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
|
||||
@ -55,11 +56,11 @@ public class Instruction12x extends Instruction {
|
||||
return Format.Format12x;
|
||||
}
|
||||
|
||||
public byte getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public byte getRegisterB() {
|
||||
public int getRegisterB() {
|
||||
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction20t extends Instruction {
|
||||
public class Instruction20t extends Instruction implements OffsetInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short offA) {
|
||||
@ -59,7 +60,7 @@ public class Instruction20t extends Instruction {
|
||||
return Format.Format20t;
|
||||
}
|
||||
|
||||
public short getOffset() {
|
||||
public int getOffset() {
|
||||
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
|
||||
}
|
||||
|
||||
|
@ -31,13 +31,14 @@ package org.jf.dexlib.Code.Format;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Item;
|
||||
import org.jf.dexlib.TypeIdItem;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction21c extends InstructionWithReference {
|
||||
public class Instruction21c extends InstructionWithReference implements SingleRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, Item referencedItem) {
|
||||
@ -69,7 +70,7 @@ public class Instruction21c extends InstructionWithReference {
|
||||
return Format.Format21c;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,13 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.LiteralInstruction;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction21h extends Instruction {
|
||||
public class Instruction21h extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, short litB) {
|
||||
@ -55,11 +57,11 @@ public class Instruction21h extends Instruction {
|
||||
return Format.Format21h;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public short getLiteral() {
|
||||
public long getLiteral() {
|
||||
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,13 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.LiteralInstruction;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction21s extends Instruction {
|
||||
public class Instruction21s extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, short litB) {
|
||||
@ -55,11 +57,11 @@ public class Instruction21s extends Instruction {
|
||||
return Format.Format21s;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public short getLiteral() {
|
||||
public long getLiteral() {
|
||||
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction21t extends Instruction {
|
||||
public class Instruction21t extends Instruction implements OffsetInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, short offB) {
|
||||
@ -67,7 +68,7 @@ public class Instruction21t extends Instruction {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public short getOffset() {
|
||||
public int getOffset() {
|
||||
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction22b extends Instruction {
|
||||
public class Instruction22b extends Instruction implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, short regB, byte litC) {
|
||||
@ -57,11 +58,11 @@ public class Instruction22b extends Instruction {
|
||||
return Format.Format22b;
|
||||
}
|
||||
|
||||
public short getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public short getRegisterB() {
|
||||
public int getRegisterB() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,12 @@ package org.jf.dexlib.Code.Format;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Item;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction22c extends InstructionWithReference {
|
||||
public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
|
||||
@ -58,11 +58,11 @@ public class Instruction22c extends InstructionWithReference {
|
||||
return Format.Format22c;
|
||||
}
|
||||
|
||||
public byte getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public byte getRegisterB() {
|
||||
public int getRegisterB() {
|
||||
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.DexFile;
|
||||
|
||||
public class Instruction22cs extends Instruction {
|
||||
public class Instruction22cs extends Instruction implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte regA, byte regB, int fieldOffset) {
|
||||
@ -60,11 +61,11 @@ public class Instruction22cs extends Instruction {
|
||||
return Format.Format22cs;
|
||||
}
|
||||
|
||||
public byte getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public byte getRegisterB() {
|
||||
public int getRegisterB() {
|
||||
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
import org.jf.dexlib.FieldIdItem;
|
||||
|
||||
public class Instruction22csf extends InstructionWithReference implements TwoRegisterInstruction {
|
||||
private final Instruction22cs unfixedInstruction;
|
||||
|
||||
public Instruction22csf(Opcode opcode, Instruction22cs unfixedInstruction, FieldIdItem field) {
|
||||
//the opcode should be the "fixed" opcode. i.e. iget-object, etc. (NOT the "quick" version)
|
||||
super(opcode, field);
|
||||
this.unfixedInstruction = unfixedInstruction;
|
||||
}
|
||||
|
||||
public Format getFormat() {
|
||||
return Format.Format22csf;
|
||||
}
|
||||
|
||||
public int getRegisterA() {
|
||||
return unfixedInstruction.getRegisterA();
|
||||
}
|
||||
|
||||
public int getRegisterB() {
|
||||
return unfixedInstruction.getRegisterB();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
|
||||
/**
|
||||
* This represents a "fixed" Format22cs instruction, where the object register is always null and so the correct type
|
||||
* can't be determined. How this is handled is "implementation dependent". baksmali just replaces it with a call to
|
||||
* object->hashCode(). Since the object register is always null, this will have the same effect as tring to access
|
||||
* whatever field that was trying to be accessed - namely, a NPE
|
||||
*/
|
||||
public class Instruction22csn extends Instruction {
|
||||
|
||||
/**
|
||||
* this is the first register, i.e. the object register. The others don't matter, because we don't know what
|
||||
* the original field is/was.
|
||||
*/
|
||||
public final int RegisterNum;
|
||||
|
||||
public Instruction22csn(int registerNum) {
|
||||
//the opcode should be ignored. It just needs to be a 4 byte opcode
|
||||
super(Opcode.IGET_QUICK);
|
||||
this.RegisterNum = registerNum;
|
||||
}
|
||||
|
||||
|
||||
public Format getFormat() {
|
||||
return Format.Format35msn;
|
||||
}
|
||||
}
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction22s extends Instruction {
|
||||
public class Instruction22s extends Instruction implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short litC) {
|
||||
@ -56,11 +57,11 @@ public class Instruction22s extends Instruction {
|
||||
return Format.Format22s;
|
||||
}
|
||||
|
||||
public byte getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public byte getRegisterB() {
|
||||
public int getRegisterB() {
|
||||
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction22t extends Instruction {
|
||||
public class Instruction22t extends Instruction implements OffsetInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short offC) {
|
||||
@ -72,7 +73,7 @@ public class Instruction22t extends Instruction {
|
||||
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public short getOffset() {
|
||||
public int getOffset() {
|
||||
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction22x extends Instruction {
|
||||
public class Instruction22x extends Instruction implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, int regB) {
|
||||
@ -59,7 +60,7 @@ public class Instruction22x extends Instruction {
|
||||
return Format.Format22x;
|
||||
}
|
||||
|
||||
public short getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.ThreeRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction23x extends Instruction {
|
||||
public class Instruction23x extends Instruction implements ThreeRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, short regB, short regC) {
|
||||
@ -58,15 +59,15 @@ public class Instruction23x extends Instruction {
|
||||
return Format.Format23x;
|
||||
}
|
||||
|
||||
public short getRegisterA() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public short getRegisterB() {
|
||||
public int getRegisterB() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
|
||||
}
|
||||
|
||||
public short getRegisterC() {
|
||||
public int getRegisterC() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 3]);
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,11 @@ package org.jf.dexlib.Code.Format;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction30t extends Instruction
|
||||
{
|
||||
public class Instruction30t extends Instruction implements OffsetInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, int offA) {
|
||||
|
@ -31,12 +31,13 @@ package org.jf.dexlib.Code.Format;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Item;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction31c extends InstructionWithReference {
|
||||
public class Instruction31c extends InstructionWithReference implements SingleRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA) {
|
||||
@ -57,7 +58,7 @@ public class Instruction31c extends InstructionWithReference {
|
||||
return Format.Format31c;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,13 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.LiteralInstruction;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction31i extends Instruction {
|
||||
public class Instruction31i extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, int litB) {
|
||||
@ -55,11 +57,11 @@ public class Instruction31i extends Instruction {
|
||||
return Format.Format31i;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
public int getLiteral() {
|
||||
public long getLiteral() {
|
||||
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.OffsetInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction31t extends Instruction {
|
||||
public class Instruction31t extends Instruction implements OffsetInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, int offB) {
|
||||
|
@ -31,11 +31,11 @@ package org.jf.dexlib.Code.Format;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.TwoRegisterInstruction;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction32x extends Instruction
|
||||
{
|
||||
public class Instruction32x extends Instruction implements TwoRegisterInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, int regA, int regB) {
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
import org.jf.dexlib.MethodIdItem;
|
||||
|
||||
public class Instruction35msf extends InstructionWithReference {
|
||||
private final Instruction35ms unfixedInstruction;
|
||||
|
||||
public Instruction35msf(Opcode opcode, Instruction35ms unfixedInstruction, MethodIdItem method) {
|
||||
//the opcode should be the "fixed" opcode. i.e. iget-object, etc. (NOT the "quick" version)
|
||||
super(opcode, method);
|
||||
this.unfixedInstruction = unfixedInstruction;
|
||||
}
|
||||
|
||||
public Format getFormat() {
|
||||
return Format.Format35msf;
|
||||
}
|
||||
|
||||
public int getRegisterA() {
|
||||
return unfixedInstruction.getRegisterA();
|
||||
}
|
||||
|
||||
public byte getRegCount() {
|
||||
return unfixedInstruction.getRegCount();
|
||||
}
|
||||
|
||||
public byte getRegisterD() {
|
||||
return unfixedInstruction.getRegisterD();
|
||||
}
|
||||
|
||||
public byte getRegisterE() {
|
||||
return unfixedInstruction.getRegisterE();
|
||||
}
|
||||
|
||||
public byte getRegisterF() {
|
||||
return unfixedInstruction.getRegisterF();
|
||||
}
|
||||
|
||||
public byte getRegisterG() {
|
||||
return unfixedInstruction.getRegisterG();
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
|
||||
/**
|
||||
* This represents a "fixed" Format35ms, or Format3rms instruction, where the object register is always null and so the
|
||||
* correct type can't be determined. How this is handled is "implementation dependent". baksmali just replaces it with
|
||||
* a call to object->hashCode(). Since the object register is always null, this will have the same effect as calling
|
||||
* whatever the original method was - namely, a NPE
|
||||
*/
|
||||
public class Instruction35msn extends Instruction {
|
||||
|
||||
/**
|
||||
* this is the first register, i.e. the object register. The others don't matter, because we don't know what
|
||||
* the original method call is/was.
|
||||
*/
|
||||
public final int RegisterNum;
|
||||
|
||||
public Instruction35msn(int registerNum) {
|
||||
super(Opcode.INVOKE_VIRTUAL);
|
||||
this.RegisterNum = registerNum;
|
||||
}
|
||||
|
||||
|
||||
public Format getFormat() {
|
||||
return Format.Format35msn;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
|
||||
public class Instruction35sf extends InstructionWithReference {
|
||||
private final Instruction35s unfixedInstruction;
|
||||
|
||||
public Instruction35sf(Instruction35s unfixedInstruction) {
|
||||
super(Opcode.INVOKE_DIRECT, unfixedInstruction.getReferencedItem());
|
||||
this.unfixedInstruction = unfixedInstruction;
|
||||
}
|
||||
|
||||
public Format getFormat() {
|
||||
return Format.Format35sf;
|
||||
}
|
||||
|
||||
public byte getRegisterA() {
|
||||
return unfixedInstruction.getRegisterA();
|
||||
}
|
||||
|
||||
public byte getRegCount() {
|
||||
return unfixedInstruction.getRegCount();
|
||||
}
|
||||
|
||||
public byte getRegisterD() {
|
||||
return unfixedInstruction.getRegisterD();
|
||||
}
|
||||
|
||||
public byte getRegisterE() {
|
||||
return unfixedInstruction.getRegisterE();
|
||||
}
|
||||
|
||||
public byte getRegisterF() {
|
||||
return unfixedInstruction.getRegisterF();
|
||||
}
|
||||
|
||||
public byte getRegisterG() {
|
||||
return unfixedInstruction.getRegisterG();
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.InstructionWithReference;
|
||||
import org.jf.dexlib.MethodIdItem;
|
||||
|
||||
public class Instruction3rmsf extends InstructionWithReference {
|
||||
private final Instruction3rms unfixedInstruction;
|
||||
|
||||
public Instruction3rmsf(Opcode opcode, Instruction3rms unfixedInstruction, MethodIdItem method) {
|
||||
//the opcode should be the "fixed" opcode. i.e. iget-object, etc. (NOT the "quick" version)
|
||||
super(opcode, method);
|
||||
this.unfixedInstruction = unfixedInstruction;
|
||||
}
|
||||
|
||||
public Format getFormat() {
|
||||
return Format.Format3rmsf;
|
||||
}
|
||||
|
||||
public int getStartRegister() {
|
||||
return unfixedInstruction.getStartRegister();
|
||||
}
|
||||
|
||||
public short getRegCount() {
|
||||
return unfixedInstruction.getRegCount();
|
||||
}
|
||||
}
|
@ -30,11 +30,13 @@ package org.jf.dexlib.Code.Format;
|
||||
|
||||
import org.jf.dexlib.Code.Instruction;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.SingleRegisterInstruction;
|
||||
import org.jf.dexlib.Code.LiteralInstruction;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.dexlib.Util.NumberUtils;
|
||||
import org.jf.dexlib.Util.Output;
|
||||
|
||||
public class Instruction51l extends Instruction {
|
||||
public class Instruction51l extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
|
||||
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||
|
||||
public static void emit(Output out, Opcode opcode, short regA, long litB) {
|
||||
@ -55,7 +57,7 @@ public class Instruction51l extends Instruction {
|
||||
return Format.Format51l;
|
||||
}
|
||||
|
||||
public short getRegister() {
|
||||
public int getRegisterA() {
|
||||
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code;
|
||||
|
||||
public interface LiteralInstruction {
|
||||
long getLiteral();
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code;
|
||||
|
||||
public interface OffsetInstruction {
|
||||
public int getOffset();
|
||||
}
|
@ -255,26 +255,17 @@ public enum Opcode
|
||||
|
||||
|
||||
INVOKE_EXECUTE_INLINE((byte)0xee, "execute_inline", ReferenceType.none, Format.Format35ms, true),
|
||||
|
||||
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, true),
|
||||
|
||||
IGET_QUICK((byte)0xf2, "iget-quick", ReferenceType.none, Format.Format22cs, true),
|
||||
IGET_WIDE_QUICK((byte)0xf3, "iget-wide-quick", ReferenceType.none, Format.Format22cs, true),
|
||||
IGET_OBJECT_QUICK((byte)0xf4, "iget-object-quick", ReferenceType.none, Format.Format22cs, true),
|
||||
|
||||
IPUT_QUICK((byte)0xf5, "iput-quick", ReferenceType.none, Format.Format22cs, true),
|
||||
IPUT_WIDE_QUICK((byte)0xf6, "iput-wide-quick", ReferenceType.none, Format.Format22cs, true),
|
||||
IPUT_OBJECT_QUICK((byte)0xf7, "iput-object-quick", ReferenceType.none, Format.Format22cs, true),
|
||||
|
||||
|
||||
|
||||
INVOKE_VIRTUAL_QUICK((byte)0xf8, "invoke-virtual-quick", ReferenceType.none, Format.Format35ms, true),
|
||||
INVOKE_VIRTUAL_RANGE_QUICK((byte)0xf9, "invoke-virtual-range-quick", ReferenceType.none, Format.Format3rms, true),
|
||||
|
||||
INVOKE_SUPERL_QUICK((byte)0xfa, "invoke-super-quick", ReferenceType.none, Format.Format35ms, true),
|
||||
INVOKE_SUPER_RANGE_QUICK((byte)0xfb, "invoke-super-range-quick", ReferenceType.none, Format.Format3rms, true),
|
||||
|
||||
;
|
||||
INVOKE_SUPER_QUICK((byte)0xfa, "invoke-super-quick", ReferenceType.none, Format.Format35ms, true),
|
||||
INVOKE_SUPER_RANGE_QUICK((byte)0xfb, "invoke-super-range-quick", ReferenceType.none, Format.Format3rms, true);
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code;
|
||||
|
||||
public interface SingleRegisterInstruction {
|
||||
int getRegisterA();
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code;
|
||||
|
||||
public interface ThreeRegisterInstruction extends TwoRegisterInstruction {
|
||||
int getRegisterC();
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code;
|
||||
|
||||
public interface TwoRegisterInstruction extends SingleRegisterInstruction {
|
||||
int getRegisterA();
|
||||
int getRegisterB();
|
||||
|
||||
}
|
@ -28,16 +28,14 @@
|
||||
|
||||
package org.jf.dexlib;
|
||||
|
||||
import org.jf.dexlib.Code.InstructionReader;
|
||||
import org.jf.dexlib.Code.InstructionIterator;
|
||||
import org.jf.dexlib.Code.Opcode;
|
||||
import org.jf.dexlib.Code.InstructionWriter;
|
||||
import org.jf.dexlib.Code.*;
|
||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||
import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.SparseArray;
|
||||
import org.jf.dexlib.Util.Leb128Utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class CodeItem extends Item<CodeItem> {
|
||||
private int registerCount;
|
||||
@ -358,6 +356,13 @@ public class CodeItem extends Item<CodeItem> {
|
||||
return tries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an array of the <code>EncodedCatchHandler</code> objects in this <code>CodeItem</code>
|
||||
*/
|
||||
public EncodedCatchHandler[] getHandlers() {
|
||||
return encodedCatchHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the <code>DebugInfoItem</code> associated with this <code>CodeItem</code>
|
||||
*/
|
||||
@ -381,6 +386,28 @@ public class CodeItem extends Item<CodeItem> {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by OdexUtil to update this <code>CodeItem</code> with a deodexed version of the instructions
|
||||
* @param newEncodedInstructions
|
||||
*/
|
||||
public void updateCode(byte[] newEncodedInstructions) {
|
||||
final LinkedList<Item> referencedItemsList = new LinkedList<Item>();
|
||||
|
||||
|
||||
InstructionIterator.IterateInstructions(dexFile, newEncodedInstructions,
|
||||
new InstructionIterator.ProcessInstructionDelegate() {
|
||||
public void ProcessInstruction(int index, Instruction instruction) {
|
||||
if (instruction.opcode.referenceType != ReferenceType.none) {
|
||||
referencedItemsList.add(((InstructionWithReference)instruction).getReferencedItem());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
referencedItems = new Item[referencedItemsList.size()];
|
||||
referencedItemsList.toArray(referencedItems);
|
||||
encodedInstructions = newEncodedInstructions;
|
||||
}
|
||||
|
||||
public static class TryItem {
|
||||
/**
|
||||
* The address (in 2-byte words) within the code where the try block starts
|
||||
|
@ -166,11 +166,18 @@ public class DexFile
|
||||
*/
|
||||
private final DexFile dexFile = this;
|
||||
|
||||
/**
|
||||
* Is this file an odex file? This is only set when reading in an odex file
|
||||
*/
|
||||
private boolean isOdex = false;
|
||||
|
||||
|
||||
private int dataOffset;
|
||||
private int dataSize;
|
||||
private int fileSize;
|
||||
|
||||
private boolean disableInterning = false;
|
||||
|
||||
|
||||
/**
|
||||
* A private constructor containing common code to initialize the section maps and lists
|
||||
@ -278,7 +285,7 @@ public class DexFile
|
||||
}
|
||||
|
||||
boolean isDex = true;
|
||||
boolean isOdex = true;
|
||||
this.isOdex = true;
|
||||
for (int i=0; i<8; i++) {
|
||||
if (magic[i] != dexMagic[i]) {
|
||||
isDex = false;
|
||||
@ -401,6 +408,30 @@ public class DexFile
|
||||
this.sortAllItems = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables adding new items to this dex file. The various getInterned*() type
|
||||
* methods on individual items will return null if there isn't an existing item
|
||||
* that matches
|
||||
*/
|
||||
public void disableInterning() {
|
||||
this.disableInterning = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a boolean value indicating whether interning new items has been disabled
|
||||
* for this dex file
|
||||
*/
|
||||
public boolean getInterningDisabled() {
|
||||
return disableInterning;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a boolean value indicating whether this dex file was created by reading in an odex file
|
||||
*/
|
||||
public boolean isOdex() {
|
||||
return this.isOdex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean value indicating whether items in this dex file should be
|
||||
* written back out "in-place", or whether the normal layout logic should be
|
||||
|
@ -155,6 +155,20 @@ public class ProtoIdItem extends Item<ProtoIdItem> {
|
||||
return cachedPrototypeString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the return type of the method
|
||||
*/
|
||||
public TypeIdItem getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a <code>TypeListItem</code> containing the method parameter types
|
||||
*/
|
||||
public TypeListItem getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of registers required for the parameters of this <code>ProtoIdItem</code>
|
||||
*/
|
||||
|
@ -174,8 +174,11 @@ public abstract class Section<T extends Item> {
|
||||
* as the item passed to this method.
|
||||
*/
|
||||
protected T intern(T item) {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
T internedItem = getInternedItem(item);
|
||||
if (internedItem == null) {
|
||||
if (internedItem == null && !item.dexFile.getInterningDisabled()) {
|
||||
uniqueItems.put(item, item);
|
||||
items.add(item);
|
||||
return item;
|
||||
|
@ -53,16 +53,6 @@ public class StringIdItem extends Item<StringIdItem> {
|
||||
this.stringDataItem = stringDataItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>StringIdItem</code> and associated <code>StringDataItem</code>
|
||||
* for the given <code>String</code> value
|
||||
* @param dexFile The <code>DexFile</code> that this item will belong to
|
||||
* @param stringValue The string value that this item represents
|
||||
*/
|
||||
private StringIdItem(DexFile dexFile, String stringValue) {
|
||||
this(dexFile, StringDataItem.getInternedStringDataItem(dexFile, stringValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>StringIdItem</code> for the given values, and that has been interned into
|
||||
* the given <code>DexFile</code>
|
||||
@ -72,7 +62,11 @@ public class StringIdItem extends Item<StringIdItem> {
|
||||
* the given <code>DexFile</code>
|
||||
*/
|
||||
public static StringIdItem getInternedStringIdItem(DexFile dexFile, String stringValue) {
|
||||
StringIdItem stringIdItem = new StringIdItem(dexFile, stringValue);
|
||||
StringDataItem stringDataItem = StringDataItem.getInternedStringDataItem(dexFile, stringValue);
|
||||
if (stringDataItem == null) {
|
||||
return null;
|
||||
}
|
||||
StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem);
|
||||
return dexFile.StringIdsSection.intern(stringIdItem);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,11 @@ public class TypeIdItem extends Item<TypeIdItem> {
|
||||
* the given <code>DexFile</code>
|
||||
*/
|
||||
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, String typeDescriptor) {
|
||||
TypeIdItem typeIdItem = new TypeIdItem(dexFile, StringIdItem.getInternedStringIdItem(dexFile, typeDescriptor));
|
||||
StringIdItem stringIdItem = StringIdItem.getInternedStringIdItem(dexFile, typeDescriptor);
|
||||
if (stringIdItem == null) {
|
||||
return null;
|
||||
}
|
||||
TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem);
|
||||
return dexFile.TypeIdsSection.intern(typeIdItem);
|
||||
}
|
||||
|
||||
|
1479
dexlib/src/main/java/org/jf/dexlib/Util/DeodexUtil.java
Normal file
1479
dexlib/src/main/java/org/jf/dexlib/Util/DeodexUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
359
dexlib/src/main/java/org/jf/dexlib/Util/Deodexerant.java
Normal file
359
dexlib/src/main/java/org/jf/dexlib/Util/Deodexerant.java
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Util;
|
||||
|
||||
import org.jf.dexlib.*;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Deodexerant {
|
||||
private final String host;
|
||||
private final int port;
|
||||
|
||||
public final DexFile dexFile;
|
||||
|
||||
private Socket socket = null;
|
||||
private PrintWriter out = null;
|
||||
private BufferedReader in = null;
|
||||
|
||||
public Deodexerant(DexFile dexFile, String host, int port) {
|
||||
this.dexFile = dexFile;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public InlineMethod lookupInlineMethod(int inlineMethodIndex) {
|
||||
connectIfNeeded();
|
||||
|
||||
String response = sendCommand("I " + inlineMethodIndex);
|
||||
|
||||
InlineMethodType type;
|
||||
|
||||
if (response.startsWith("virtual")) {
|
||||
type = InlineMethodType.Virtual;
|
||||
} else if (response.startsWith("direct")) {
|
||||
type = InlineMethodType.Direct;
|
||||
} else if (response.startsWith("static")) {
|
||||
type = InlineMethodType.Static;
|
||||
} else {
|
||||
throw new RuntimeException("Invalid response from deodexerant");
|
||||
}
|
||||
|
||||
|
||||
int colon = response.indexOf(':');
|
||||
if (colon == -1) {
|
||||
throw new RuntimeException("Invalid response from deodexerant");
|
||||
}
|
||||
|
||||
String methodDescriptor = response.substring(colon+2);
|
||||
|
||||
MethodIdItem method = parseAndLookupMethod(methodDescriptor);
|
||||
|
||||
return new InlineMethod(method, type);
|
||||
}
|
||||
|
||||
public FieldIdItem lookupField(TypeIdItem type, int fieldOffset) {
|
||||
connectIfNeeded();
|
||||
|
||||
String response = sendCommand("F " + type.getTypeDescriptor() + " " + fieldOffset);
|
||||
|
||||
int colon = response.indexOf(':');
|
||||
if (colon == -1) {
|
||||
throw new RuntimeException("Invalid response from deodexerant");
|
||||
}
|
||||
|
||||
String fieldDescriptor = response.substring(colon+2);
|
||||
|
||||
return parseAndLookupField(fieldDescriptor);
|
||||
}
|
||||
|
||||
private static HashMap<Integer, MethodIdItem> cachedVirtualMethods = new HashMap<Integer, MethodIdItem>();
|
||||
public MethodIdItem lookupVirtualMethod(TypeIdItem type, int methodIndex, boolean superLookup) {
|
||||
int hash = type.hashCode() + methodIndex * 31;
|
||||
|
||||
connectIfNeeded();
|
||||
|
||||
String commandChar = superLookup?"S":"V";
|
||||
String response = sendCommand(commandChar + " " + type.getTypeDescriptor() + " " + methodIndex);
|
||||
|
||||
int colon = response.indexOf(':');
|
||||
if (colon == -1) {
|
||||
throw new RuntimeException("Invalid response from deodexerant");
|
||||
}
|
||||
|
||||
String methodDescriptor = response.substring(colon+2);
|
||||
|
||||
return parseAndLookupMethod(methodDescriptor);
|
||||
}
|
||||
|
||||
public String lookupSuperclass(String typeDescriptor) {
|
||||
connectIfNeeded();
|
||||
|
||||
String response = sendCommand("P " + typeDescriptor);
|
||||
int colon = response.indexOf(':');
|
||||
if (colon == -1) {
|
||||
throw new RuntimeException("Invalid response from deodexerant");
|
||||
}
|
||||
|
||||
String type = response.substring(colon+2);
|
||||
if (type.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public String lookupCommonSuperclass(String typeDescriptor1, String typeDescriptor2) {
|
||||
connectIfNeeded();
|
||||
|
||||
String response = sendCommand("C " + typeDescriptor1 + " " + typeDescriptor2);
|
||||
int colon = response.indexOf(':');
|
||||
if (colon == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return response.substring(colon+2);
|
||||
}
|
||||
|
||||
private String sendCommand(String cmd) {
|
||||
try {
|
||||
out.println(cmd);
|
||||
out.flush();
|
||||
String response = in.readLine();
|
||||
if (response.startsWith("err")) {
|
||||
String error = response.substring(5);
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
return response;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void connectIfNeeded() {
|
||||
try {
|
||||
if (socket != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
socket = new Socket(host, port);
|
||||
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern methodPattern = Pattern.compile("(\\[*(?:L[^;]+;)|[ZBSCIJFD])->([^(]+)\\(([^)]*)\\)(.+)");
|
||||
private MethodIdItem parseAndLookupMethod(String method) {
|
||||
//expecting a string like Lsome/class;->someMethod(IIII)Lreturn/type;
|
||||
|
||||
Matcher m = methodPattern.matcher(method);
|
||||
if (!m.matches()) {
|
||||
throw new RuntimeException("invalid method string: " + method);
|
||||
}
|
||||
|
||||
String clazz = m.group(1);
|
||||
String methodName = m.group(2);
|
||||
String params = m.group(3);
|
||||
String ret = m.group(4);
|
||||
|
||||
LinkedList<TypeIdItem> paramList = new LinkedList<TypeIdItem>();
|
||||
|
||||
for (int i=0; i<params.length(); i++) {
|
||||
switch (params.charAt(i)) {
|
||||
case 'Z':
|
||||
case 'B':
|
||||
case 'S':
|
||||
case 'C':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'F':
|
||||
case 'D':
|
||||
paramList.add(getType(dexFile, Character.toString(params.charAt(i))));
|
||||
break;
|
||||
case 'L':
|
||||
{
|
||||
int end = params.indexOf(';', i);
|
||||
if (end == -1) {
|
||||
throw new RuntimeException("invalid parameter in the method string: " + method);
|
||||
}
|
||||
|
||||
paramList.add(getType(dexFile, params.substring(i, end+1)));
|
||||
i = end;
|
||||
break;
|
||||
}
|
||||
case '[':
|
||||
{
|
||||
int end;
|
||||
int typeStart = i+1;
|
||||
while (typeStart < params.length() && params.charAt(typeStart) == '[') {
|
||||
typeStart++;
|
||||
}
|
||||
switch (params.charAt(typeStart)) {
|
||||
case 'Z':
|
||||
case 'B':
|
||||
case 'S':
|
||||
case 'C':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'F':
|
||||
case 'D':
|
||||
end = typeStart;
|
||||
break;
|
||||
case 'L':
|
||||
end = params.indexOf(';', typeStart);
|
||||
if (end == -1) {
|
||||
throw new RuntimeException("invalid parameter in the method string: " + method);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("invalid parameter in the method string: " + method);
|
||||
}
|
||||
|
||||
paramList.add(getType(dexFile, params.substring(i, end+1)));
|
||||
i = end;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("invalid parameter in the method string: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
TypeIdItem classType = getType(dexFile, clazz);
|
||||
TypeIdItem retType = getType(dexFile, ret);
|
||||
|
||||
TypeListItem paramListItem = null;
|
||||
if (paramList.size() > 0) {
|
||||
paramListItem = TypeListItem.getInternedTypeListItem(dexFile, paramList);
|
||||
if (paramListItem == null) {
|
||||
throw new RuntimeException("Could not find type list item in dex file");
|
||||
}
|
||||
}
|
||||
|
||||
ProtoIdItem protoItem = ProtoIdItem.getInternedProtoIdItem(dexFile, retType, paramListItem);
|
||||
if (protoItem == null) {
|
||||
throw new RuntimeException("Could not find prototype item in dex file");
|
||||
}
|
||||
|
||||
StringIdItem methodNameItem = StringIdItem.getInternedStringIdItem(dexFile, methodName);
|
||||
if (methodNameItem == null) {
|
||||
throw new RuntimeException("Could not find method name item in dex file");
|
||||
}
|
||||
|
||||
MethodIdItem methodIdItem;
|
||||
|
||||
do {
|
||||
methodIdItem = MethodIdItem.getInternedMethodIdItem(dexFile, classType, protoItem, methodNameItem);
|
||||
if (methodIdItem != null) {
|
||||
return methodIdItem;
|
||||
}
|
||||
|
||||
String superclassDescriptor = lookupSuperclass(classType.getTypeDescriptor());
|
||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||
|
||||
while (classType == null && superclassDescriptor != null) {
|
||||
superclassDescriptor = lookupSuperclass(superclassDescriptor);
|
||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||
}
|
||||
|
||||
} while (classType != null);
|
||||
throw new RuntimeException("Could not find method in dex file");
|
||||
}
|
||||
|
||||
private static final Pattern fieldPattern = Pattern.compile("(\\[*L[^;]+;)->([^:]+):(.+)");
|
||||
private FieldIdItem parseAndLookupField(String field) {
|
||||
//expecting a string like Lsome/class;->someField:Lfield/type;
|
||||
|
||||
Matcher m = fieldPattern.matcher(field);
|
||||
if (!m.matches()) {
|
||||
throw new RuntimeException("invalid field string: " + field);
|
||||
}
|
||||
|
||||
String clazz = m.group(1);
|
||||
String fieldName = m.group(2);
|
||||
String fieldType = m.group(3);
|
||||
|
||||
TypeIdItem classType = TypeIdItem.getInternedTypeIdItem(dexFile, clazz);
|
||||
StringIdItem fieldNameItem = StringIdItem.getInternedStringIdItem(dexFile, fieldName);
|
||||
TypeIdItem fieldTypeItem = TypeIdItem.getInternedTypeIdItem(dexFile, fieldType);
|
||||
|
||||
FieldIdItem fieldIdItem;
|
||||
|
||||
do {
|
||||
fieldIdItem = FieldIdItem.getInternedFieldIdItem(dexFile, classType, fieldTypeItem, fieldNameItem);
|
||||
if (fieldIdItem != null) {
|
||||
return fieldIdItem;
|
||||
}
|
||||
|
||||
String superclassDescriptor = lookupSuperclass(classType.getTypeDescriptor());
|
||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||
|
||||
while (classType == null && superclassDescriptor != null) {
|
||||
superclassDescriptor = lookupSuperclass(superclassDescriptor);
|
||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||
}
|
||||
|
||||
} while (classType != null);
|
||||
throw new RuntimeException("Could not find field in dex file");
|
||||
}
|
||||
|
||||
public enum InlineMethodType {
|
||||
Virtual,
|
||||
Direct,
|
||||
Static
|
||||
}
|
||||
|
||||
public static class InlineMethod {
|
||||
public final MethodIdItem methodIdItem;
|
||||
public final InlineMethodType methodType;
|
||||
public InlineMethod(MethodIdItem methodIdItem, InlineMethodType methodType) {
|
||||
this.methodIdItem = methodIdItem;
|
||||
this.methodType = methodType;
|
||||
}
|
||||
}
|
||||
|
||||
private static TypeIdItem getType(DexFile dexFile, String typeDescriptor) {
|
||||
TypeIdItem type = TypeIdItem.getInternedTypeIdItem(dexFile, typeDescriptor);
|
||||
if (type == null) {
|
||||
throw new RuntimeException("Could not find type \"" + typeDescriptor + "\" in dex file");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user