From 5f98a2926093cd9a6c2ea64848c47fc5e39e018d Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Sun, 30 Aug 2009 04:28:11 +0000 Subject: [PATCH] Add support for the odex only opcodes git-svn-id: https://smali.googlecode.com/svn/trunk@432 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../Format/Instruction22csMethodItem.java | 47 ++++++++ .../Format/Instruction35msMethodItem.java | 77 +++++++++++++ .../Format/Instruction35sMethodItem.java | 77 +++++++++++++ .../Format/Instruction3rcMethodItem.java | 3 +- .../Format/Instruction3rmsMethodItem.java | 52 +++++++++ .../baksmali/Adaptors/MethodDefinition.java | 17 ++- .../templates/templates/baksmali.stg | 20 ++++ .../org/jf/dexlib/Code/Format/Format.java | 4 + .../dexlib/Code/Format/Instruction22cs.java | 80 +++++++++++++ .../jf/dexlib/Code/Format/Instruction35c.java | 2 +- .../dexlib/Code/Format/Instruction35ms.java | 108 ++++++++++++++++++ .../jf/dexlib/Code/Format/Instruction35s.java | 58 ++++++++++ .../dexlib/Code/Format/Instruction3rms.java | 90 +++++++++++++++ .../main/java/org/jf/dexlib/Code/Opcode.java | 33 +++++- 14 files changed, 663 insertions(+), 5 deletions(-) create mode 100644 baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22csMethodItem.java create mode 100644 baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35msMethodItem.java create mode 100644 baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35sMethodItem.java create mode 100644 baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rmsMethodItem.java create mode 100644 dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java create mode 100644 dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java create mode 100644 dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35s.java create mode 100644 dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22csMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22csMethodItem.java new file mode 100644 index 00000000..c0ee2746 --- /dev/null +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22csMethodItem.java @@ -0,0 +1,47 @@ +/* + * [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.baksmali.Adaptors.Format; + +import org.jf.dexlib.Code.Format.Instruction22cs; +import org.jf.dexlib.CodeItem; +import org.antlr.stringtemplate.StringTemplateGroup; +import org.antlr.stringtemplate.StringTemplate; + +public class Instruction22csMethodItem extends InstructionFormatMethodItem { + public Instruction22csMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, + Instruction22cs instruction) { + super(codeItem, offset, stg, instruction); + } + + protected void setAttributes(StringTemplate template) { + template.setAttribute("FieldOffset", instruction.getFieldOffset()); + template.setAttribute("RegisterA", formatRegister(instruction.getRegisterA())); + template.setAttribute("RegisterB", formatRegister(instruction.getRegisterB())); + } +} diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35msMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35msMethodItem.java new file mode 100644 index 00000000..20d4243a --- /dev/null +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35msMethodItem.java @@ -0,0 +1,77 @@ +/* + * [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.baksmali.Adaptors.Format; + +import org.jf.dexlib.CodeItem; +import org.jf.dexlib.Code.Format.Instruction35ms; +import org.jf.dexlib.Code.Format.Instruction35c; +import org.jf.baksmali.Adaptors.Reference.Reference; +import org.antlr.stringtemplate.StringTemplateGroup; +import org.antlr.stringtemplate.StringTemplate; + +public class Instruction35msMethodItem extends InstructionFormatMethodItem { + public Instruction35msMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, + Instruction35ms instruction) { + super(codeItem, offset, stg, instruction); + } + + protected void setAttributes(StringTemplate template) { + template.setAttribute("MethodIndex", instruction.getMethodIndex()); + setRegistersAttribute(template); + } + + private void setRegistersAttribute(StringTemplate template) { + switch (instruction.getRegCount()) { + case 1: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + return; + case 2: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + return; + case 3: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); + return; + case 4: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); + return; + case 5: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterA())); + } + } +} diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35sMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35sMethodItem.java new file mode 100644 index 00000000..8ac7acfe --- /dev/null +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction35sMethodItem.java @@ -0,0 +1,77 @@ +/* + * [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.baksmali.Adaptors.Format; + +import org.jf.dexlib.Code.Format.Instruction35s; +import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.Reference.Reference; +import org.antlr.stringtemplate.StringTemplateGroup; +import org.antlr.stringtemplate.StringTemplate; + +public class Instruction35sMethodItem extends InstructionFormatMethodItem { + public Instruction35sMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, + Instruction35s instruction) { + super(codeItem, offset, stg, instruction); + } + + protected void setAttributes(StringTemplate template) { + template.setAttribute("Reference", Reference.makeReference(template.getGroup(), + instruction.getReferencedItem())); + setRegistersAttribute(template); + } + + private void setRegistersAttribute(StringTemplate template) { + switch (instruction.getRegCount()) { + case 1: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + return; + case 2: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + return; + case 3: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); + return; + case 4: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); + return; + case 5: + template.setAttribute("Registers", formatRegister(instruction.getRegisterD())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterE())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterF())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterG())); + template.setAttribute("Registers", formatRegister(instruction.getRegisterA())); + } + } +} diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rcMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rcMethodItem.java index c91ab853..b509d039 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rcMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rcMethodItem.java @@ -36,7 +36,8 @@ import org.jf.dexlib.Code.Format.Instruction3rc; import org.jf.dexlib.CodeItem; public class Instruction3rcMethodItem extends InstructionFormatMethodItem { - public Instruction3rcMethodItem(int offset, StringTemplateGroup stg, Instruction3rc instruction, CodeItem codeItem) { + public Instruction3rcMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, + Instruction3rc instruction) { super(codeItem, offset, stg, instruction); } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rmsMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rmsMethodItem.java new file mode 100644 index 00000000..558b251a --- /dev/null +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction3rmsMethodItem.java @@ -0,0 +1,52 @@ +/* + * [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.baksmali.Adaptors.Format; + +import org.antlr.stringtemplate.StringTemplateGroup; +import org.antlr.stringtemplate.StringTemplate; +import org.jf.dexlib.Code.Format.Instruction3rms; +import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.RegisterFormatter; + +public class Instruction3rmsMethodItem extends InstructionFormatMethodItem { + public Instruction3rmsMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, + Instruction3rms instruction) { + super(codeItem, offset, stg, instruction); + } + + protected void setAttributes(StringTemplate template) { + template.setAttribute("MethodIndex", instruction.getMethodIndex()); + + String[] registers = RegisterFormatter.formatFormat3rcRegisters(codeItem, instruction.getStartRegister(), + instruction.getStartRegister() + instruction.getRegCount() - 1); + + template.setAttribute("StartRegister", registers[0]); + template.setAttribute("LastRegister", registers[1]); + } +} diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java index 513e2a28..82c5c339 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java @@ -265,6 +265,10 @@ public class MethodDefinition { case Format22c: instructions.add(new Instruction22cMethodItem(codeItem, offset, stg, (Instruction22c)instruction)); return; + case Format22cs: + instructions.add(new Instruction22csMethodItem(codeItem, offset, stg, + (Instruction22cs)instruction)); + return; case Format22s: instructions.add(new Instruction22sMethodItem(codeItem, offset, stg, (Instruction22s)instruction)); return; @@ -307,8 +311,19 @@ public class MethodDefinition { case Format35c: instructions.add(new Instruction35cMethodItem(codeItem, offset, stg, (Instruction35c)instruction)); return; + case Format35s: + instructions.add(new Instruction35sMethodItem(codeItem, offset, stg, (Instruction35s)instruction)); + return; + case Format35ms: + instructions.add(new Instruction35msMethodItem(codeItem, offset, stg, + (Instruction35ms)instruction)); + return; case Format3rc: - instructions.add(new Instruction3rcMethodItem(offset, stg, (Instruction3rc)instruction, codeItem)); + instructions.add(new Instruction3rcMethodItem(codeItem, offset, stg, (Instruction3rc)instruction)); + return; + case Format3rms: + instructions.add(new Instruction3rmsMethodItem(codeItem, offset, stg, + (Instruction3rms)instruction)); return; case Format51l: instructions.add(new Instruction51lMethodItem(codeItem, offset, stg, (Instruction51l)instruction)); diff --git a/baksmali/src/main/resources/templates/templates/baksmali.stg b/baksmali/src/main/resources/templates/templates/baksmali.stg index 7af2bed7..acab30f7 100644 --- a/baksmali/src/main/resources/templates/templates/baksmali.stg +++ b/baksmali/src/main/resources/templates/templates/baksmali.stg @@ -188,6 +188,11 @@ Format22c(Opcode, RegisterA, RegisterB, Reference) ::= , , >> +Format22cs(Opcode, RegisterA, RegisterB, FieldOffset) ::= +<< + , , Field@ +>> + Format22s(Opcode, RegisterA, RegisterB, Literal) ::= << , , @@ -238,11 +243,26 @@ Format35c(Opcode, Registers, Reference) ::= {}, >> +Format35s(Opcode, Registers, Reference) ::= +<< + {}, +>> + +Format35ms(Opcode, Registers, MethodIndex) ::= +<< + {}, vtable@ +>> + Format3rc(Opcode, StartRegister, LastRegister, Reference) ::= << { .. }, >> +Format3rms(Opcode, StartRegister, LastRegister, MethodIndex) ::= +<< + { .. }, vtable@ +>> + Format51l(Opcode, Register, Literal) ::= << , diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java index 6157abf8..fee982b5 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java @@ -43,6 +43,7 @@ public enum Format { Format21t(Instruction21t.Factory, 4), Format22b(Instruction22b.Factory, 4), Format22c(Instruction22c.Factory, 4), + Format22cs(Instruction22cs.Factory, 4), Format22s(Instruction22s.Factory, 4), Format22t(Instruction22t.Factory, 4), Format22x(Instruction22x.Factory, 4), @@ -53,7 +54,10 @@ public enum Format { Format31t(Instruction31t.Factory, 6), Format32x(Instruction32x.Factory, 6), Format35c(Instruction35c.Factory, 6), + Format35s(Instruction35s.Factory, 6), + Format35ms(Instruction35ms.Factory, 6), Format3rc(Instruction3rc.Factory, 6), + Format3rms(Instruction3rms.Factory, 6), Format51l(Instruction51l.Factory, 10), ArrayData(null, -1, true), PackedSwitchData(null, -1, true), diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java new file mode 100644 index 00000000..cf911f20 --- /dev/null +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java @@ -0,0 +1,80 @@ +/* + * [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; +import org.jf.dexlib.Util.Output; +import org.jf.dexlib.Util.NumberUtils; +import org.jf.dexlib.DexFile; + +public class Instruction22cs extends Instruction { + public static final Instruction.InstructionFactory Factory = new Factory(); + + public static void emit(Output out, Opcode opcode, byte regA, byte regB, int fieldOffset) { + if (regA >= 1 << 4 || + regB >= 1 << 4) { + throw new RuntimeException("The register number must be less than v16"); + } + + if (fieldOffset >= 1 << 16) { + throw new RuntimeException("The field offset must be less than 65536"); + } + + out.writeByte(opcode.value); + out.writeByte((regB << 4) | regA); + out.writeShort(fieldOffset); + } + + private Instruction22cs(Opcode opcode, byte[] buffer, int bufferIndex) { + super(opcode, buffer, bufferIndex); + } + + public Format getFormat() { + return Format.Format22cs; + } + + public byte getRegisterA() { + return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); + } + + public byte getRegisterB() { + return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); + } + + public int getFieldOffset() { + return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); + } + + private static class Factory implements Instruction.InstructionFactory { + public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { + return new Instruction22cs(opcode, buffer, bufferIndex); + } + } +} diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java index 01cef0b4..dddf6741 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java @@ -65,7 +65,7 @@ public class Instruction35c extends InstructionWithReference { checkItem(opcode, referencedItem, regCount); } - private Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { + protected Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { super(dexFile, opcode, buffer, bufferIndex); if (getRegCount() > 5) { diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java new file mode 100644 index 00000000..fdad8883 --- /dev/null +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java @@ -0,0 +1,108 @@ +/* + * [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; +import org.jf.dexlib.Util.Output; +import org.jf.dexlib.Util.NumberUtils; +import org.jf.dexlib.DexFile; + + +public class Instruction35ms extends Instruction { + public static final Instruction.InstructionFactory Factory = new Factory(); + + public static void emit(Output out, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG, + byte regA, int methodIndex) { + if (regCount > 5) { + throw new RuntimeException("regCount cannot be greater than 5"); + } + + if (regD >= 1 << 4 || + regE >= 1 << 4 || + regF >= 1 << 4 || + regG >= 1 << 4 || + regA >= 1 << 4) { + throw new RuntimeException("All register args must fit in 4 bits"); + } + + if (methodIndex >= 1 << 16) { + throw new RuntimeException("The method index must be less than 65536"); + } + + out.writeByte(opcode.value); + out.writeByte((regCount << 4) | regA); + out.writeShort(methodIndex); + out.writeByte((regE << 4) | regD); + out.writeByte((regG << 4) | regF); + } + + private Instruction35ms(Opcode opcode, byte[] buffer, int bufferIndex) { + super(opcode, buffer, bufferIndex); + } + + public Format getFormat() { + return Format.Format35ms; + } + + public byte getRegisterA() { + return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); + } + + public byte getRegCount() { + return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); + } + + public byte getRegisterD() { + return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]); + } + + public byte getRegisterE() { + return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]); + } + + public byte getRegisterF() { + return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]); + } + + public byte getRegisterG() { + return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]); + } + + public int getMethodIndex() { + return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); + } + + private static class Factory implements Instruction.InstructionFactory { + public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { + return new Instruction35ms(opcode, buffer, bufferIndex); + } + } +} + diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35s.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35s.java new file mode 100644 index 00000000..47770cb6 --- /dev/null +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35s.java @@ -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; +import org.jf.dexlib.Util.Output; +import org.jf.dexlib.Item; +import org.jf.dexlib.DexFile; + +public class Instruction35s extends Instruction35c { + public static final Instruction.InstructionFactory Factory = new Factory(); + + public static void emit(Output out, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG, + byte regA, Item referencedItem) { + Instruction35c.emit(out, opcode, regCount, regD, regE, regF, regG, regA, referencedItem); + } + + private Instruction35s(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { + super(dexFile, opcode, buffer, bufferIndex); + } + + public Format getFormat() { + return Format.Format35s; + } + + private static class Factory implements Instruction.InstructionFactory { + public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { + return new Instruction35s(dexFile, opcode, buffer, bufferIndex); + } + } +} diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java new file mode 100644 index 00000000..b7bf031f --- /dev/null +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java @@ -0,0 +1,90 @@ +/* + * [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; +import org.jf.dexlib.Util.Output; +import org.jf.dexlib.Util.NumberUtils; +import org.jf.dexlib.DexFile; + +public class Instruction3rms extends Instruction { + public static final Instruction.InstructionFactory Factory = new Factory(); + + public static void emit(Output out, Opcode opcode, short regCount, int startReg, int methodIndex) { + if (regCount >= 1 << 8) { + throw new RuntimeException("regCount must be less than 256"); + } + if (regCount < 0) { + throw new RuntimeException("regCount cannot be negative"); + } + + if (startReg >= 1 << 16) { + throw new RuntimeException("The beginning register of the range must be less than 65536"); + } + if (startReg < 0) { + throw new RuntimeException("The beginning register of the range cannot be negative"); + } + + if (methodIndex >= 1 << 16) { + throw new RuntimeException("The method index must be less than 65536"); + } + + out.writeByte(opcode.value); + out.writeByte(regCount); + out.writeShort(0); + out.writeShort(startReg); + } + + private Instruction3rms(Opcode opcode, byte[] buffer, int bufferIndex) { + super(opcode, buffer, bufferIndex); + } + + public Format getFormat() { + return Format.Format3rms; + } + + public short getRegCount() { + return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); + } + + public int getStartRegister() { + return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); + } + + public int getMethodIndex() { + return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); + } + + private static class Factory implements Instruction.InstructionFactory { + public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { + return new Instruction3rms(opcode, buffer, bufferIndex); + } + } +} diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java b/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java index 2964c68e..5174b5ae 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java @@ -251,7 +251,30 @@ public enum Opcode XOR_INT_LIT8((byte)0xdf, "xor-int/lit8", ReferenceType.none, Format.Format22b), SHL_INT_LIT8((byte)0xe0, "shl-int/lit8", ReferenceType.none, Format.Format22b), SHR_INT_LIT8((byte)0xe1, "shr-int/lit8", ReferenceType.none, Format.Format22b), - USHR_INT_LIT8((byte)0xe2, "ushr-int/lit8", ReferenceType.none, Format.Format22b); + USHR_INT_LIT8((byte)0xe2, "ushr-int/lit8", ReferenceType.none, Format.Format22b), + + + 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), + + ; @@ -280,11 +303,17 @@ public enum Opcode public final String name; public final ReferenceType referenceType; public final Format format; - + public final boolean odexOnly; + Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format) { + this(opcodeValue, opcodeName, referenceType, format, false); + } + + Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format, boolean odexOnly) { this.value = opcodeValue; this.name = opcodeName; this.referenceType = referenceType; this.format = format; + this.odexOnly = odexOnly; } }