Search in sources :

Example 1 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.

the class ShlTranslator method translate.

// TODO(timkornau): Check this code again
/**
   * Translates a SHL instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The SHL 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 SHL instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
    Preconditions.checkNotNull(instruction, "Error: Argument instruction can't be null");
    Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
    if (!instruction.getMnemonic().equals("shl") && !instruction.getMnemonic().equals("sal")) {
        throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (wrong mnemonic)");
    }
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    final List<? extends IOperandTree> operands = instruction.getOperands();
    // Load source operand.
    final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
    instructions.addAll(firstResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    // Load destination operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
    instructions.addAll(secondResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final OperandSize size1 = firstResult.getSize();
    final OperandSize size2 = secondResult.getSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
    final String operand1 = firstResult.getRegister();
    final String operand2 = secondResult.getRegister();
    final String shiftMsbLsbValue = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(size1));
    final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(size1));
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
    final String modValue = String.valueOf(size1.getBitSize());
    final String carryMask = String.valueOf(Helpers.getCarryMask(size1));
    final String shiftCarryValue = String.valueOf(-size1.getBitSize());
    final String shiftMask = environment.getNextVariableString();
    final String shiftMaskZero = environment.getNextVariableString();
    final String shiftMaskLessOne = environment.getNextVariableString();
    final String shiftMaskOne = environment.getNextVariableString();
    final String result = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    final String msbResult = environment.getNextVariableString();
    final String carryResult = environment.getNextVariableString();
    final int before = instructions.size();
    final List<ReilInstruction> writebackInstructions = new ArrayList<>();
    // Write the result of the SHR operation back into the target register
    Helpers.writeBack(environment, offset + 16, operands.get(0), truncatedResult, size1, firstResult.getAddress(), firstResult.getType(), writebackInstructions);
    // Make sure to shift less than the size1 of the register
    instructions.add(ReilHelpers.createMod(offset, size2, operand2, size2, modValue, size2, shiftMask));
    // Find out if the shift mask is 0 and negate the result
    instructions.add(ReilHelpers.createBisz(offset + 1, size2, shiftMask, OperandSize.BYTE, shiftMaskZero));
    // Find out if the shift mask is 1
    instructions.add(ReilHelpers.createSub(offset + 2, size2, "1", size2, shiftMask, size2, shiftMaskLessOne));
    instructions.add(ReilHelpers.createBisz(offset + 3, size2, shiftMaskLessOne, OperandSize.BYTE, shiftMaskOne));
    // Perform the shift
    instructions.add(ReilHelpers.createBsh(offset + 4, size1, operand1, size2, shiftMask, resultSize, result));
    // Truncate the result to the correct size1
    instructions.add(ReilHelpers.createAnd(offset + 5, resultSize, result, size1, truncateMask, size1, truncatedResult));
    // Don't change the flags if the shift value was zero (jump to writeBack).
    final String jmpGoalWriteBack = String.format("%d.%d", instruction.getAddress().toLong(), before + 16);
    instructions.add(ReilHelpers.createJcc(offset + 6, OperandSize.BYTE, shiftMaskZero, OperandSize.ADDRESS, jmpGoalWriteBack));
    // Extract the MSB of the result and shift it into the SF
    instructions.add(ReilHelpers.createAnd(offset + 7, resultSize, result, resultSize, msbMask, resultSize, msbResult));
    instructions.add(ReilHelpers.createBsh(offset + 8, resultSize, msbResult, resultSize, shiftMsbLsbValue, OperandSize.BYTE, Helpers.SIGN_FLAG));
    // Set the CF to the MSB of the result
    instructions.add(ReilHelpers.createAnd(offset + 9, resultSize, result, resultSize, carryMask, resultSize, carryResult));
    instructions.add(ReilHelpers.createBsh(offset + 10, resultSize, carryResult, resultSize, shiftCarryValue, OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Set the ZF
    instructions.add(ReilHelpers.createBisz(offset + 11, size1, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
    // The OF needs to be set to a different value if the shift-mask was 1
    final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), before + 15);
    instructions.add(ReilHelpers.createJcc(offset + 12, OperandSize.BYTE, shiftMaskOne, OperandSize.ADDRESS, jmpGoal2));
    // Set the OF to undefined if the shift-mask was positive but not 1
    instructions.add(ReilHelpers.createUndef(offset + 13, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Jump to writeBack.
    instructions.add(ReilHelpers.createJcc(offset + 14, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalWriteBack));
    // Set the OF if the shift-mask was 1.
    instructions.add(ReilHelpers.createXor(offset + 15, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Write back to the target register.
    instructions.addAll(writebackInstructions);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 2 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.

the class ShldTranslator method translate.

/**
   * Translates a SHL instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The SHL 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 SHL instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "shld");
    if (instruction.getOperands().size() != 3) {
        throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (invalid number of operands)");
    }
    // Distinct behaviour:
    // 1. Shift value is 0
    // 2. Shift value is 1
    // 3. Shift value is too large
    // 4. Shift value has right size
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    final List<? extends IOperandTree> operands = instruction.getOperands();
    // Load target value
    final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
    instructions.addAll(firstResult.getInstructions());
    offset = baseOffset + instructions.size();
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
    instructions.addAll(secondResult.getInstructions());
    offset = baseOffset + instructions.size();
    // Load shift value
    final TranslationResult thirdResult = Helpers.translateOperand(environment, offset, operands.get(2), true);
    instructions.addAll(thirdResult.getInstructions());
    final String truncatedShiftValue = environment.getNextVariableString();
    final String truncatedShiftValueZero = environment.getNextVariableString();
    offset = baseOffset + instructions.size();
    // Test whether the shift value is zero (leads to no operation)
    instructions.add(ReilHelpers.createAnd(offset++, thirdResult.getSize(), thirdResult.getRegister(), OperandSize.BYTE, "31", OperandSize.BYTE, truncatedShiftValue));
    instructions.add(ReilHelpers.createBisz(offset++, OperandSize.BYTE, truncatedShiftValue, OperandSize.BYTE, truncatedShiftValueZero));
    final int jumpInsertIndex1 = (int) (offset - baseOffset);
    offset++;
    // Placeholder for jcc
    // instructions.add(ReilHelpers.createJcc(offset++, OperandSize.BYTE, truncatedShiftValue,
    // OperandSize.ADDRESS, endAddress));
    // If a shift happens, AF is undefined
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
    // Test whether the shift value is too large (leads to an undefined result)
    final String sizeSubtractionResult = environment.getNextVariableString();
    final String sizeMaskingResult = environment.getNextVariableString();
    instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, String.valueOf(firstResult.getSize().getBitSize()), OperandSize.BYTE, truncatedShiftValue, OperandSize.WORD, sizeSubtractionResult));
    instructions.add(ReilHelpers.createAnd(offset++, OperandSize.WORD, sizeSubtractionResult, OperandSize.WORD, String.valueOf(0x8000), OperandSize.WORD, sizeMaskingResult));
    final int jumpInsertIndex2 = (int) (offset - baseOffset);
    offset++;
    // Placeholder for createJcc(offset++, OperandSize.WORD, sizeMaskingResult, OperandSize.ADDRESS,
    // largeValueHandler));
    // From here on, we know that the shift value is valid
    final String shiftedFirstInput = environment.getNextVariableString();
    final String shiftMask = String.valueOf(firstResult.getSize().getBitSize());
    final OperandSize combinedSize = TranslationHelpers.getNextSize(firstResult.getSize());
    final OperandSize extendedSize = TranslationHelpers.getNextSize(combinedSize);
    final String combinedSource = environment.getNextVariableString();
    final String shiftedResult = environment.getNextVariableString();
    // Combine the operands into one operand
    instructions.add(ReilHelpers.createBsh(offset++, firstResult.getSize(), firstResult.getRegister(), firstResult.getSize(), shiftMask, combinedSize, shiftedFirstInput));
    instructions.add(ReilHelpers.createOr(offset++, combinedSize, shiftedFirstInput, secondResult.getSize(), secondResult.getRegister(), combinedSize, combinedSource));
    // Do the shift
    instructions.add(ReilHelpers.createBsh(offset++, combinedSize, combinedSource, OperandSize.BYTE, truncatedShiftValue, extendedSize, shiftedResult));
    // Isolate the result
    final String isolationMask = getAllButMask(combinedSize, firstResult.getSize());
    final String isolationResult = environment.getNextVariableString();
    final String shiftedIsolationResult = environment.getNextVariableString();
    instructions.add(ReilHelpers.createAnd(offset++, extendedSize, shiftedResult, combinedSize, isolationMask, combinedSize, isolationResult));
    instructions.add(ReilHelpers.createBsh(offset++, combinedSize, isolationResult, OperandSize.BYTE, "-" + shiftMask, firstResult.getSize(), shiftedIsolationResult));
    // Set the flags (TODO: Parity)
    instructions.add(ReilHelpers.createBisz(offset++, firstResult.getSize(), shiftedIsolationResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
    Helpers.generateSignFlagCode(environment, offset, shiftedIsolationResult, firstResult.getSize(), instructions);
    offset = baseOffset + instructions.size() + 2;
    final String tempCf = environment.getNextVariableString();
    final String carryMask = String.valueOf(getCarryMask(combinedSize));
    final String shiftCarryLsb = String.valueOf(-combinedSize.getBitSize());
    instructions.add(ReilHelpers.createAnd(offset++, extendedSize, shiftedResult, extendedSize, carryMask, extendedSize, tempCf));
    instructions.add(ReilHelpers.createBsh(offset++, extendedSize, tempCf, extendedSize, shiftCarryLsb, OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Store the original input value in a temp register for OF calculation
    final String tempInput = environment.getNextVariableString();
    instructions.add(ReilHelpers.createStr(offset++, firstResult.getSize(), firstResult.getRegister(), firstResult.getSize(), tempInput));
    // Write the result back
    Helpers.writeBack(environment, offset, operands.get(0), shiftedIsolationResult, firstResult.getSize(), firstResult.getAddress(), firstResult.getType(), instructions);
    offset = baseOffset + instructions.size() + 2;
    // Test whether the shift value is 1
    final String shiftValueOne = environment.getNextVariableString();
    instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, truncatedShiftValue, OperandSize.BYTE, "1", OperandSize.WORD, shiftValueOne));
    final int jumpInsertIndex3 = (int) (offset - baseOffset);
    offset++;
    // Placeholder for createJcc(offset++, OperandSize.WORD, shiftValueOne, OperandSize.ADDRESS,
    // notOneHandler));
    // The shift-value was 1 => Calculate the OF
    final String xoredMsb = environment.getNextVariableString();
    final String maskedMsb = environment.getNextVariableString();
    final long msbMask = TranslationHelpers.getMsbMask(firstResult.getSize());
    final long msbShift = TranslationHelpers.getShiftMsbLsbMask(firstResult.getSize());
    instructions.add(ReilHelpers.createXor(offset++, firstResult.getSize(), tempInput, firstResult.getSize(), shiftedIsolationResult, firstResult.getSize(), xoredMsb));
    instructions.add(ReilHelpers.createAnd(offset++, firstResult.getSize(), xoredMsb, firstResult.getSize(), String.valueOf(msbMask), firstResult.getSize(), maskedMsb));
    instructions.add(ReilHelpers.createBsh(offset++, firstResult.getSize(), maskedMsb, OperandSize.BYTE, String.valueOf(msbShift), OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    final int jumpInsertIndex4 = (int) (offset - baseOffset);
    offset++;
    // Placeholder for createJcc(offset++, OperandSize.BYTE, "1", OperandSize.ADDRESS, endAddress));
    // Handle mod-value too large
    final String largeValueHandler = String.format("%d.%d", instruction.getAddress().toLong(), offset - baseOffset);
    final IOperandTree inputOperand = operands.get(0);
    if (inputOperand.getRootNode().getChildren().get(0).getType() == com.google.security.zynamics.zylib.disassembly.ExpressionType.REGISTER) {
        final String operand = Helpers.getLeafValue(inputOperand.getRootNode());
        final String undefRegister = Helpers.getOperandSize(inputOperand) == environment.getArchitectureSize() ? operand : Helpers.getParentRegister(operand);
        instructions.add(ReilHelpers.createUndef(offset++, environment.getArchitectureSize(), undefRegister));
    }
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.CARRY_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.SIGN_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.ZERO_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.PARITY_FLAG));
    // Handle shift value > 1 || shift value too large
    final String notOneHandler = String.format("%d.%d", instruction.getAddress().toLong(), offset - baseOffset);
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // The End
    final String jmpGoalEnd = String.format("%d.%d", instruction.getAddress().toLong(), offset - baseOffset);
    instructions.add(ReilHelpers.createNop(offset++));
    instructions.add(jumpInsertIndex1, ReilHelpers.createJcc(baseOffset + jumpInsertIndex1, OperandSize.BYTE, truncatedShiftValueZero, OperandSize.ADDRESS, jmpGoalEnd));
    instructions.add(jumpInsertIndex2, ReilHelpers.createJcc(baseOffset + jumpInsertIndex2, OperandSize.WORD, sizeMaskingResult, OperandSize.ADDRESS, largeValueHandler));
    instructions.add(jumpInsertIndex3, ReilHelpers.createJcc(baseOffset + jumpInsertIndex3, OperandSize.WORD, shiftValueOne, OperandSize.ADDRESS, notOneHandler));
    instructions.add(jumpInsertIndex4, ReilHelpers.createJcc(baseOffset + jumpInsertIndex4, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalEnd));
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 3 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.

the class ShrTranslator method translate.

// TODO(timkornau): Check this code again
/**
   * Translates a SHR instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The SHR 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 SHR instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "shr");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a shr instruction (invalid number of operands)");
    }
    final long reilOffsetBase = instruction.getAddress().toLong() * 0x100;
    long offset = reilOffsetBase;
    final List<? extends IOperandTree> operands = instruction.getOperands();
    // Load source operand.
    final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
    instructions.addAll(firstResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = reilOffsetBase + instructions.size();
    // Load destination operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
    instructions.addAll(secondResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = reilOffsetBase + instructions.size();
    final OperandSize size1 = firstResult.getSize();
    final OperandSize size2 = secondResult.getSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
    final String operand1 = firstResult.getRegister();
    final String operand2 = secondResult.getRegister();
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
    final String modValue = String.valueOf(size1.getBitSize());
    final String shiftMask = environment.getNextVariableString();
    final String shiftMaskZero = environment.getNextVariableString();
    final String shiftMaskLessOne = environment.getNextVariableString();
    final String shiftMaskOne = environment.getNextVariableString();
    final String shiftMaskNeg = environment.getNextVariableString();
    final String result = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    final String incShiftMaskNeg = environment.getNextVariableString();
    final String decResult = environment.getNextVariableString();
    final int before = instructions.size();
    final List<ReilInstruction> writebackInstructions = new ArrayList<ReilInstruction>();
    // Write the result of the SHR operation back into the target register
    Helpers.writeBack(environment, offset + 17, operands.get(0), truncatedResult, size1, firstResult.getAddress(), firstResult.getType(), writebackInstructions);
    // Make sure to shift less than the size1 of the register
    instructions.add(ReilHelpers.createMod(offset, size2, operand2, size2, modValue, size2, shiftMask));
    // Find out if the shift mask is 0 and negate the result
    instructions.add(ReilHelpers.createBisz(offset + 1, size2, shiftMask, OperandSize.BYTE, shiftMaskZero));
    // Find out if the shift mask is 1
    instructions.add(ReilHelpers.createSub(offset + 2, size2, "1", size2, shiftMask, size2, shiftMaskLessOne));
    instructions.add(ReilHelpers.createBisz(offset + 3, size2, shiftMaskLessOne, OperandSize.BYTE, shiftMaskOne));
    // Negate the shift-mask => BSH to the right
    instructions.add(ReilHelpers.createSub(offset + 4, size2, "0", size2, shiftMask, size2, shiftMaskNeg));
    // Perform the shift
    instructions.add(ReilHelpers.createBsh(offset + 5, size1, operand1, size2, shiftMaskNeg, resultSize, result));
    // Truncate the result to the correct size1
    instructions.add(ReilHelpers.createAnd(offset + 6, resultSize, result, size1, truncateMask, size1, truncatedResult));
    // Don't change the flags if the shift value was zero (jump to writeBack).
    final String jmpGoalWriteBack = String.format("%d.%d", instruction.getAddress().toLong(), before + 17);
    instructions.add(ReilHelpers.createJcc(offset + 7, OperandSize.BYTE, shiftMaskZero, OperandSize.ADDRESS, jmpGoalWriteBack));
    // The SF is always 0
    instructions.add(ReilHelpers.createStr(offset + 8, OperandSize.BYTE, "0", OperandSize.BYTE, Helpers.SIGN_FLAG));
    // Set the CF to the last MSB shifted out of the register
    // Perform another shift, this time by one position less and take the LSB
    // This is only safe if the mask is not 0
    instructions.add(ReilHelpers.createAdd(offset + 9, size2, shiftMaskNeg, size2, "1", size2, incShiftMaskNeg));
    instructions.add(ReilHelpers.createBsh(offset + 10, size1, operand1, size2, incShiftMaskNeg, size1, decResult));
    instructions.add(ReilHelpers.createAnd(offset + 11, size1, decResult, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Set the ZF
    instructions.add(ReilHelpers.createBisz(offset + 12, size1, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
    // The OF needs to be set to a different value if the shift-mask was 1
    final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), before + 16);
    instructions.add(ReilHelpers.createJcc(offset + 13, OperandSize.BYTE, shiftMaskOne, OperandSize.ADDRESS, jmpGoal2));
    // Set the OF to undefined if the shift-mask was positive but not 1
    instructions.add(ReilHelpers.createUndef(offset + 14, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Jump to writeBack.
    instructions.add(ReilHelpers.createJcc(offset + 15, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalWriteBack));
    // Set the OF if the shift-mask was 1
    instructions.add(ReilHelpers.createXor(offset + 16, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Write back to the target register.
    instructions.addAll(writebackInstructions);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 4 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.

the class XchgTranslator method translate.

// TODO(timkornau): Check this code again
/**
   * Translates a XCHG instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The XCHG 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 XCHG instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "xchg");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a xchg instruction (invalid number of operands)");
    }
    final long reilOffsetBase = instruction.getAddress().toLong() * 0x100;
    long offset = reilOffsetBase;
    final List<? extends IOperandTree> operands = instruction.getOperands();
    final IOperandTree firstOperand = operands.get(0);
    final IOperandTree secondOperand = operands.get(1);
    final OperandSize archSize = environment.getArchitectureSize();
    // Load first operand.
    final TranslationResult firstResult = Helpers.translateOperand(environment, offset, firstOperand, true);
    instructions.addAll(firstResult.getInstructions());
    offset = reilOffsetBase + instructions.size();
    // Load second operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, secondOperand, true);
    instructions.addAll(secondResult.getInstructions());
    offset = reilOffsetBase + instructions.size();
    if (firstResult.getSize() != secondResult.getSize()) {
        throw new InternalTranslationException("Error: The operands of XCHG instructions must have equal size");
    }
    final OperandSize size = firstResult.getSize();
    final String firstRegister = firstResult.getRegister();
    final String secondRegister = secondResult.getRegister();
    if (firstResult.getType() == TranslationResultType.REGISTER) {
        if (secondResult.getType() == TranslationResultType.REGISTER) {
            if (size == archSize) {
                final String temp = environment.getNextVariableString();
                instructions.add(ReilHelpers.createStr(offset, size, firstRegister, size, temp));
                instructions.add(ReilHelpers.createStr(offset + 1, size, secondRegister, size, firstRegister));
                instructions.add(ReilHelpers.createStr(offset + 2, size, temp, size, secondRegister));
                Helpers.writeBack(environment, offset + instructions.size(), firstOperand, firstRegister, archSize, firstResult.getAddress(), firstResult.getType(), instructions);
                Helpers.writeBack(environment, offset + instructions.size(), secondOperand, secondRegister, archSize, secondResult.getAddress(), secondResult.getType(), instructions);
            } else {
                Helpers.writeBack(environment, offset, secondOperand, firstRegister, size, secondResult.getAddress(), secondResult.getType(), instructions);
                offset = reilOffsetBase + instructions.size();
                Helpers.writeBack(environment, offset, firstOperand, secondRegister, size, firstResult.getAddress(), firstResult.getType(), instructions);
            }
        } else if (secondResult.getType() == TranslationResultType.MEMORY_ACCESS) {
            Helpers.writeBack(environment, offset, secondOperand, firstRegister, size, secondResult.getAddress(), secondResult.getType(), instructions);
            offset = reilOffsetBase + instructions.size();
            Helpers.writeBack(environment, offset, firstOperand, secondRegister, size, firstResult.getAddress(), firstResult.getType(), instructions);
        } else {
            assert false;
        }
    } else {
        assert false;
    }
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 5 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.

the class XorTranslator method translate.

/**
   * Translates a XOR instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The XOR 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 XOR instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "xor");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a xor 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);
    // Adjust the offset of the next REIL instruction.
    instructions.addAll(targetResult.getInstructions());
    offset = baseOffset + instructions.size();
    final OperandSize size = targetResult.getSize();
    final String sourceRegister = sourceResult.getRegister();
    final String targetRegister = targetResult.getRegister();
    final String xorResult = environment.getNextVariableString();
    // Do the XOR operation
    instructions.add(ReilHelpers.createXor(offset, size, sourceRegister, size, targetRegister, size, xorResult));
    // Set the flags according to the result of the XOR operation
    Helpers.generateBinaryOperationFlags(environment, offset + 1, xorResult, size, instructions);
    offset = baseOffset + instructions.size();
    // Write the result of the XOR operation into the target register
    Helpers.writeBack(environment, offset, targetOperand, xorResult, size, targetResult.getAddress(), targetResult.getType(), instructions);
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Aggregations

TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)55 OperandSize (com.google.security.zynamics.reil.OperandSize)45 InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)42 IOperandTree (com.google.security.zynamics.zylib.disassembly.IOperandTree)39 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)9 ArrayList (java.util.ArrayList)9 TranslationResultType (com.google.security.zynamics.reil.translators.TranslationResultType)3 OperandType (com.google.security.zynamics.reil.OperandType)2 ReilOperand (com.google.security.zynamics.reil.ReilOperand)1 ReilOperandNode (com.google.security.zynamics.reil.ReilOperandNode)1 IOperandTreeNode (com.google.security.zynamics.zylib.disassembly.IOperandTreeNode)1