183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/* 283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * [The "BSD licence"] 300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke) 483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * All rights reserved. 583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without 783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions 883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * are met: 983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright 1083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer. 1183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright 1283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer in the 1383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * documentation and/or other materials provided with the distribution. 1483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products 1583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * derived from this software without specific prior written permission. 1683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 1783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 2883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 2983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compackage org.jf.dexlib.Code; 3083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 31b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.ArrayDataPseudoInstruction; 32b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.Instruction10x; 33b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.PackedSwitchDataPseudoInstruction; 34b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.SparseSwitchDataPseudoInstruction; 35b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.DexFile; 3616a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.comimport org.jf.dexlib.Util.ExceptionWithContext; 3783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport org.jf.dexlib.Util.Hex; 3883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 3983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compublic class InstructionIterator { 4016a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com public static void IterateInstructions(DexFile dexFile, byte[] insns, ProcessInstructionDelegate delegate) { 4183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int insnsPosition = 0; 4283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 4383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (insnsPosition < insns.length) { 4416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com try 4516a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com { 4616a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com Opcode opcode = Opcode.getOpcodeByValue(insns[insnsPosition]); 4783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 4816a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com Instruction instruction = null; 4916a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com 5016a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com if (opcode == null) { 5116a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com throw new RuntimeException("Unknown opcode: " + Hex.u1(insns[insnsPosition])); 5216a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com } 5383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 5416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com if (opcode == Opcode.NOP) { 5516a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com byte secondByte = insns[insnsPosition + 1]; 5683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com switch (secondByte) { 5716a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com case 0: 5816a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com { 5916a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com instruction = new Instruction10x(Opcode.NOP, insns, insnsPosition); 6016a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com break; 6116a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com } 6283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com case 1: 6383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com { 6416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com instruction = new PackedSwitchDataPseudoInstruction(insns, insnsPosition); 6583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com break; 6683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 6783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com case 2: 6883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com { 6916a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com instruction = new SparseSwitchDataPseudoInstruction(insns, insnsPosition); 7083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com break; 7183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 7283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com case 3: 7383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com { 7416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com instruction = new ArrayDataPseudoInstruction(insns, insnsPosition); 7583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com break; 7683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 7783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 7883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else { 7916a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com instruction = opcode.format.Factory.makeInstruction(dexFile, opcode, insns, insnsPosition); 8083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 8183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 8216a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com assert instruction != null; 8383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 8416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com delegate.ProcessInstruction(insnsPosition/2, instruction); 8516a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com insnsPosition += instruction.getSize(insnsPosition/2)*2; 8616a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com } catch (Exception ex) { 8716a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com throw ExceptionWithContext.withContext(ex, "Error occured at code address " + insnsPosition * 2); 8883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 8983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 9083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 9183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 9283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public static interface ProcessInstructionDelegate { 9316a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com public void ProcessInstruction(int codeAddress, Instruction instruction); 9483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 9583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com} 96