Search in sources :

Example 6 with TranslationResult

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

the class MulTranslator method translate.

/**
   * Translates a MUL instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The MUL 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 MUL instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "mul");
    if (instruction.getOperands().size() != 1) {
        throw new InternalTranslationException("Error: Argument instruction is not a mul instruction (invalid number of operand)");
    }
    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();
    final String operand1 = firstResult.getRegister();
    final String operand2 = "eax";
    final OperandSize size1 = firstResult.getSize();
    final OperandSize size2 = environment.getArchitectureSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(size2);
    final String result = environment.getNextVariableString();
    final String upperHalf = environment.getNextVariableString();
    final String upperHalfZero = environment.getNextVariableString();
    final String maskUpper = String.valueOf(TranslationHelpers.getAllButMask(resultSize, size1));
    // Multiply the operands
    instructions.add(ReilHelpers.createMul(offset, size1, operand1, size2, operand2, resultSize, result));
    // Clear the lower half of the result
    instructions.add(ReilHelpers.createAnd(offset + 1, resultSize, result, resultSize, maskUpper, resultSize, upperHalf));
    // Check whether upper half is zero
    instructions.add(ReilHelpers.createBisz(offset + 2, resultSize, upperHalf, OperandSize.BYTE, upperHalfZero));
    // CF = Upper half is zero
    instructions.add(ReilHelpers.createBisz(offset + 3, resultSize, upperHalfZero, OperandSize.BYTE, Helpers.CARRY_FLAG));
    // OF = Upper half is zero
    instructions.add(ReilHelpers.createBisz(offset + 4, resultSize, upperHalfZero, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // SF, ZF, AF and PF are undefined
    instructions.add(ReilHelpers.createUndef(offset + 5, OperandSize.BYTE, Helpers.SIGN_FLAG));
    instructions.add(ReilHelpers.createUndef(offset + 6, OperandSize.BYTE, Helpers.ZERO_FLAG));
    instructions.add(ReilHelpers.createUndef(offset + 7, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
    instructions.add(ReilHelpers.createUndef(offset + 8, OperandSize.BYTE, Helpers.PARITY_FLAG));
    instructions.addAll(Helpers.writeMulResult(environment, offset + 9, result, size1));
}
Also used : InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 7 with TranslationResult

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

the class NotTranslator method translate.

/**
   * Translates an NOT instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The NOT 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 NOT instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "not");
    if (instruction.getOperands().size() != 1) {
        throw new InternalTranslationException("Error: Argument instruction is not an not instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    // NOT instructions have exactly one operand.
    final IOperandTree operand = instruction.getOperands().get(0);
    // Load the operand.
    final TranslationResult result = Helpers.translateOperand(environment, offset, operand, true);
    instructions.addAll(result.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final String operandRegister = result.getRegister();
    final OperandSize size = result.getSize();
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size));
    final String xorResult = environment.getNextVariableString();
    // Flip all bits in the operand
    instructions.add(ReilHelpers.createXor(offset, size, operandRegister, size, truncateMask, size, xorResult));
    // Write the flipped value back to the operand
    Helpers.writeBack(environment, offset + 1, operand, xorResult, size, result.getAddress(), result.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)

Example 8 with TranslationResult

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

the class PushTranslator method translate.

/**
   * Translates a PUSH instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The PUSH 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 PUSH instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "push");
    if (instruction.getOperands().size() != 1) {
        throw new InternalTranslationException("Error: Argument instruction is not a push instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    // PUSH instructions have exactly one operand.
    final IOperandTree operand = instruction.getOperands().get(0);
    // Load the operand.
    final TranslationResult result = Helpers.translateOperand(environment, offset, operand, true);
    instructions.addAll(result.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    // A push with an 8-bit immediate is treated like a 32-bit push.    
    final OperandSize resultSize = (result.getSize() == OperandSize.BYTE) ? OperandSize.DWORD : result.getSize();
    final String loadedValue = result.getRegister();
    final String tempRegister;
    if (result.getInstructions().isEmpty() && loadedValue.equalsIgnoreCase("esp")) {
        // push esp must be handled separately
        tempRegister = environment.getNextVariableString();
        instructions.add(ReilHelpers.createStr(offset++, resultSize, loadedValue, resultSize, tempRegister));
    } else {
        tempRegister = loadedValue;
    }
    Helpers.generatePush(environment, offset, tempRegister, resultSize, 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)

Example 9 with TranslationResult

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

the class RclTranslator method translate.

// TODO:(timkornau@google.com) Check this code again
/**
   * Translates a RCL instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The RCL 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 RCL instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "rcl");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a rcl 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 target 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 sourceSize = sourceResult.getSize();
    final OperandSize targetSize = targetResult.getSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(targetSize);
    final String sourceRegister = sourceResult.getRegister();
    final String targetRegister = targetResult.getRegister();
    final String os = String.valueOf(targetSize.getBitSize());
    final String rotateMask = environment.getNextVariableString();
    final String rotateMaskZero = environment.getNextVariableString();
    final String rotateMaskLessOne = environment.getNextVariableString();
    final String rotateMaskOne = environment.getNextVariableString();
    final String shiftedCf = environment.getNextVariableString();
    final String realOp1 = environment.getNextVariableString();
    final String shrValue = environment.getNextVariableString();
    final String shredResult = environment.getNextVariableString();
    final String shledResult = environment.getNextVariableString();
    final String result = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    final String msbResult = environment.getNextVariableString();
    final String tempOf = environment.getNextVariableString();
    final String tempOfLsb = environment.getNextVariableString();
    final String carryMask = String.valueOf(Helpers.getCarryMask(targetSize));
    final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(targetSize));
    final String maskSize = String.valueOf(TranslationHelpers.getAllBitsMask(targetSize));
    // TODO: + 1 ?
    final String modVal = String.valueOf(targetSize.getBitSize() + 1);
    final String shiftMsbLsb = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(targetSize));
    final int linesBefore = instructions.size();
    // Make sure to rotate less than the size of the register
    instructions.add(ReilHelpers.createMod(offset, sourceSize, sourceRegister, sourceSize, os, OperandSize.BYTE, rotateMask));
    // Find out if the rotate mask is 0
    instructions.add(ReilHelpers.createBisz(offset + 1, OperandSize.BYTE, rotateMask, OperandSize.BYTE, rotateMaskZero));
    // Find out if the rotate mask is 1
    instructions.add(ReilHelpers.createSub(offset + 2, OperandSize.BYTE, rotateMask, OperandSize.BYTE, "1", OperandSize.BYTE, rotateMaskLessOne));
    instructions.add(ReilHelpers.createBisz(offset + 3, OperandSize.BYTE, rotateMaskLessOne, OperandSize.BYTE, rotateMaskOne));
    // Rotating through the carry flag is like rotating through a 33 bit register
    // For rotating leftwards, the CF must be added at the MSB of the 32 bit register
    instructions.add(ReilHelpers.createBsh(offset + 4, OperandSize.BYTE, Helpers.CARRY_FLAG, sourceSize, os, resultSize, shiftedCf));
    instructions.add(ReilHelpers.createOr(offset + 5, targetSize, targetRegister, resultSize, shiftedCf, resultSize, realOp1));
    // Perform the rotate
    // y = ( x << n ) | ( x >> ( ( regsize + 1 ) - n ) )
    instructions.add(ReilHelpers.createBsh(offset + 6, resultSize, realOp1, OperandSize.BYTE, rotateMask, resultSize, shledResult));
    instructions.add(ReilHelpers.createAdd(offset + 7, OperandSize.BYTE, "-" + modVal, OperandSize.BYTE, rotateMask, OperandSize.BYTE, shrValue));
    instructions.add(ReilHelpers.createBsh(offset + 8, resultSize, realOp1, OperandSize.BYTE, shrValue, resultSize, shredResult));
    instructions.add(ReilHelpers.createOr(offset + 9, resultSize, shledResult, resultSize, shredResult, resultSize, result));
    // Truncate the result
    instructions.add(ReilHelpers.createAnd(offset + 10, resultSize, result, targetSize, maskSize, targetSize, truncatedResult));
    // Don't change the flags if the rotate value was zero
    final String jmpGoal = String.format("%d.%d", instruction.getAddress().toLong(), linesBefore + 20);
    instructions.add(ReilHelpers.createJcc(offset + 11, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal));
    // Set the CF to the MSB of the untruncated result
    instructions.add(ReilHelpers.createAnd(offset + 12, resultSize, result, resultSize, carryMask, resultSize, msbResult));
    instructions.add(ReilHelpers.createBsh(offset + 13, resultSize, msbResult, resultSize, "-" + os, OperandSize.BYTE, Helpers.CARRY_FLAG));
    // The OF needs to be set to a different value if the rotate-mask was 1
    final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), linesBefore + 17);
    instructions.add(ReilHelpers.createJcc(offset + 14, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal2));
    // Set the OF to undefined if the rotate-mask was positive but not 1
    instructions.add(ReilHelpers.createUndef(offset + 15, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Jump to the end
    final String jmpGoal3 = String.format("%d.%d", instruction.getAddress().toLong(), linesBefore + 20);
    instructions.add(ReilHelpers.createJcc(offset + 16, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal3));
    // OF = MSB(DEST) XOR CF
    instructions.add(ReilHelpers.createAnd(offset + 17, sourceSize, truncatedResult, sourceSize, msbMask, sourceSize, tempOf));
    instructions.add(ReilHelpers.createBsh(offset + 18, sourceSize, tempOf, sourceSize, shiftMsbLsb, OperandSize.BYTE, tempOfLsb));
    instructions.add(ReilHelpers.createBsh(offset + 19, OperandSize.BYTE, tempOfLsb, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG));
    Helpers.writeBack(environment, offset + 20, targetOperand, truncatedResult, targetResult.getSize(), 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)

Example 10 with TranslationResult

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

the class RcrTranslator method translate.

// TODO(timkornau): Check this code again
/**
   * Translates a RCR instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The RCR 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 RCR instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "rcr");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a rcr 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 target 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 sourceSize = sourceResult.getSize();
    final OperandSize targetSize = targetResult.getSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(sourceSize);
    final String sourceRegister = sourceResult.getRegister();
    final String targetRegister = targetResult.getRegister();
    final String rotateMask = environment.getNextVariableString();
    final String rotateMaskZero = environment.getNextVariableString();
    final String rotateMaskLessOne = environment.getNextVariableString();
    final String rotateMaskOne = environment.getNextVariableString();
    final String shiftedOp1 = environment.getNextVariableString();
    final String realOp1 = environment.getNextVariableString();
    final String shrValue = environment.getNextVariableString();
    final String shredResult = environment.getNextVariableString();
    final String shlValue = environment.getNextVariableString();
    final String shledResult = environment.getNextVariableString();
    final String result = environment.getNextVariableString();
    final String shiftedResult = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    final String tempOf = environment.getNextVariableString();
    final String tempOfLsb = environment.getNextVariableString();
    final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(sourceSize));
    final String maskSize = String.valueOf(TranslationHelpers.getAllBitsMask(sourceSize));
    final String modVal = String.valueOf(sourceSize.getBitSize());
    final String shiftMsbLsb = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(sourceSize));
    // Make sure to rotate less than the size of the register
    instructions.add(ReilHelpers.createMod(offset, targetSize, targetRegister, targetSize, modVal, targetSize, rotateMask));
    // Find out if the rotate mask is 0 and negate the result
    instructions.add(ReilHelpers.createBisz(offset + 1, targetSize, rotateMask, OperandSize.BYTE, rotateMaskZero));
    // Find out if the rotate mask is 1
    instructions.add(ReilHelpers.createSub(offset + 2, targetSize, rotateMask, targetSize, "1", targetSize, rotateMaskLessOne));
    instructions.add(ReilHelpers.createBisz(offset + 3, targetSize, rotateMaskLessOne, OperandSize.BYTE, rotateMaskOne));
    // Rotating through the carry flag is like rotating through a 33 bit register
    // For rotating rightwards, the CF must be added at the LSB of the 32 register
    instructions.add(ReilHelpers.createBsh(offset + 4, sourceSize, sourceRegister, OperandSize.BYTE, "1", resultSize, shiftedOp1));
    instructions.add(ReilHelpers.createOr(offset + 5, resultSize, shiftedOp1, OperandSize.BYTE, Helpers.CARRY_FLAG, resultSize, realOp1));
    // Negate the rotate-mask => ROT to the right
    instructions.add(ReilHelpers.createSub(offset + 6, OperandSize.BYTE, "0", OperandSize.BYTE, rotateMask, OperandSize.BYTE, shrValue));
    // Perform the rotate
    instructions.add(ReilHelpers.createBsh(offset + 7, sourceSize, realOp1, OperandSize.BYTE, shrValue, sourceSize, shredResult));
    instructions.add(ReilHelpers.createSub(offset + 8, OperandSize.BYTE, modVal, OperandSize.BYTE, rotateMask, OperandSize.BYTE, shlValue));
    instructions.add(ReilHelpers.createBsh(offset + 9, sourceSize, realOp1, OperandSize.BYTE, shlValue, sourceSize, shledResult));
    instructions.add(ReilHelpers.createOr(offset + 10, sourceSize, shredResult, sourceSize, shledResult, sourceSize, result));
    // Truncate the result (get rid of the CF in the LSB)
    instructions.add(ReilHelpers.createBsh(offset + 11, resultSize, result, OperandSize.BYTE, "-1", resultSize, shiftedResult));
    instructions.add(ReilHelpers.createAnd(offset + 12, resultSize, shiftedResult, sourceSize, maskSize, sourceSize, truncatedResult));
    // Don't change the flags if the rotate value was zero
    final String jmpGoal = "666";
    instructions.add(ReilHelpers.createJcc(offset + 13, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal));
    // Properly update OF if the rotate value == 1
    final String jmpGoal2 = "666";
    instructions.add(ReilHelpers.createJcc(offset + 14, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal2));
    // Set the OF to undefined if the rotate-mask was positive but not 1
    instructions.add(ReilHelpers.createUndef(offset + 15, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Update the CF now
    final String jmpGoal3 = "666";
    instructions.add(ReilHelpers.createJcc(offset + 15, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal3));
    instructions.add(ReilHelpers.createAnd(offset + 16, sourceSize, sourceRegister, sourceSize, msbMask, sourceSize, tempOf));
    instructions.add(ReilHelpers.createBsh(offset + 17, sourceSize, tempOf, sourceSize, shiftMsbLsb, OperandSize.BYTE, tempOfLsb));
    instructions.add(ReilHelpers.createXor(offset + 18, OperandSize.BYTE, tempOfLsb, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Set the CF to the LSB of the untruncated result
    instructions.add(ReilHelpers.createAnd(offset + 19, resultSize, result, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
    Helpers.writeBack(environment, offset + 20, targetOperand, result, targetResult.getSize(), 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