From f61f3789dc87f3b0cf051413ea645f3cb188979b Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Mon, 27 Apr 2009 04:42:02 +0000 Subject: [PATCH] Added support for Format22b git-svn-id: https://smali.googlecode.com/svn/trunk@25 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../antlr3/org/JesusFreke/smali/smaliLexer.g | 25 +++++++ .../antlr3/org/JesusFreke/smali/smaliParser.g | 6 +- .../org/JesusFreke/smali/smaliTreeWalker.g | 15 ++++ .../dexlib/code/Format/Format22b.java | 73 +++++++++++++++++++ .../org/JesusFreke/dexlib/code/Opcode.java | 2 +- src/test/resources/examples/HelloWorld2.smali | 24 ++++++ 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/JesusFreke/dexlib/code/Format/Format22b.java diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g index 43a2e744..e10c577f 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g @@ -305,6 +305,15 @@ INSTRUCTION_FORMAT21t_PHRASE WS? ',' WS? (LABEL_EMIT | OFFSET_EMIT); +INSTRUCTION_FORMAT22b_PHRASE + : INSTRUCTION_FORMAT22b_EMIT + WS + REGISTER_EMIT + WS? ',' WS? + REGISTER_EMIT + WS? ',' WS? + INTEGER_LITERAL_EMIT; + INSTRUCTION_FORMAT22c_FIELD_PHRASE : INSTRUCTION_FORMAT22c_FIELD_EMIT WS @@ -799,6 +808,22 @@ fragment INSTRUCTION_FORMAT21t | 'if-lez' ; +fragment INSTRUCTION_FORMAT22b_EMIT + : INSTRUCTION_FORMAT22b {emit($INSTRUCTION_FORMAT22b, INSTRUCTION_FORMAT22b);}; +fragment INSTRUCTION_FORMAT22b + : 'add-int/lit8' + | 'rsub-int/lit8' + | 'mul-int/lit8' + | 'div-int/lit8' + | 'rem-int/lit8' + | 'and-int/lit8' + | 'or-int/lit8' + | 'xor-int/lit8' + | 'shl-int/lit8' + | 'shr-int/lit8' + | 'ushr-int/lit8' + ; + fragment INSTRUCTION_FORMAT22c_FIELD_EMIT : INSTRUCTION_FORMAT22c_FIELD {emit($INSTRUCTION_FORMAT22c_FIELD, INSTRUCTION_FORMAT22c_FIELD);}; fragment INSTRUCTION_FORMAT22c_FIELD diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g index 8520a825..b31d3db7 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g @@ -63,6 +63,7 @@ tokens { I_STATEMENT_FORMAT21h; I_STATEMENT_FORMAT21s; I_STATEMENT_FORMAT21t; + I_STATEMENT_FORMAT22b; I_STATEMENT_FORMAT22c_FIELD; I_STATEMENT_FORMAT22x; I_STATEMENT_FORMAT23x; @@ -174,7 +175,10 @@ instruction returns [int size] | //e.g. if-eqz v0, endloop: INSTRUCTION_FORMAT21t REGISTER (LABEL | OFFSET) {$size = Format21t.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT21t[$start, "I_STATEMENT_FORMAT21t"] INSTRUCTION_FORMAT21t REGISTER LABEL? OFFSET?) - | //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; + | //e.g. add-int v0, v1, 123 + INSTRUCTION_FORMAT22b REGISTER REGISTER INTEGER_LITERAL {$size = Format22b.Format.getByteCount();} + -> ^(I_STATEMENT_FORMAT22b[$start, "I_STATEMENT_FORMAT22b"] INSTRUCTION_FORMAT22b REGISTER REGISTER INTEGER_LITERAL) + | //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 diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g index 67675b6f..2b04444e 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g @@ -59,6 +59,10 @@ import org.JesusFreke.dexlib.code.Format.*; return val; } + private static byte parseIntLiteral_byte(String intLiteral) { + return Byte.parseByte(intLiteral); + } + private static short parseIntLiteral_short(String intLiteral) { return Short.parseShort(intLiteral); } @@ -456,6 +460,17 @@ instruction returns[Instruction instruction] $instruction = Format21t.Format.make(dexFile, opcode.value, regA, (short)addressOffset); } + | //e.g. add-int v0, v1, 123 + ^(I_STATEMENT_FORMAT22b INSTRUCTION_FORMAT22b registerA=REGISTER registerB=REGISTER INTEGER_LITERAL) + { + Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22b.text); + short regA = parseRegister_byte($registerA.text); + short regB = parseRegister_byte($registerB.text); + + byte litC = parseIntLiteral_byte($INTEGER_LITERAL.text); + + $instruction = Format22b.Format.make(dexFile, opcode.value, regA, regB, litC); + } | //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; ^(I_STATEMENT_FORMAT22c_FIELD INSTRUCTION_FORMAT22c_FIELD registerA=REGISTER registerB=REGISTER fully_qualified_field) { diff --git a/src/main/java/org/JesusFreke/dexlib/code/Format/Format22b.java b/src/main/java/org/JesusFreke/dexlib/code/Format/Format22b.java new file mode 100644 index 00000000..9f278dc4 --- /dev/null +++ b/src/main/java/org/JesusFreke/dexlib/code/Format/Format22b.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 Format22b extends Format +{ + public static final Format22b Format = new Format22b(); + + private Format22b() { + } + + public Instruction make(DexFile dexFile, byte opcode, short regA, short regB, byte litC) { + 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"); + } + + bytes[0] = opcode; + bytes[1] = (byte)regA; + bytes[2] = (byte)regB; + bytes[3] = litC; + + return new Instruction(dexFile, bytes, null); + } + + public int getByteCount() { + return 4; + } + + public String getFormatName() { + return "22b"; + } +} diff --git a/src/main/java/org/JesusFreke/dexlib/code/Opcode.java b/src/main/java/org/JesusFreke/dexlib/code/Opcode.java index b004e79a..f5b5f6c5 100644 --- a/src/main/java/org/JesusFreke/dexlib/code/Opcode.java +++ b/src/main/java/org/JesusFreke/dexlib/code/Opcode.java @@ -281,7 +281,7 @@ public enum Opcode } public static Opcode getOpcodeByValue(byte opcodeValue) { - return opcodesByValue.get(opcodeValue); + return opcodesByValue.get(opcodeValue & 0xFF); } public final byte value; diff --git a/src/test/resources/examples/HelloWorld2.smali b/src/test/resources/examples/HelloWorld2.smali index 38d21929..90a68f6d 100644 --- a/src/test/resources/examples/HelloWorld2.smali +++ b/src/test/resources/examples/HelloWorld2.smali @@ -27,6 +27,8 @@ ;-2147483648 ;-9223372036854775808 ;-1 +;20 + .method static constructor ()V ;test @@ -127,6 +129,18 @@ HERE: return-object v6 .end method +.method public testFormat22b()Ljava/lang/String; + .registers 2 + + const/16 v0, -10 + add-int/lit8 v1, v0, 30 + + invoke-static {v1}, java/lang/Integer/toString(I)Ljava/lang/String; + move-result-object v0 + + return-object v0 +.end method + .method public onCreate(Landroid/os/Bundle;)V .registers 6 @@ -358,6 +372,16 @@ HERE: 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 + + ;test format22b + invoke-virtual {v4}, org/JesusFreke/HelloWorld2/HelloWorld2/testFormat22b()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