Exemple #1
0
  /**
   * Translates a OR instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The OR instruction to translate.
   * @param instructions The generated REIL code will be added to this list
   * @throws InternalTranslationException if any of the arguments are null the passed instruction is
   *     not a OR instruction
   */
  @Override
  public void translate(
      final ITranslationEnvironment environment,
      final IInstruction instruction,
      final List<ReilInstruction> instructions)
      throws InternalTranslationException {

    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "or");

    if (instruction.getOperands().size() != 2) {
      throw new InternalTranslationException(
          "Error: Argument instruction is not a or instruction (invalid number of operands)");
    }

    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;

    final List<? extends IOperandTree> operands = instruction.getOperands();

    final IOperandTree targetOperand = operands.get(0);
    final IOperandTree sourceOperand = operands.get(1);

    // Load source operand.
    final TranslationResult sourceResult =
        Helpers.translateOperand(environment, offset, sourceOperand, true);
    instructions.addAll(sourceResult.getInstructions());

    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();

    // Load destination operand.
    final TranslationResult targetResult =
        Helpers.translateOperand(environment, offset, targetOperand, true);
    instructions.addAll(targetResult.getInstructions());

    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();

    final OperandSize size = targetResult.getSize();

    final String sourceRegister = sourceResult.getRegister();
    final String targetRegister = targetResult.getRegister();

    final String orResult = environment.getNextVariableString();

    // Do the OR operation
    instructions.add(
        ReilHelpers.createOr(offset, size, sourceRegister, size, targetRegister, size, orResult));

    // Set the flags according to the result of the OR operation
    Helpers.generateBinaryOperationFlags(environment, offset + 1, orResult, size, instructions);
    offset = baseOffset + instructions.size();

    // Write the result of the OR operation back into the target operand
    Helpers.writeBack(
        environment,
        offset,
        targetOperand,
        orResult,
        size,
        targetResult.getAddress(),
        targetResult.getType(),
        instructions);
  }
  /**
   * Translates an ADD instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The ADD instruction to translate.
   * @param instructions The generated REIL code will be added to this list
   * @throws InternalTranslationException if any of the arguments are null the passed instruction is
   *     not an ADD instruction
   */
  @Override
  public void translate(
      final ITranslationEnvironment environment,
      final IInstruction instruction,
      final List<ReilInstruction> instructions)
      throws InternalTranslationException {

    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "add");

    if (instruction.getOperands().size() != 2) {
      throw new InternalTranslationException(
          "Error: Argument instruction is not a add instruction (invalid number of operands)");
    }

    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;

    final List<? extends IOperandTree> operands = instruction.getOperands();

    final IOperandTree targetOperand = operands.get(0);
    final IOperandTree sourceOperand = operands.get(1);

    // Load source operand.
    final TranslationResult sourceResult =
        Helpers.translateOperand(environment, offset, sourceOperand, true);
    instructions.addAll(sourceResult.getInstructions());

    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();

    // Load destination operand.
    final TranslationResult targetResult =
        Helpers.translateOperand(environment, offset, targetOperand, true);
    instructions.addAll(targetResult.getInstructions());

    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();

    final OperandSize size = targetResult.getSize();

    final String sourceRegister = sourceResult.getRegister();
    final String targetRegister = targetResult.getRegister();

    final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(size));
    final String carryMask = String.valueOf(Helpers.getCarryMask(size));
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size));
    final String shiftValue = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(size));
    final String shiftCarry = String.valueOf(-size.getBitSize());

    final OperandSize resultSize = TranslationHelpers.getNextSize(size);

    final String msb1 = environment.getNextVariableString();
    final String msb2 = environment.getNextVariableString();
    final String addResult = environment.getNextVariableString();
    final String msbResult = environment.getNextVariableString();
    final String msbSameBefore = environment.getNextVariableString();
    final String msbSameBeforeNeg = environment.getNextVariableString();
    final String msbChanged = environment.getNextVariableString();
    final String tempOf = environment.getNextVariableString();
    final String tempCf = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();

    // Isolate the MSBs of the two operands
    instructions.add(
        ReilHelpers.createAnd(offset, size, sourceRegister, size, msbMask, size, msb1));
    instructions.add(
        ReilHelpers.createAnd(offset + 1, size, targetRegister, size, msbMask, size, msb2));

    // Perform the addition
    instructions.add(
        ReilHelpers.createAdd(
            offset + 2, size, sourceRegister, size, targetRegister, resultSize, addResult));

    // Isolate the MSB of the result and put it into the Sign Flag
    instructions.add(
        ReilHelpers.createAnd(
            offset + 3, resultSize, addResult, resultSize, msbMask, size, msbResult));
    instructions.add(
        ReilHelpers.createBsh(
            offset + 4, size, msbResult, size, shiftValue, OperandSize.BYTE, Helpers.SIGN_FLAG));

    // Find out if the MSB of the two operands were different and whether the MSB of the first
    // operand changed
    instructions.add(
        ReilHelpers.createXor(offset + 5, size, msb1, size, msb2, size, msbSameBefore));
    instructions.add(
        ReilHelpers.createXor(
            offset + 6, size, msbSameBefore, size, msbMask, size, msbSameBeforeNeg));
    instructions.add(
        ReilHelpers.createXor(offset + 7, size, msb1, size, msbResult, size, msbChanged));
    instructions.add(
        ReilHelpers.createAnd(offset + 8, size, msbSameBeforeNeg, size, msbChanged, size, tempOf));

    // Write the result into the Overflow Flag
    instructions.add(
        ReilHelpers.createBsh(
            offset + 9, size, tempOf, size, shiftValue, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));

    // Update the Carry Flag
    instructions.add(
        ReilHelpers.createAnd(
            offset + 10, resultSize, addResult, resultSize, carryMask, resultSize, tempCf));
    instructions.add(
        ReilHelpers.createBsh(
            offset + 11,
            resultSize,
            tempCf,
            resultSize,
            shiftCarry,
            OperandSize.BYTE,
            Helpers.CARRY_FLAG));

    // Truncate the result to fit into the target
    instructions.add(
        ReilHelpers.createAnd(
            offset + 12, resultSize, addResult, resultSize, truncateMask, size, truncatedResult));

    // Update the Zero Flag
    instructions.add(
        ReilHelpers.createBisz(
            offset + 13, size, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));

    // Write the result of the ADD operation back into the target register
    Helpers.writeBack(
        environment,
        offset + 14,
        targetOperand,
        truncatedResult,
        size,
        targetResult.getAddress(),
        targetResult.getType(),
        instructions);
  }