diff --git a/smali/src/main/antlr3/org/jf/smali/smaliParser.g b/smali/src/main/antlr3/org/jf/smali/smaliParser.g index 1d957c59..d7ad2169 100644 --- a/smali/src/main/antlr3/org/jf/smali/smaliParser.g +++ b/smali/src/main/antlr3/org/jf/smali/smaliParser.g @@ -139,12 +139,14 @@ tokens { package org.jf.smali; import org.jf.dexlib.Code.Format.*; +import org.jf.dexlib.Code.Opcode; } @members { private boolean verboseErrors = false; private boolean allowOdex = false; + private int apiLevel; public void setVerboseErrors(boolean verboseErrors) { this.verboseErrors = verboseErrors; @@ -154,6 +156,10 @@ import org.jf.dexlib.Code.Format.*; this.allowOdex = allowOdex; } + public void setApiLevel(int apiLevel) { + this.apiLevel = apiLevel; + } + public String getErrorMessage(RecognitionException e, String[] tokenNames) { @@ -710,7 +716,7 @@ instruction returns [int size] | //e.g. throw-verification-error generic-error, Lsome/class; INSTRUCTION_FORMAT20bc VERIFICATION_ERROR_TYPE COMMA verification_error_reference {$size += Format.Format20bc.size;} { - if (!allowOdex) { + if (!allowOdex || Opcode.getOpcodeByName($INSTRUCTION_FORMAT20bc.text) == null || apiLevel >= 14) { throwOdexedInstructionException(input, $INSTRUCTION_FORMAT20bc.text); } } @@ -725,7 +731,7 @@ instruction returns [int size] | //e.g. sget-object-volatile v0, java/lang/System/out LJava/io/PrintStream; INSTRUCTION_FORMAT21c_FIELD_ODEX REGISTER COMMA fully_qualified_field {$size = Format.Format21c.size;} { - if (!allowOdex) { + if (!allowOdex || Opcode.getOpcodeByName($INSTRUCTION_FORMAT21c_FIELD_ODEX.text) == null || apiLevel >= 14) { throwOdexedInstructionException(input, $INSTRUCTION_FORMAT21c_FIELD_ODEX.text); } } @@ -754,7 +760,7 @@ instruction returns [int size] | //e.g. iput-object-volatile v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; INSTRUCTION_FORMAT22c_FIELD_ODEX REGISTER COMMA REGISTER COMMA fully_qualified_field {$size = Format.Format22c.size;} { - if (!allowOdex) { + if (!allowOdex || Opcode.getOpcodeByName($INSTRUCTION_FORMAT22c_FIELD_ODEX.text) == null || apiLevel >= 14) { throwOdexedInstructionException(input, $INSTRUCTION_FORMAT22c_FIELD_ODEX.text); } } diff --git a/smali/src/main/java/org/jf/smali/main.java b/smali/src/main/java/org/jf/smali/main.java index 39765a92..e65f4e65 100644 --- a/smali/src/main/java/org/jf/smali/main.java +++ b/smali/src/main/java/org/jf/smali/main.java @@ -197,7 +197,7 @@ public class main { boolean errors = false; for (File file: filesToProcess) { - if (!assembleSmaliFile(file, dexFile, verboseErrors, oldLexer, printTokens, allowOdex)) { + if (!assembleSmaliFile(file, dexFile, verboseErrors, oldLexer, printTokens, allowOdex, apiLevel)) { errors = true; } } @@ -272,7 +272,7 @@ public class main { } private static boolean assembleSmaliFile(File smaliFile, DexFile dexFile, boolean verboseErrors, boolean oldLexer, - boolean printTokens, boolean allowOdex) + boolean printTokens, boolean allowOdex, int apiLevel) throws Exception { CommonTokenStream tokens; @@ -311,6 +311,7 @@ public class main { smaliParser parser = new smaliParser(tokens); parser.setVerboseErrors(verboseErrors); parser.setAllowOdex(allowOdex); + parser.setApiLevel(apiLevel); smaliParser.smali_file_return result = parser.smali_file();