diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g index 1e3aa790..43a2e744 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g @@ -321,7 +321,16 @@ INSTRUCTION_FORMAT22x_PHRASE WS REGISTER_EMIT WS? ',' WS? - REGISTER_EMIT; + REGISTER_EMIT; + +INSTRUCTION_FORMAT23x_PHRASE + : INSTRUCTION_FORMAT23x_EMIT + WS + REGISTER_EMIT + WS? ',' WS? + REGISTER_EMIT + WS? ',' WS? + REGISTER_EMIT; INSTRUCTION_FORMAT30t_PHRASE : INSTRUCTION_FORMAT30t_EMIT @@ -817,6 +826,63 @@ fragment INSTRUCTION_FORMAT22x | 'move-object/from16' ; +fragment INSTRUCTION_FORMAT23x_EMIT + : INSTRUCTION_FORMAT23x {emit($INSTRUCTION_FORMAT23x, INSTRUCTION_FORMAT23x);}; +fragment INSTRUCTION_FORMAT23x + : 'cmpl-float' + | 'cmpg-float' + | 'cmpl-double' + | 'cmpg-double' + | 'cmp-long' + | 'aget' + | 'aget-wide' + | 'aget-object' + | 'aget-boolean' + | 'aget-byte' + | 'aget-char' + | 'aget-short' + | 'aput' + | 'aput-wide' + | 'aput-object' + | 'aput-boolean' + | 'aput-byte' + | 'aput-char' + | 'aput-short' + | 'add-int' + | 'sub-int' + | 'mul-int' + | 'div-int' + | 'rem-int' + | 'and-int' + | 'or-int' + | 'xor-int' + | 'shl-int' + | 'shr-int' + | 'ushr-int' + | 'add-long' + | 'sub-long' + | 'mul-long' + | 'div-long' + | 'rem-long' + | 'and-long' + | 'or-long' + | 'xor-long' + | 'shl-long' + | 'shr-long' + | 'ushr-long' + | 'add-float' + | 'sub-float' + | 'mul-float' + | 'div-float' + | 'rem-float' + | 'add-double' + | 'sub-double' + | 'mul-double' + | 'div-double' + | 'rem-double' + ; + + fragment INSTRUCTION_FORMAT30t_EMIT : INSTRUCTION_FORMAT30t {emit($INSTRUCTION_FORMAT30t, INSTRUCTION_FORMAT30t);}; fragment INSTRUCTION_FORMAT30t diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g index 668a0651..8520a825 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g @@ -65,6 +65,7 @@ tokens { I_STATEMENT_FORMAT21t; I_STATEMENT_FORMAT22c_FIELD; I_STATEMENT_FORMAT22x; + I_STATEMENT_FORMAT23x; I_STATEMENT_FORMAT30t; I_STATEMENT_FORMAT32x; I_STATEMENT_FORMAT35c_METHOD; @@ -178,7 +179,10 @@ instruction returns [int size] -> ^(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) + -> ^(I_STATEMENT_FORMAT22x[$start, "I_STATEMENT_FORMAT22x"] INSTRUCTION_FORMAT22x REGISTER REGISTER) + | //e.g. add-int v1, v2, v3 + INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER {$size = Format23x.Format.getByteCount();} + -> ^(I_STATEMENT_FORMAT23x[$start, "I_STATEMENT_FORMAT23x"] INSTRUCTION_FORMAT23x REGISTER 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?) diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g index 58875aef..67675b6f 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g @@ -476,6 +476,16 @@ instruction returns[Instruction instruction] $instruction = Format22x.Format.make(dexFile, opcode.value, regA, regB); } + | //e.g. add-int v1, v2, v3 + ^(I_STATEMENT_FORMAT23x INSTRUCTION_FORMAT23x registerA=REGISTER registerB=REGISTER registerC=REGISTER) + { + Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT23x.text); + short regA = parseRegister_byte($registerA.text); + short regB = parseRegister_byte($registerB.text); + short regC = parseRegister_byte($registerC.text); + + $instruction = Format23x.Format.make(dexFile, opcode.value, regA, regB, regC); + } | //e.g. goto/32 endloop: ^(I_STATEMENT_FORMAT30t INSTRUCTION_FORMAT30t offset_or_label) { diff --git a/src/main/java/org/JesusFreke/dexlib/code/Format/Format23x.java b/src/main/java/org/JesusFreke/dexlib/code/Format/Format23x.java new file mode 100644 index 00000000..597ae876 --- /dev/null +++ b/src/main/java/org/JesusFreke/dexlib/code/Format/Format23x.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.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 Format23x extends Format +{ + public static final Format23x Format = new Format23x(); + + private Format23x() { + } + + public Instruction make(DexFile dexFile, byte opcode, short regA, short regB, short regC) { + 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<<8) { + throw new RuntimeException("The register number must be less than v256"); + } + + if (regC >= 1<<8) { + throw new RuntimeException("The register number must be less than v256"); + } + + bytes[0] = opcode; + bytes[1] = (byte)regA; + bytes[2] = (byte)regB; + bytes[3] = (byte)regC; + + return new Instruction(dexFile, bytes, null); + } + + public int getByteCount() { + return 4; + } + + public String getFormatName() { + return "23x"; + } +} diff --git a/src/test/resources/examples/HelloWorld2.smali b/src/test/resources/examples/HelloWorld2.smali index 437c639e..38d21929 100644 --- a/src/test/resources/examples/HelloWorld2.smali +++ b/src/test/resources/examples/HelloWorld2.smali @@ -26,6 +26,7 @@ ;-32768 ;-2147483648 ;-9223372036854775808 +;-1 .method static constructor ()V ;test @@ -111,6 +112,21 @@ HERE: return-object v2 .end method +.method public testFormat23x()Ljava/lang/String; + .registers 7 + + const-wide/16 v0, 1 + const-wide/high16 v2, 1 + + cmp-long v4, v0, v2 + + invoke-static {v4}, java/lang/Integer/toString(I)Ljava/lang/String; + move-result-object v6 + + + return-object v6 +.end method + .method public onCreate(Landroid/os/Bundle;)V .registers 6 @@ -335,6 +351,18 @@ HERE: move-result-object v2 + ;test format23x + invoke-virtual {v4}, org/JesusFreke/HelloWorld2/HelloWorld2/testFormat23x()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;