From ee5ca54d51a3b8a33b23caf9d84aaed63a60b1bf Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Sun, 26 Apr 2009 23:49:08 +0000 Subject: [PATCH] Added support for Format22x and Format32x git-svn-id: https://smali.googlecode.com/svn/trunk@19 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../antlr3/org/JesusFreke/smali/smaliLexer.g | 30 ++++++++ .../antlr3/org/JesusFreke/smali/smaliParser.g | 10 ++- .../org/JesusFreke/smali/smaliTreeWalker.g | 18 +++++ .../dexlib/code/Format/Format22x.java | 73 ++++++++++++++++++ .../dexlib/code/Format/Format32x.java | 76 +++++++++++++++++++ src/test/resources/examples/HelloWorld2.smali | 26 +++++++ 6 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/JesusFreke/dexlib/code/Format/Format22x.java create mode 100644 src/main/java/org/JesusFreke/dexlib/code/Format/Format32x.java diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g index 515295c0..92cf5f92 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g @@ -295,11 +295,25 @@ INSTRUCTION_FORMAT22c_FIELD_PHRASE WS FIELD_TYPE_DESCRIPTOR_EMITCHILD; +INSTRUCTION_FORMAT22x_PHRASE + : INSTRUCTION_FORMAT22x_EMIT + WS + REGISTER_EMIT + WS? ',' WS? + REGISTER_EMIT; + INSTRUCTION_FORMAT30t_PHRASE : INSTRUCTION_FORMAT30t_EMIT WS (LABEL_EMIT | OFFSET_EMIT); +INSTRUCTION_FORMAT32x_PHRASE + : INSTRUCTION_FORMAT32x_EMIT + WS + REGISTER_EMIT + WS? ',' WS? + REGISTER_EMIT; + INSTRUCTION_FORMAT35c_METHOD_PHRASE : INSTRUCTION_FORMAT35c_METHOD_EMIT WS @@ -748,11 +762,27 @@ fragment INSTRUCTION_FORMAT22c_FIELD | 'iput-short' ; +fragment INSTRUCTION_FORMAT22x_EMIT + : INSTRUCTION_FORMAT22x {emit($INSTRUCTION_FORMAT22x, INSTRUCTION_FORMAT22x);}; +fragment INSTRUCTION_FORMAT22x + : 'move/from16' + | 'move-wide/from16' + | 'move-object/from16' + ; + fragment INSTRUCTION_FORMAT30t_EMIT : INSTRUCTION_FORMAT30t {emit($INSTRUCTION_FORMAT30t, INSTRUCTION_FORMAT30t);}; fragment INSTRUCTION_FORMAT30t : 'goto/32'; +fragment INSTRUCTION_FORMAT32x_EMIT + : INSTRUCTION_FORMAT32x {emit($INSTRUCTION_FORMAT32x, INSTRUCTION_FORMAT32x);}; +fragment INSTRUCTION_FORMAT32x + : 'move/16' + | 'move-wide/16' + | 'move-object/16' + ; + fragment INSTRUCTION_FORMAT35c_METHOD_EMIT : INSTRUCTION_FORMAT35c_METHOD {emit($INSTRUCTION_FORMAT35c_METHOD, INSTRUCTION_FORMAT35c_METHOD);}; fragment INSTRUCTION_FORMAT35c_METHOD diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g index cbd50671..0e564db1 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g @@ -59,9 +59,11 @@ tokens { I_STATEMENT_FORMAT20t; I_STATEMENT_FORMAT21c_TYPE; I_STATEMENT_FORMAT21c_FIELD; - I_STATEMENT_FORMAT22c_FIELD; I_STATEMENT_FORMAT21c_STRING; + I_STATEMENT_FORMAT22c_FIELD; + I_STATEMENT_FORMAT22x; I_STATEMENT_FORMAT30t; + I_STATEMENT_FORMAT32x; I_STATEMENT_FORMAT35c_METHOD; I_STATEMENT_FORMAT3rc_METHOD; I_REGISTER_RANGE; @@ -162,9 +164,15 @@ instruction returns [int size] | //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field {$size = Format22c.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_INSTANCE_FIELD_STATEMENT"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field) + | //e.g. move/from16 v1, v1234 + INSTRUCTION_FORMAT22x REGISTER REGISTER {$size = Format22x.Format.getByteCount();} + -> ^(I_STATEMENT_FORMAT22x[$start, "I_STATEMENT_FORMAT22x"] INSTRUCTION_FORMAT22x REGISTER REGISTER) | //e.g. goto/32 endloop: INSTRUCTION_FORMAT30t (LABEL | OFFSET) {$size = Format30t.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT30t[$start, "I_STATEMENT_FORMAT30t"] INSTRUCTION_FORMAT30t LABEL? OFFSET?) + | //e.g. move/16 v4567, v1234 + INSTRUCTION_FORMAT32x REGISTER REGISTER {$size = Format32x.Format.getByteCount();} + -> ^(I_STATEMENT_FORMAT32x[$start, "I_STATEMENT_FORMAT32x"] INSTRUCTION_FORMAT32x REGISTER REGISTER) | //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V INSTRUCTION_FORMAT35c_METHOD OPEN_BRACKET register_list CLOSE_BRACKET fully_qualified_method {$size = Format35c.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT35c_METHOD[$start, "I_STATEMENT_FORMAT35c_METHOD"] INSTRUCTION_FORMAT35c_METHOD register_list fully_qualified_method) diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g index eb22a312..038a4e01 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g @@ -428,6 +428,15 @@ instruction returns[Instruction instruction] $instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem); } + | //e.g. move/from16 v1, v1234 + ^(I_STATEMENT_FORMAT22x INSTRUCTION_FORMAT22x registerA=REGISTER registerB=REGISTER) + { + Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22x.text); + short regA = parseRegister_byte($registerA.text); + int regB = parseRegister_short($registerB.text); + + $instruction = Format22x.Format.make(dexFile, opcode.value, regA, regB); + } | //e.g. goto/32 endloop: ^(I_STATEMENT_FORMAT30t INSTRUCTION_FORMAT30t offset_or_label) { @@ -437,6 +446,15 @@ instruction returns[Instruction instruction] $instruction = Format30t.Format.make(dexFile, opcode.value, addressOffset); } + | //e.g. move/16 v5678, v1234 + ^(I_STATEMENT_FORMAT32x INSTRUCTION_FORMAT32x registerA=REGISTER registerB=REGISTER) + { + Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT32x.text); + int regA = parseRegister_short($registerA.text); + int regB = parseRegister_short($registerB.text); + + $instruction = Format32x.Format.make(dexFile, opcode.value, regA, regB); + } | //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V ^(I_STATEMENT_FORMAT35c_METHOD INSTRUCTION_FORMAT35c_METHOD register_list fully_qualified_method) { diff --git a/src/main/java/org/JesusFreke/dexlib/code/Format/Format22x.java b/src/main/java/org/JesusFreke/dexlib/code/Format/Format22x.java new file mode 100644 index 00000000..0f8eba04 --- /dev/null +++ b/src/main/java/org/JesusFreke/dexlib/code/Format/Format22x.java @@ -0,0 +1,73 @@ +/* + * [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.JesusFreke.dexlib.code.Format; + +import org.JesusFreke.dexlib.code.Instruction; +import org.JesusFreke.dexlib.code.Opcode; +import org.JesusFreke.dexlib.DexFile; +import org.JesusFreke.dexlib.IndexedItem; + +public class Format22x extends Format +{ + public static final Format22x Format = new Format22x(); + + private Format22x() { + } + + public Instruction make(DexFile dexFile, byte opcode, short regA, int regB) { + byte[] bytes = new byte[4]; + + Opcode op = Opcode.getOpcodeByValue(opcode); + + checkOpcodeFormat(op); + + if (regA >= 1<<8) { + throw new RuntimeException("The register number must be less than v256"); + } + + if (regB >= 1<<16) { + throw new RuntimeException("The register number must be less than v65536"); + } + + bytes[0] = opcode; + bytes[1] = (byte)regA; + bytes[2] = (byte)regB; + bytes[3] = (byte)(regB >> 8); + + return new Instruction(dexFile, bytes, null); + } + + public int getByteCount() { + return 4; + } + + public String getFormatName() { + return "22x"; + } +} diff --git a/src/main/java/org/JesusFreke/dexlib/code/Format/Format32x.java b/src/main/java/org/JesusFreke/dexlib/code/Format/Format32x.java new file mode 100644 index 00000000..5082e1a6 --- /dev/null +++ b/src/main/java/org/JesusFreke/dexlib/code/Format/Format32x.java @@ -0,0 +1,76 @@ +/* + * [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.JesusFreke.dexlib.code.Format; + +import org.JesusFreke.dexlib.code.Instruction; +import org.JesusFreke.dexlib.code.Opcode; +import org.JesusFreke.dexlib.DexFile; +import org.JesusFreke.dexlib.IndexedItem; + +public class Format32x extends Format +{ + public static final Format32x Format = new Format32x(); + + private Format32x() { + } + + public Instruction make(DexFile dexFile, byte opcode, int regA, int regB) { + byte[] bytes = new byte[6]; + + Opcode op = Opcode.getOpcodeByValue(opcode); + + checkOpcodeFormat(op); + + if (regA >= 1<<16) { + throw new RuntimeException("The register number must be less than v65536"); + } + + if (regB >= 1<<16) { + throw new RuntimeException("The register number must be less than v65536"); + } + + bytes[0] = opcode; + + bytes[2] = (byte)regA; + bytes[3] = (byte)(regA >> 8); + + bytes[4] = (byte)regB; + bytes[5] = (byte)(regB >> 8); + + return new Instruction(dexFile, bytes, null); + } + + public int getByteCount() { + return 6; + } + + public String getFormatName() { + return "32x"; + } +} diff --git a/src/test/resources/examples/HelloWorld2.smali b/src/test/resources/examples/HelloWorld2.smali index 48427f39..88b9d26f 100644 --- a/src/test/resources/examples/HelloWorld2.smali +++ b/src/test/resources/examples/HelloWorld2.smali @@ -22,6 +22,8 @@ ;Format10t with an offset ;Format20t with a label ;Format30t with a label +;Testing Format22x and Format32x + .method static constructor ()V ;test @@ -43,6 +45,19 @@ return-void .end method + +.method public largeRegisterTest()Ljava/lang/String; + .registers 1235 + + const-string v1, "Testing Format22x and Format32x" + move-object/16 v1234, v1 + + const-string v1, "This shouldn't be displayed!" + move-object/from16 v1, v1234 + + return-object v1 +.end method + .method public onCreate(Landroid/os/Bundle;)V .registers 6 @@ -209,6 +224,17 @@ + ;test format22x and format32x + invoke-virtual {v4}, org/JesusFreke/HelloWorld2/HelloWorld2/largeRegisterTest()Ljava/lang/String; + move-result-object v1 + + invoke-virtual {v2, v1}, java/lang/String/concat(Ljava/lang/String;)Ljava/lang/String; + move-result-object v2 + + invoke-virtual {v2, v3}, java/lang/String/concat(Ljava/lang/String;)Ljava/lang/String; + move-result-object v2 + + check-cast v4, Landroid/app/Activity; invoke-virtual {v0,v2}, android/widget/TextView/setText(Ljava/lang/CharSequence;)V