Example #1
0
  public int countIndirectBranches() {
    int res = 0;
    for (Map.Entry<AbsoluteAddress, Instruction> entry : assemblyMap.entrySet()) {
      Instruction instr = entry.getValue();

      if (instr instanceof BranchInstruction) {
        BranchInstruction branch = (BranchInstruction) instr;
        if (branch.isIndirect()) {
          // if branch target is not a memory operand pointing into a static data area of the binary
          // (imports)
          if (branch.getBranchDestination() instanceof MemoryOperand) {
            MemoryOperand memOp = (MemoryOperand) branch.getBranchDestination();
            // Import calls have only displacement
            if (memOp.getBase() == null && memOp.getIndex() == null) {
              AbsoluteAddress disp = new AbsoluteAddress(memOp.getDisplacement());
              // Check whether displacement points into import table
              ExecutableImage module = getModule(disp);
              if (module instanceof PEModule
                  && ((PEModule) module).getImportTable().containsKey(disp)) continue;
            }
          }
          res++;
          // logger.verbose(entry.getKey() + "\t" + getInstructionString(entry.getKey()));
        }
      }
    }
    return res;
  }
Example #2
0
  public LinkedList<BranchInstruction> getIndirectBranches() {
    LinkedList<BranchInstruction> indirectBranches = new LinkedList<BranchInstruction>();
    for (Map.Entry<AbsoluteAddress, Instruction> entry : assemblyMap.entrySet()) {
      Instruction instr = entry.getValue();

      if (instr instanceof BranchInstruction) {
        BranchInstruction branch = (BranchInstruction) instr;
        if (branch.isIndirect()) {
          indirectBranches.add(branch);
        }
      }
    }
    return indirectBranches;
  }
  public void visitBranchInstruction(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int offset,
      BranchInstruction branchInstruction) {
    byte opcode = branchInstruction.opcode;

    // Evaluate the target instruction blocks.
    evaluateInstructionBlock(clazz, method, codeAttribute, offset + branchInstruction.branchOffset);

    // Evaluate the instructions after a subroutine branch.
    if (opcode == InstructionConstants.OP_JSR || opcode == InstructionConstants.OP_JSR_W) {
      // We assume subroutine calls (jsr and jsr_w instructions) don't
      // change the stack, other than popping the return value.
      stackSize -= 1;

      evaluateInstructionBlock(
          clazz, method, codeAttribute, offset + branchInstruction.length(offset));
    }

    // Some branch instructions always end the current instruction block.
    exitInstructionBlock =
        opcode == InstructionConstants.OP_GOTO
            || opcode == InstructionConstants.OP_GOTO_W
            || opcode == InstructionConstants.OP_JSR
            || opcode == InstructionConstants.OP_JSR_W;
  }
Example #4
0
 /** @return complete, i.e., deep copy of this list */
 public InstructionList copy() {
   Map<InstructionHandle, InstructionHandle> map =
       new HashMap<InstructionHandle, InstructionHandle>();
   InstructionList il = new InstructionList();
   /* Pass 1: Make copies of all instructions, append them to the new list
    * and associate old instruction references with the new ones, i.e.,
    * a 1:1 mapping.
    */
   for (InstructionHandle ih = start; ih != null; ih = ih.next) {
     Instruction i = ih.instruction;
     Instruction c = i.copy(); // Use clone for shallow copy
     if (c instanceof BranchInstruction) {
       map.put(ih, il.append((BranchInstruction) c));
     } else {
       map.put(ih, il.append(c));
     }
   }
   /* Pass 2: Update branch targets.
    */
   InstructionHandle ih = start;
   InstructionHandle ch = il.start;
   while (ih != null) {
     Instruction i = ih.instruction;
     Instruction c = ch.instruction;
     if (i instanceof BranchInstruction) {
       BranchInstruction bi = (BranchInstruction) i;
       BranchInstruction bc = (BranchInstruction) c;
       InstructionHandle itarget = bi.getTarget(); // old target
       // New target is in hash map
       bc.setTarget(map.get(itarget));
       if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
         InstructionHandle[] itargets = ((Select) bi).getTargets();
         InstructionHandle[] ctargets = ((Select) bc).getTargets();
         for (int j = 0; j < itargets.length; j++) { // Update all targets
           ctargets[j] = map.get(itargets[j]);
         }
       }
     }
     ih = ih.next;
     ch = ch.next;
   }
   return il;
 }
Example #5
0
 /**
  * Redirect all references from old_target to new_target, i.e., update targets of branch
  * instructions.
  *
  * @param old_target the old target instruction handle
  * @param new_target the new target instruction handle
  */
 public void redirectBranches(InstructionHandle old_target, InstructionHandle new_target) {
   for (InstructionHandle ih = start; ih != null; ih = ih.next) {
     Instruction i = ih.getInstruction();
     if (i instanceof BranchInstruction) {
       BranchInstruction b = (BranchInstruction) i;
       InstructionHandle target = b.getTarget();
       if (target == old_target) {
         b.setTarget(new_target);
       }
       if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
         InstructionHandle[] targets = ((Select) b).getTargets();
         for (int j = 0; j < targets.length; j++) {
           if (targets[j] == old_target) {
             ((Select) b).setTarget(j, new_target);
           }
         }
       }
     }
   }
 }
Example #6
0
  public void visitBranchInstruction(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int offset,
      BranchInstruction branchInstruction) {
    // Check if the instruction is an unconditional goto instruction.
    byte opcode = branchInstruction.opcode;
    if (opcode == InstructionConstants.OP_GOTO || opcode == InstructionConstants.OP_GOTO_W) {
      // Check if the goto instruction points to another simple goto
      // instruction.
      int branchOffset = branchInstruction.branchOffset;
      int targetOffset = offset + branchOffset;

      if (branchOffset != branchInstruction.length(offset)
          && !codeAttributeEditor.isModified(offset)
          && !codeAttributeEditor.isModified(targetOffset)) {
        Instruction targetInstruction = InstructionFactory.create(codeAttribute.code, targetOffset);

        if (targetInstruction.opcode == InstructionConstants.OP_GOTO) {
          // Simplify the goto instruction.
          int targetBranchOffset = ((BranchInstruction) targetInstruction).branchOffset;

          Instruction newBranchInstruction =
              new BranchInstruction(opcode, (branchOffset + targetBranchOffset));
          codeAttributeEditor.replaceInstruction(offset, newBranchInstruction);

          // Visit the instruction, if required.
          if (extraInstructionVisitor != null) {
            extraInstructionVisitor.visitBranchInstruction(
                clazz, method, codeAttribute, offset, branchInstruction);
          }
        }
      }
    }
  }
Example #7
0
 public void setInstruction(InstructionHandle ih) {
   BranchInstruction.notifyTarget(this.ih, ih, this);
   this.ih = ih;
 }
Example #8
0
 /**
  * Initialize instruction list from byte array.
  *
  * @param code byte array containing the instructions
  */
 public InstructionList(byte[] code) {
   ByteSequence bytes = new ByteSequence(code);
   InstructionHandle[] ihs = new InstructionHandle[code.length];
   int[] pos = new int[code.length]; // Can't be more than that
   int count = 0; // Contains actual length
   /* Pass 1: Create an object for each byte code and append them
    * to the list.
    */
   try {
     while (bytes.available() > 0) {
       // Remember byte offset and associate it with the instruction
       int off = bytes.getIndex();
       pos[count] = off;
       /* Read one instruction from the byte stream, the byte position is set
        * accordingly.
        */
       Instruction i = Instruction.readInstruction(bytes);
       InstructionHandle ih;
       if (i instanceof BranchInstruction) {
         ih = append((BranchInstruction) i);
       } else {
         ih = append(i);
       }
       ih.setPosition(off);
       ihs[count] = ih;
       count++;
     }
   } catch (IOException e) {
     throw new ClassGenException(e.toString(), e);
   }
   byte_positions = new int[count]; // Trim to proper size
   System.arraycopy(pos, 0, byte_positions, 0, count);
   /* Pass 2: Look for BranchInstruction and update their targets, i.e.,
    * convert offsets to instruction handles.
    */
   for (int i = 0; i < count; i++) {
     if (ihs[i] instanceof BranchHandle) {
       BranchInstruction bi = (BranchInstruction) ihs[i].instruction;
       int target = bi.position + bi.getIndex(); /* Byte code position:
                * relative -> absolute. */
       // Search for target position
       InstructionHandle ih = findHandle(ihs, pos, count, target);
       if (ih == null) {
         throw new ClassGenException("Couldn't find target for branch: " + bi);
       }
       bi.setTarget(ih); // Update target
       // If it is a Select instruction, update all branch targets
       if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
         Select s = (Select) bi;
         int[] indices = s.getIndices();
         for (int j = 0; j < indices.length; j++) {
           target = bi.position + indices[j];
           ih = findHandle(ihs, pos, count, target);
           if (ih == null) {
             throw new ClassGenException("Couldn't find target for switch: " + bi);
           }
           s.setTarget(j, ih); // Update target
         }
       }
     }
   }
 }
 public void setEnd(InstructionHandle end) {
   BranchInstruction.notifyTarget(this.end, end, this);
   this.end = end;
 }
 public void setStart(InstructionHandle start) {
   BranchInstruction.notifyTarget(this.start, start, this);
   this.start = start;
 }