• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * [The "BSD licence"]
3  * Copyright (c) 2010 Ben Gruver (JesusFreke)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 package org.jf.dexlib.Code;
30 
31 import org.jf.dexlib.Code.Format.*;
32 import org.jf.dexlib.DexFile;
33 import org.jf.dexlib.Util.ExceptionWithContext;
34 import org.jf.dexlib.Util.Hex;
35 
36 public class InstructionIterator {
IterateInstructions(DexFile dexFile, byte[] insns, ProcessInstructionDelegate delegate)37     public static void IterateInstructions(DexFile dexFile, byte[] insns, ProcessInstructionDelegate delegate) {
38         int insnsPosition = 0;
39 
40         while (insnsPosition < insns.length) {
41             try
42             {
43                 short opcodeValue = (short)(insns[insnsPosition] & 0xFF);
44                 if (opcodeValue == 0xFF) {
45                     opcodeValue = (short)((0xFF << 8) | insns[insnsPosition+1]);
46                 }
47 
48                 Opcode opcode = Opcode.getOpcodeByValue(opcodeValue);
49 
50                 Instruction instruction = null;
51 
52                 if (opcode == null) {
53                     System.err.println(String.format("unknown opcode encountered - %x. Treating as nop.",
54                             (opcodeValue & 0xFFFF)));
55                     instruction = new UnknownInstruction(opcodeValue);
56                 } else {
57                     if (opcode == Opcode.NOP) {
58                         byte secondByte = insns[insnsPosition + 1];
59                         switch (secondByte) {
60                             case 0:
61                             {
62                                 instruction = new Instruction10x(Opcode.NOP, insns, insnsPosition);
63                                 break;
64                             }
65                             case 1:
66                             {
67                                 instruction = new PackedSwitchDataPseudoInstruction(insns, insnsPosition);
68                                 break;
69                             }
70                             case 2:
71                             {
72                                 instruction = new SparseSwitchDataPseudoInstruction(insns, insnsPosition);
73                                 break;
74                             }
75                             case 3:
76                             {
77                                 instruction = new ArrayDataPseudoInstruction(insns, insnsPosition);
78                                 break;
79                             }
80                         }
81                     } else {
82                         instruction = opcode.format.Factory.makeInstruction(dexFile, opcode, insns, insnsPosition);
83                     }
84                 }
85 
86                 assert instruction != null;
87 
88                 delegate.ProcessInstruction(insnsPosition/2, instruction);
89                 insnsPosition += instruction.getSize(insnsPosition/2)*2;
90             } catch (Exception ex) {
91                 throw ExceptionWithContext.withContext(ex, "Error occured at code address " + insnsPosition * 2);
92             }
93         }
94     }
95 
96     public static interface ProcessInstructionDelegate {
ProcessInstruction(int codeAddress, Instruction instruction)97         public void ProcessInstruction(int codeAddress, Instruction instruction);
98     }
99 }
100