diff --git a/smali/src/main/antlr3/org/jf/smali/smaliLexer.g b/smali/src/main/antlr3/org/jf/smali/smaliLexer.g index 074ce8b7..ce6d9c6f 100644 --- a/smali/src/main/antlr3/org/jf/smali/smaliLexer.g +++ b/smali/src/main/antlr3/org/jf/smali/smaliLexer.g @@ -421,6 +421,13 @@ INSTRUCTION_FORMAT35c_TYPE_PHRASE WS? COMMA_EMIT WS? NONVOID_TYPE_DESCRIPTOR_EMITCHILD; +INSTRUCTION_FORMAT35ms_METHOD_PHRASE + : INSTRUCTION_FORMAT35ms_METHOD_EMIT + WS + REGISTER_LIST_EMITCHILDREN + WS? COMMA_EMIT WS? + VTABLE_OFFSET_EMIT; + INSTRUCTION_FORMAT3rc_METHOD_PHRASE : INSTRUCTION_FORMAT3rc_METHOD_EMIT WS @@ -738,6 +745,18 @@ fragment REFERENCE_TYPE_DESCRIPTOR_EMITCHILD : CLASS_DESCRIPTOR_EMIT | ARRAY_DESCRIPTOR_EMIT; +fragment VTABLE_OFFSET_EMIT + : VTABLE_OFFSET {emit($VTABLE_OFFSET, VTABLE_OFFSET);}; + +fragment VTABLE_OFFSET + : 'vtable@0x' + ( + '0'..'9' + | 'a'..'f' + | 'A'..'F' + )+ + ; + fragment PRIMITIVE_TYPE_EMIT : PRIMITIVE_TYPE {emit($PRIMITIVE_TYPE, PRIMITIVE_TYPE);}; @@ -1421,6 +1440,14 @@ fragment INSTRUCTION_FORMAT35c_TYPE_EMIT fragment INSTRUCTION_FORMAT35c_TYPE : 'filled-new-array'; +fragment INSTRUCTION_FORMAT35ms_METHOD_EMIT + : INSTRUCTION_FORMAT35ms_METHOD {emit($INSTRUCTION_FORMAT35ms_METHOD, INSTRUCTION_FORMAT35ms_METHOD);}; +fragment INSTRUCTION_FORMAT35ms_METHOD + : 'execute-inline' + | 'invoke-virtual-quick' + | 'invoke-super-quick' + ; + fragment INSTRUCTION_FORMAT3rc_METHOD_EMIT : INSTRUCTION_FORMAT3rc_METHOD {emit($INSTRUCTION_FORMAT3rc_METHOD, INSTRUCTION_FORMAT3rc_METHOD);}; fragment INSTRUCTION_FORMAT3rc_METHOD diff --git a/smali/src/main/antlr3/org/jf/smali/smaliParser.g b/smali/src/main/antlr3/org/jf/smali/smaliParser.g index f634e7fe..d5b1eefb 100644 --- a/smali/src/main/antlr3/org/jf/smali/smaliParser.g +++ b/smali/src/main/antlr3/org/jf/smali/smaliParser.g @@ -443,6 +443,11 @@ instruction returns [int size] | //e.g. filled-new-array {v0,v1}, I INSTRUCTION_FORMAT35c_TYPE OPEN_BRACE register_list CLOSE_BRACE nonvoid_type_descriptor {$size = Format.Format35c.size;} -> ^(I_STATEMENT_FORMAT35c_TYPE[$start, "I_STATEMENT_FORMAT35c_TYPE"] INSTRUCTION_FORMAT35c_TYPE register_list nonvoid_type_descriptor) + | //e.g. invoke-virtual-range {v0, v1} vtable@0x4 + INSTRUCTION_FORMAT35ms_METHOD OPEN_BRACE register_list CLOSE_BRACE VTABLE_OFFSET + { + throw new OdexedInstructionException(input, $INSTRUCTION_FORMAT35ms_METHOD.text); + } | //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder; INSTRUCTION_FORMAT3rc_METHOD OPEN_BRACE register_range CLOSE_BRACE fully_qualified_method {$size = Format.Format3rc.size;} -> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method) diff --git a/smali/src/main/java/org/jf/smali/OdexedInstructionException.java b/smali/src/main/java/org/jf/smali/OdexedInstructionException.java new file mode 100644 index 00000000..82ed73d4 --- /dev/null +++ b/smali/src/main/java/org/jf/smali/OdexedInstructionException.java @@ -0,0 +1,46 @@ +/* + * [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.smali; + +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.IntStream; + +public class OdexedInstructionException extends RecognitionException { + private String odexedInstruction; + + OdexedInstructionException(IntStream input, String odexedInstruction) { + super(input); + this.odexedInstruction = odexedInstruction; + } + + public String getMessage() { + return odexedInstruction + " is an odexed instruction. You cannot recompile a disassembled odex file " + + "unless it has been deodexed."; + } +}