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 884643d3..78d96957 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 @@ -31,11 +31,10 @@ package org.jf.baksmali.Adaptors.Format; import org.jf.baksmali.Adaptors.MethodDefinition; import org.jf.baksmali.Adaptors.MethodItem; import org.jf.baksmali.Adaptors.ReferenceFormatter; +import org.jf.baksmali.Renderers.LongRenderer; import org.jf.dexlib.Code.Format.UnknownInstruction; -import org.jf.dexlib2.ReferenceType; import org.jf.dexlib2.iface.instruction.*; import org.jf.util.IndentingWriter; -import org.jf.baksmali.Renderers.LongRenderer; import javax.annotation.Nonnull; import java.io.IOException; @@ -150,8 +149,7 @@ public class InstructionMethodItem extends MethodItem { writer.write(", "); writeReference(writer); return true; - //TODO: uncomment - /*case Format22cs: + case Format22cs: writeOpcode(writer); writer.write(' '); writeFirstRegister(writer); @@ -159,7 +157,7 @@ public class InstructionMethodItem extends MethodItem { writeSecondRegister(writer); writer.write(", "); writeFieldOffset(writer); - return true;*/ + return true; case Format22t: writeOpcode(writer); writer.write(' '); @@ -322,12 +320,14 @@ public class InstructionMethodItem extends MethodItem { LongRenderer.writeSignedIntOrLongTo(writer, ((WideLiteralInstruction)instruction).getWideLiteral()); } - //TODO: uncomment - /*protected void writeFieldOffset(IndentingWriter writer) throws IOException { + + protected void writeFieldOffset(IndentingWriter writer) throws IOException { writer.write("field@0x"); - writer.printUnsignedLongAsHex(((OdexedFieldAccess) instruction).getFieldOffset()); + writer.printUnsignedLongAsHex(((FieldOffsetInstruction)instruction).getFieldOffset()); } + //TODO: uncomment + /* protected void writeInlineIndex(IndentingWriter writer) throws IOException { writer.write("inline@0x"); writer.printUnsignedLongAsHex(((OdexedInvokeInline) instruction).getInlineIndex()); 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 53bcd23f..070001fb 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 @@ -100,6 +100,8 @@ public abstract class DexBackedInstruction implements Instruction { return new DexBackedInstruction22b(dexFile, opcode, instructionStartOffset); case Format22c: return new DexBackedInstruction22c(dexFile, opcode, instructionStartOffset); + case Format22cs: + return new DexBackedInstruction22cs(dexFile, opcode, instructionStartOffset); case Format22s: return new DexBackedInstruction22s(dexFile, opcode, instructionStartOffset); case Format22t: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction22cs.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction22cs.java new file mode 100644 index 00000000..0e4e3418 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction22cs.java @@ -0,0 +1,62 @@ +/* + * 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.Instruction22cs; +import org.jf.util.NibbleUtils; + +import javax.annotation.Nonnull; + +public class DexBackedInstruction22cs extends DexBackedInstruction implements Instruction22cs { + public DexBackedInstruction22cs(@Nonnull DexBackedDexFile dexFile, + @Nonnull Opcode opcode, + int instructionStart) { + super(dexFile, opcode, instructionStart); + } + + @Override + public int getRegisterA() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1)); + } + + @Override + public int getRegisterB() { + return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1)); + } + + @Override + public int getFieldOffset() { + 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 3b7b6b7d..e38427c2 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,11 @@ public class CodeItem { } } + if (instruction instanceof FieldOffsetInstruction) { + int fieldOffset = ((FieldOffsetInstruction)instruction).getFieldOffset(); + args.add(String.format("field@0x%x", fieldOffset)); + } + out.annotate(instruction.getCodeUnits()*2, "%s %s", instruction.getOpcode().name, Joiner.on(", ").join(args)); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/FieldOffsetInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/FieldOffsetInstruction.java new file mode 100644 index 00000000..048dd54b --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/FieldOffsetInstruction.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 FieldOffsetInstruction extends Instruction { + int getFieldOffset(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22cs.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22cs.java new file mode 100644 index 00000000..8d34cec2 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22cs.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.FieldOffsetInstruction; +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction; + +public interface Instruction22cs extends TwoRegisterInstruction, FieldOffsetInstruction { +} 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 0086a91e..5f7af6d2 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 @@ -83,6 +83,8 @@ public abstract class ImmutableInstruction implements Instruction { return ImmutableInstruction22b.of((Instruction22b)instruction); case Format22c: return ImmutableInstruction22c.of((Instruction22c)instruction); + case Format22cs: + return ImmutableInstruction22cs.of((Instruction22cs)instruction); case Format22s: return ImmutableInstruction22s.of((Instruction22s)instruction); case Format22t: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22cs.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22cs.java new file mode 100644 index 00000000..5704d207 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22cs.java @@ -0,0 +1,75 @@ +/* + * 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.Instruction22cs; +import org.jf.dexlib2.util.Preconditions; + +import javax.annotation.Nonnull; + +public class ImmutableInstruction22cs extends ImmutableInstruction implements Instruction22cs { + public static final Format FORMAT = Format.Format22cs; + + protected final int registerA; + protected final int registerB; + @Nonnull protected final int fieldOffset; + + public ImmutableInstruction22cs(@Nonnull Opcode opcode, + int registerA, + int registerB, + int fieldOffset) { + super(opcode); + Preconditions.checkFormat(opcode, FORMAT); + this.registerA = Preconditions.checkNibbleRegister(registerA); + this.registerB = Preconditions.checkNibbleRegister(registerB); + this.fieldOffset = Preconditions.checkFieldOffset(fieldOffset); + } + + public static ImmutableInstruction22cs of(Instruction22cs instruction) { + if (instruction instanceof ImmutableInstruction22cs) { + return (ImmutableInstruction22cs)instruction; + } + return new ImmutableInstruction22cs( + instruction.getOpcode(), + instruction.getRegisterA(), + instruction.getRegisterB(), + instruction.getFieldOffset()); + } + + @Override public int getRegisterA() { return registerA; } + @Override public int getRegisterB() { return registerB; } + @Override public int getFieldOffset() { return fieldOffset; } + + @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 e14e6896..10c62f80 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java @@ -150,4 +150,13 @@ public class Preconditions { valueArg, maxValue)); } } + + public static int checkFieldOffset(int fieldOffset) { + if (fieldOffset < 0 || fieldOffset > 65535) { + throw new IllegalArgumentException( + String.format("Invalid field offset: 0x%x. Must be between 0x0000 and 0xFFFF inclusive", + fieldOffset)); + } + return fieldOffset; + } }