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:
JesusFreke@JesusFreke.com
2009-09-08 06:27:32 +00:00
parent df2a55dee5
commit 5b89857df3
63 changed files with 3097 additions and 137 deletions

View File

@ -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),

View File

@ -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];
}

View File

@ -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]);
}

View File

@ -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]);
}

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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]);
}

View File

@ -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]);
}

View File

@ -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]);
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -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]);
}

View File

@ -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]);
}

View File

@ -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) {

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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]);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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>
*/

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View 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;
}
}