diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java index 74d05e51..e9c871da 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java @@ -191,14 +191,13 @@ public class InstructionMethodItem extends MethodItem { writer.write(", "); writeReference(writer); return true; - //TODO: uncomment - /*case Format35mi: + case Format35mi: writeOpcode(writer); writer.write(' '); writeInvokeRegisters(writer); writer.write(", "); writeInlineIndex(writer); - return true;*/ + return true; case Format35ms: writeOpcode(writer); writer.write(' '); @@ -326,12 +325,10 @@ public class InstructionMethodItem extends MethodItem { writer.printUnsignedLongAsHex(((FieldOffsetInstruction)instruction).getFieldOffset()); } - //TODO: uncomment - /* protected void writeInlineIndex(IndentingWriter writer) throws IOException { - writer.write("inline@0x"); - writer.printUnsignedLongAsHex(((OdexedInvokeInline) instruction).getInlineIndex()); - }*/ + writer.write("inline@"); + writer.printSignedIntAsDec(((InlineIndexInstruction)instruction).getInlineIndex()); + } protected void writeVtableIndex(IndentingWriter writer) throws IOException { writer.write("vtable@"); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java index d0d3860b..0ba0e722 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java @@ -124,6 +124,8 @@ public abstract class DexBackedInstruction implements Instruction { return new DexBackedInstruction35c(dexFile, opcode, instructionStartOffset); case Format35ms: return new DexBackedInstruction35ms(dexFile, opcode, instructionStartOffset); + case Format35mi: + return new DexBackedInstruction35mi(dexFile, opcode, instructionStartOffset); case Format3rc: return new DexBackedInstruction3rc(dexFile, opcode, instructionStartOffset); case Format51l: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction35mi.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction35mi.java new file mode 100644 index 00000000..c80035e5 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction35mi.java @@ -0,0 +1,82 @@ +/* + * Copyright 2013, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.dexbacked.instruction; + +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.dexbacked.DexBackedDexFile; +import org.jf.dexlib2.iface.instruction.formats.Instruction35mi; +import org.jf.util.NibbleUtils; + +import javax.annotation.Nonnull; + +public class DexBackedInstruction35mi extends DexBackedInstruction implements Instruction35mi { + public DexBackedInstruction35mi(@Nonnull DexBackedDexFile dexFile, + @Nonnull Opcode opcode, + int instructionStart) { + super(dexFile, opcode, instructionStart); + } + + @Override public int getRegisterCount() { + //TODO: make sure dalvik verifies that this is in the correct range + return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1)); + } + + @Override + public int getRegisterC() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 4)); + } + + @Override + public int getRegisterD() { + return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 4)); + } + + @Override + public int getRegisterE() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 5)); + } + + @Override + public int getRegisterF() { + return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 5)); + } + + @Override + public int getRegisterG() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1)); + } + + @Override + public int getInlineIndex() { + return dexFile.readUshort(instructionStart + 2); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java index 487018e0..53590aaf 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java @@ -290,6 +290,9 @@ public class CodeItem { } else if (instruction instanceof VtableIndexInstruction) { int vtableIndex = ((VtableIndexInstruction)instruction).getVtableIndex(); args.add(String.format("vtable@%d", vtableIndex)); + } else if (instruction instanceof InlineIndexInstruction) { + int inlineIndex = ((InlineIndexInstruction)instruction).getInlineIndex(); + args.add(String.format("inline@%d", inlineIndex)); } out.annotate(instruction.getCodeUnits()*2, "%s %s", diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/InlineIndexInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/InlineIndexInstruction.java new file mode 100644 index 00000000..b1691460 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/InlineIndexInstruction.java @@ -0,0 +1,36 @@ +/* + * Copyright 2013, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.iface.instruction; + +public interface InlineIndexInstruction extends Instruction { + int getInlineIndex(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction35mi.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction35mi.java new file mode 100644 index 00000000..4b502fea --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction35mi.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.iface.instruction.formats; + +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction; +import org.jf.dexlib2.iface.instruction.InlineIndexInstruction; + +public interface Instruction35mi extends FiveRegisterInstruction, InlineIndexInstruction { +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java index 5474e6cf..9311c097 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java @@ -105,6 +105,8 @@ public abstract class ImmutableInstruction implements Instruction { return ImmutableInstruction32x.of((Instruction32x)instruction); case Format35c: return ImmutableInstruction35c.of((Instruction35c)instruction); + case Format35mi: + return ImmutableInstruction35mi.of((Instruction35mi)instruction); case Format35ms: return ImmutableInstruction35ms.of((Instruction35ms)instruction); case Format3rc: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java new file mode 100644 index 00000000..a31474ea --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java @@ -0,0 +1,95 @@ +/* + * Copyright 2013, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.immutable.instruction; + +import org.jf.dexlib2.Format; +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.iface.instruction.formats.Instruction35mi; +import org.jf.dexlib2.util.Preconditions; + +import javax.annotation.Nonnull; + +public class ImmutableInstruction35mi extends ImmutableInstruction implements Instruction35mi { + public static final Format FORMAT = Format.Format35mi; + + protected final int registerCount; + protected final int registerC; + protected final int registerD; + protected final int registerE; + protected final int registerF; + protected final int registerG; + @Nonnull protected final int inlineIndex; + + public ImmutableInstruction35mi(@Nonnull Opcode opcode, + int registerCount, + int registerC, + int registerD, + int registerE, + int registerF, + int registerG, + int inlineIndex) { + super(opcode); + Preconditions.checkFormat(opcode, FORMAT); + this.registerCount = Preconditions.check35cRegisterCount(registerCount); + this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; + this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; + this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; + this.registerF = (registerCount>3) ? Preconditions.checkNibbleRegister(registerF) : 0; + this.registerG = (registerCount>4) ? Preconditions.checkNibbleRegister(registerG) : 0; + this.inlineIndex = Preconditions.checkInlineIndex(inlineIndex); + } + + public static ImmutableInstruction35mi of(Instruction35mi instruction) { + if (instruction instanceof ImmutableInstruction35mi) { + return (ImmutableInstruction35mi)instruction; + } + return new ImmutableInstruction35mi( + instruction.getOpcode(), + instruction.getRegisterCount(), + instruction.getRegisterC(), + instruction.getRegisterD(), + instruction.getRegisterE(), + instruction.getRegisterF(), + instruction.getRegisterG(), + instruction.getInlineIndex()); + } + + @Override public int getRegisterCount() { return registerCount; } + @Override public int getRegisterC() { return registerC; } + @Override public int getRegisterD() { return registerD; } + @Override public int getRegisterE() { return registerE; } + @Override public int getRegisterF() { return registerF; } + @Override public int getRegisterG() { return registerG; } + @Override public int getInlineIndex() { return inlineIndex; } + + @Override public Format getFormat() { return FORMAT; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java index 26983be7..e8e33b32 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java @@ -167,4 +167,12 @@ public class Preconditions { } return vtableIndex; } + + public static int checkInlineIndex(int inlineIndex) { + if (inlineIndex < 0 || inlineIndex > 65535) { + throw new IllegalArgumentException( + String.format("Invalid inline index: %d. Must be between 0 and 65535, inclusive", inlineIndex)); + } + return inlineIndex; + } }