Java tutorial
/* * Copyright (c) 2009-2010 Panxiaobo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package pxb.android.dex2jar; import org.objectweb.asm.Opcodes; /** * * * @author Panxiaobo [pxb1988@126.com] * @version $Id$ */ public final class DexOpcodeUtil implements DexOpcodes, Opcodes, DexInternalOpcode { /** * ? * * @param opcode * * @return */ public static int getSize(int opcode) { switch (opcode) { case OP_MOVE_RESULT_OBJECT: case OP_MOVE_EXCEPTION: case OP_MOVE_OBJECT: case OP_MOVE_WIDE: case OP_MOVE_RESULT: case OP_MOVE: case OP_MOVE_RESULT_WIDE: case OP_GOTO: case OP_RETURN_VOID: case OP_RETURN: case OP_RETURN_OBJECT: case OP_RETURN_WIDE: case OP_THROW: case OP_CONST_4: case OP_ARRAY_LENGTH: case OP_INT_TO_BYTE: case OP_INT_TO_CHAR: case OP_INT_TO_DOUBLE: case OP_INT_TO_FLOAT: case OP_INT_TO_LONG: case OP_INT_TO_SHORT: case OP_LONG_TO_DOUBLE: case OP_LONG_TO_FLOAT: case OP_LONG_TO_INT: case OP_DOUBLE_TO_FLOAT: case OP_DOUBLE_TO_INT: case OP_DOUBLE_TO_LONG: case OP_FLOAT_TO_INT: case OP_FLOAT_TO_DOUBLE: case OP_FLOAT_TO_LONG: case OP_ADD_INT_2ADDR: case OP_SUB_INT_2ADDR: case OP_MUL_INT_2ADDR: case OP_DIV_INT_2ADDR: case OP_REM_INT_2ADDR: case OP_AND_INT_2ADDR: case OP_OR_INT_2ADDR: case OP_XOR_INT_2ADDR: case OP_SHL_INT_2ADDR: case OP_SHR_INT_2ADDR: case OP_USHR_INT_2ADDR: case OP_ADD_LONG_2ADDR: case OP_SUB_LONG_2ADDR: case OP_MUL_LONG_2ADDR: case OP_DIV_LONG_2ADDR: case OP_REM_LONG_2ADDR: case OP_AND_LONG_2ADDR: case OP_OR_LONG_2ADDR: case OP_XOR_LONG_2ADDR: case OP_SHL_LONG_2ADDR: case OP_SHR_LONG_2ADDR: case OP_USHR_LONG_2ADDR: case OP_ADD_FLOAT_2ADDR: case OP_SUB_FLOAT_2ADDR: case OP_MUL_FLOAT_2ADDR: case OP_DIV_FLOAT_2ADDR: case OP_REM_FLOAT_2ADDR: case OP_SUB_DOUBLE_2ADDR: case OP_DIV_DOUBLE_2ADDR: case OP_MUL_DOUBLE_2ADDR: case OP_ADD_DOUBLE_2ADDR: case OP_REM_DOUBLE_2ADDR: case OP_NEG_INT: case OP_NOT_INT: case OP_NOT_LONG: case OP_NEG_LONG: case OP_NEG_DOUBLE: case OP_NEG_FLOAT: case OP_MONITOR_ENTER: case OP_MONITOR_EXIT: // { return 1; } case OP_NEW_INSTANCE: case OP_NEW_ARRAY: case OP_MOVE_OBJECT_FROM16: case OP_MOVE_FROM16: case OP_MOVE_WIDE_FROM16: case OP_CONST_STRING: case OP_CONST_CLASS: case OP_CONST_WIDE_16: case OP_CONST_HIGH16: case OP_CONST_WIDE_HIGH16: case OP_CONST_16: case OP_GOTO_16: case OP_CHECK_CAST: case OP_INSTANCE_OF: case OP_IF_EQZ: case OP_IF_NEZ: case OP_IF_LTZ: case OP_IF_GEZ: case OP_IF_GTZ: case OP_IF_LEZ: case OP_IF_EQ: case OP_IF_NE: case OP_IF_LT: case OP_IF_GE: case OP_IF_GT: case OP_IF_LE: case OP_APUT: case OP_APUT_WIDE: case OP_APUT_OBJECT: case OP_APUT_BOOLEAN: case OP_APUT_BYTE: case OP_APUT_CHAR: case OP_APUT_SHORT: case OP_AGET: case OP_AGET_WIDE: case OP_AGET_OBJECT: case OP_AGET_BOOLEAN: case OP_AGET_BYTE: case OP_AGET_CHAR: case OP_AGET_SHORT: case OP_IGET: case OP_IGET_WIDE: case OP_IGET_OBJECT: case OP_IGET_BOOLEAN: case OP_IGET_BYTE: case OP_IGET_SHORT: case OP_IGET_CHAR: case OP_IPUT: case OP_IPUT_WIDE: case OP_IPUT_OBJECT: case OP_IPUT_BOOLEAN: case OP_IPUT_BYTE: case OP_IPUT_SHORT: case OP_IPUT_CHAR: case OP_SPUT: case OP_SPUT_WIDE: case OP_SPUT_OBJECT: case OP_SPUT_BOOLEAN: case OP_SPUT_BYTE: case OP_SPUT_CHAR: case OP_SPUT_SHORT: case OP_SGET: case OP_SGET_WIDE: case OP_SGET_OBJECT: case OP_SGET_BOOLEAN: case OP_SGET_BYTE: case OP_SGET_CHAR: case OP_SGET_SHORT: case OP_ADD_INT_LIT8: case OP_RSUB_INT_LIT8: case OP_MUL_INT_LIT8: case OP_DIV_INT_LIT8: case OP_REM_INT_LIT8: case OP_AND_INT_LIT8: case OP_OR_INT_LIT8: case OP_XOR_INT_LIT8: case OP_SHL_INT_LIT8: case OP_SHR_INT_LIT8: case OP_USHR_INT_LIT8: case OP_MUL_INT_LIT16: case OP_DIV_INT_LIT16: case OP_REM_INT_LIT16: case OP_ADD_INT_LIT16: case OP_AND_INT_LIT16: case OP_OR_INT_LIT16: case OP_XOR_INT_LIT16: case OP_ADD_INT: case OP_SUB_INT: case OP_MUL_INT: case OP_DIV_INT: case OP_REM_INT: case OP_AND_INT: case OP_OR_INT: case OP_XOR_INT: case OP_SHR_INT: case OP_SHL_INT: case OP_USHR_INT: case OP_ADD_LONG: case OP_SUB_LONG: case OP_MUL_LONG: case OP_DIV_LONG: case OP_REM_LONG: case OP_AND_LONG: case OP_OR_LONG: case OP_XOR_LONG: case OP_SHL_LONG: case OP_SHR_LONG: case OP_USHR_LONG: case OP_ADD_FLOAT: case OP_SUB_FLOAT: case OP_MUL_FLOAT: case OP_DIV_FLOAT: case OP_REM_FLOAT: case OP_ADD_DOUBLE: case OP_SUB_DOUBLE: case OP_MUL_DOUBLE: case OP_DIV_DOUBLE: case OP_REM_DOUBLE: case OP_CMP_LONG: case OP_CMPL_DOUBLE: case OP_CMPG_DOUBLE: case OP_CMPL_FLOAT: case OP_CMPG_FLOAT: // { return 2; } case OP_INVOKE_VIRTUAL: case OP_INVOKE_DIRECT: case OP_INVOKE_STATIC: case OP_INVOKE_INTERFACE: case OP_INVOKE_SUPER: case OP_INVOKE_DIRECT_RANGE: case OP_INVOKE_INTERFACE_RANGE: case OP_INVOKE_STATIC_RANGE: case OP_INVOKE_SUPER_RANGE: case OP_INVOKE_VIRTUAL_RANGE: case OP_CONST: case OP_FILLED_NEW_ARRAY: case OP_FILLED_NEW_ARRAY_RANGE: case OP_CONST_WIDE_32: case OP_CONST_STRING_JUMBO: // { return 3; } // case OP_CONST_WIDE: { // i += 5; // in.skip(9); // } // break; case OP_NOP: return 0; case OP_FILL_ARRAY_DATA: case OP_SPARSE_SWITCH: case OP_PACKED_SWITCH: { return -1; } case OP_CONST_WIDE: return 5; default: return Integer.MAX_VALUE; // throw new // RuntimeException(String.format("Not support Opcode :[0x%04x]", // opcode)); } } /** * dexjvm * * @param dexOpcode * dex * @return */ public static int mapOpcode(int dexOpcode) { switch (dexOpcode) { case OP_ADD_INT_LIT8: return IADD; case OP_MUL_INT_LIT8: return IMUL; case OP_DIV_INT_LIT8: return IDIV; case OP_REM_INT_LIT8: return IREM; case OP_AND_INT_LIT8: return IAND; case OP_OR_INT_LIT8: return IOR; case OP_XOR_INT_LIT8: return IXOR; case OP_SHR_INT_LIT8: return ISHR; case OP_USHR_INT_LIT8: return IUSHR; case OP_SHL_INT_LIT8: return ISHL; // & case OP_AND_INT_2ADDR: return IAND; case OP_AND_LONG_2ADDR: return LAND; // | case OP_OR_INT_2ADDR: return IOR; case OP_OR_LONG_2ADDR: return LOR; // ^ case OP_XOR_INT_2ADDR: return IXOR; case OP_XOR_LONG_2ADDR: return LXOR; // + case OP_ADD_INT_2ADDR: return IADD; case OP_ADD_LONG_2ADDR: return LADD; case OP_ADD_FLOAT_2ADDR: return FADD; case OP_ADD_DOUBLE_2ADDR: return DADD; // - case OP_SUB_INT_2ADDR: return ISUB; case OP_SUB_LONG_2ADDR: return LSUB; case OP_SUB_FLOAT_2ADDR: return FSUB; case OP_SUB_DOUBLE_2ADDR: return DSUB; // * case OP_MUL_INT_2ADDR: return IMUL; case OP_MUL_LONG_2ADDR: return LMUL; case OP_MUL_FLOAT_2ADDR: return FMUL; case OP_MUL_DOUBLE_2ADDR: return DMUL; // / case OP_DIV_INT_2ADDR: return IDIV; case OP_DIV_LONG_2ADDR: return LDIV; case OP_DIV_FLOAT_2ADDR: return FDIV; case OP_DIV_DOUBLE_2ADDR: return DDIV; case OP_REM_LONG_2ADDR: return LREM; case OP_REM_INT_2ADDR: return IREM; case OP_REM_DOUBLE_2ADDR: return DREM; case OP_REM_FLOAT_2ADDR: return FREM; // shr case OP_SHR_INT_2ADDR: return ISHR; case OP_SHR_LONG_2ADDR: return LSHR; // ushr case OP_USHR_INT_2ADDR: return IUSHR; case OP_USHR_LONG_2ADDR: return LUSHR; // shl case OP_SHL_INT_2ADDR: return ISHL; case OP_SHL_LONG_2ADDR: return LSHL; case OP_AND_LONG: return LAND; case OP_AND_INT: return IAND; case OP_OR_LONG: return LOR; case OP_OR_INT: return IOR; case OP_XOR_LONG: return LXOR; case OP_XOR_INT: return IXOR; case OP_SHR_INT: return ISHR; case OP_SHL_INT: return ISHL; case OP_USHR_INT: return IUSHR; case OP_SHR_LONG: return LSHR; case OP_SHL_LONG: return LSHL; case OP_USHR_LONG: return LUSHR; case OP_ADD_INT: return IADD; case OP_ADD_LONG: return LADD; case OP_ADD_FLOAT: return FADD; case OP_ADD_DOUBLE: return DADD; case OP_SUB_FLOAT: return FSUB; case OP_SUB_DOUBLE: return DSUB; case OP_SUB_INT: return ISUB; case OP_SUB_LONG: return LSUB; case OP_DIV_INT: return IDIV; case OP_DIV_LONG: return LDIV; case OP_DIV_FLOAT: return FDIV; case OP_DIV_DOUBLE: return DDIV; case OP_MUL_INT: return IMUL; case OP_MUL_LONG: return LMUL; case OP_MUL_FLOAT: return FMUL; case OP_MUL_DOUBLE: return FMUL; case OP_CMP_LONG: return LCMP; case OP_REM_LONG: return LREM; case OP_REM_INT: return IREM; case OP_REM_FLOAT: return FREM; case OP_REM_DOUBLE: return DREM; case OP_CMPL_DOUBLE: return DCMPL; case OP_CMPL_FLOAT: return FCMPL; case OP_CMPG_DOUBLE: return DCMPG; case OP_CMPG_FLOAT: return FCMPG; case OP_MUL_INT_LIT16: return IMUL; case OP_DIV_INT_LIT16: return IDIV; case OP_REM_INT_LIT16: return IREM; case OP_ADD_INT_LIT16: return IADD; case OP_AND_INT_LIT16: return IAND; case OP_OR_INT_LIT16: return IOR; case OP_XOR_INT_LIT16: return IXOR; case OP_NEG_INT: return INEG; case OP_NEG_DOUBLE: return DNEG; case OP_NEG_FLOAT: return FNEG; case OP_NEG_LONG: return LNEG; case OP_IF_EQ: return IF_ICMPEQ; case OP_IF_NE: return IF_ICMPNE; case OP_IF_GE: return IF_ICMPGE; case OP_IF_LE: return IF_ICMPLE; case OP_IF_LT: return IF_ICMPLT; case OP_IF_GT: return IF_ICMPGT; case OP_INT_TO_BYTE: return I2B; case OP_INT_TO_SHORT: return I2S; case OP_INT_TO_CHAR: return I2C; case OP_INT_TO_FLOAT: return I2F; case OP_INT_TO_LONG: return I2L; case OP_INT_TO_DOUBLE: return I2D; case OP_LONG_TO_DOUBLE: return L2D; case OP_LONG_TO_FLOAT: return L2F; case OP_LONG_TO_INT: return L2I; case OP_DOUBLE_TO_FLOAT: return D2F; case OP_DOUBLE_TO_INT: return D2I; case OP_DOUBLE_TO_LONG: return D2L; case OP_FLOAT_TO_INT: return F2I; case OP_FLOAT_TO_LONG: return F2L; case OP_FLOAT_TO_DOUBLE: return F2D; case OP_ARRAY_LENGTH: return ARRAYLENGTH; case OP_APUT: // int return IASTORE; case OP_APUT_BOOLEAN: case OP_APUT_BYTE: return BASTORE; case OP_APUT_CHAR: return CASTORE; case OP_APUT_OBJECT: return AASTORE; case OP_APUT_SHORT: return SASTORE; case OP_APUT_WIDE: // long return LASTORE; case OP_AGET: return IALOAD; case OP_AGET_BOOLEAN: case OP_AGET_BYTE: return BALOAD; case OP_AGET_CHAR: return CALOAD; case OP_AGET_SHORT: return SALOAD; case OP_AGET_WIDE: return LALOAD; default: throw new RuntimeException("Not support " + DexOpcodeDump.dump(dexOpcode)); } } }