Search in sources :

Example 36 with IOperandTree

use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.

the class JccTranslator method translate.

/**
   * Translates a conditional jump instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The conditional jump 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 conditional jump 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");
    Preconditions.checkArgument(instruction.getOperands().size() == 1, "Error: Argument instruction is not a conditional jump instruction (invalid number of operands)");
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    // JCC 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());
    final String jumpTarget = result.getRegister();
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final Pair<OperandSize, String> condition = conditionGenerator.generate(environment, offset, instructions);
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    instructions.add(ReilHelpers.createJcc(offset, condition.first(), condition.second(), environment.getArchitectureSize(), jumpTarget));
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 37 with IOperandTree

use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.

the class LeaTranslator method translate.

// TODO: Check the code again
/**
   * Translates a LEA instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The LEA 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 LAHF instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "lea");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a lea 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);
    // The first operand must be a register.
    final String destination = Helpers.getLeafValue(targetOperand.getRootNode());
    final OperandSize size = Helpers.getOperandSize(targetOperand);
    // Load the operand.
    final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, false);
    String sourceRegister = sourceResult.getRegister() != null ? sourceResult.getRegister() : sourceResult.getAddress();
    sourceResult.getType();
    final List<ReilInstruction> sourceInstructions = sourceResult.getInstructions();
    // The source operand must always be loaded.
    instructions.addAll(sourceInstructions);
    // Adjust the offset of the next REIL instruction
    offset = baseOffset + instructions.size();
    if (size == OperandSize.WORD) {
        // Destination size is a sub-register
        final OperandType operandType = OperandType.getOperandType(sourceRegister);
        if (operandType == OperandType.INTEGER_LITERAL) {
            // Integer literals can be truncated directly.
            sourceRegister = String.valueOf(Long.valueOf(sourceRegister) & 0xFFFF);
        } else if (operandType == OperandType.REGISTER) {
            // Registers must be truncated later
            // => Add an AND instruction that truncates.
            final String truncatedValue = environment.getNextVariableString();
            final OperandSize registerSize = sourceInstructions.size() == 0 ? Helpers.getRegisterSize(sourceRegister) : environment.getArchitectureSize();
            // Add the truncating instruction
            instructions.add(ReilHelpers.createAnd(offset, registerSize, sourceRegister, OperandSize.WORD, "65535", OperandSize.WORD, truncatedValue));
            offset++;
            sourceRegister = truncatedValue;
        } else {
            // Shouldn't be possible.
            assert false;
        }
        // Write the loaded value into the destination register.
        Helpers.writeBack(environment, offset, targetOperand, sourceRegister, size, null, TranslationResultType.REGISTER, instructions);
    } else if (size == OperandSize.DWORD) {
        // Destination is a DWORD register
        // Handling DWORD values is easier. Just add a STR
        // instruction that writes the loaded source value
        // into the destination register.
        instructions.add(ReilHelpers.createStr(offset, size, sourceRegister, size, destination));
    // instructions.addAll(Helpers.writeBack(environment, offset, targetOperand, sourceRegister,
    // size, null, TranslationResultType.REGISTER));
    } else {
        assert false;
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) OperandType(com.google.security.zynamics.reil.OperandType) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 38 with IOperandTree

use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.

the class ShrdTranslator method translate.

/**
   * Translates a SHRD instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The SHRD 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 SHRD instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "shrd");
    if (instruction.getOperands().size() != 3) {
        throw new InternalTranslationException("Error: Argument instruction is not a shrd 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 shiftedSecondInput = 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++, secondResult.getSize(), secondResult.getRegister(), secondResult.getSize(), shiftMask, combinedSize, shiftedSecondInput));
    instructions.add(ReilHelpers.createOr(offset++, combinedSize, shiftedSecondInput, firstResult.getSize(), firstResult.getRegister(), combinedSize, combinedSource));
    // Negate the shift-mask
    final String negatedShiftMask = environment.getNextVariableString();
    final String truncatedNegatedShiftMask = environment.getNextVariableString();
    instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, "0", OperandSize.BYTE, truncatedShiftValue, OperandSize.WORD, negatedShiftMask));
    instructions.add(ReilHelpers.createAnd(offset++, OperandSize.WORD, negatedShiftMask, OperandSize.BYTE, "255", OperandSize.BYTE, truncatedNegatedShiftMask));
    // Less-1 shift to determine the CF
    final String incShiftMaskNeg = environment.getNextVariableString();
    final String decResult = environment.getNextVariableString();
    instructions.add(ReilHelpers.createAdd(offset++, OperandSize.BYTE, truncatedNegatedShiftMask, OperandSize.BYTE, "1", OperandSize.WORD, incShiftMaskNeg));
    instructions.add(ReilHelpers.createBsh(offset++, combinedSize, combinedSource, OperandSize.WORD, incShiftMaskNeg, combinedSize, decResult));
    instructions.add(ReilHelpers.createAnd(offset++, combinedSize, decResult, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Do the shift
    instructions.add(ReilHelpers.createBsh(offset++, combinedSize, combinedSource, OperandSize.BYTE, truncatedNegatedShiftMask, 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;
    /** JCC placeholder **/
    // final String tempCf = environment.getNextVariableString();
    // 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;
    /** JCC placeholder **/
    // 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, OperandSize.BYTE, String.valueOf(msbMask), OperandSize.BYTE, 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 (firstResult.getType() == TranslationResultType.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 39 with IOperandTree

use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.

the class SubTranslator method translate.

/**
   * Translates a SUB instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The SUB 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 SUB instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "sub");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a sub instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    final List<? extends IOperandTree> operands = instruction.getOperands();
    final IOperandTree operand1 = operands.get(0);
    final IOperandTree operand2 = operands.get(1);
    // Load source operand.
    final TranslationResult operand2Result = Helpers.translateOperand(environment, offset, operand2, true);
    instructions.addAll(operand2Result.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    // Load destination operand.
    final TranslationResult operand1Result = Helpers.translateOperand(environment, offset, operand1, true);
    instructions.addAll(operand1Result.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final OperandSize size = operand1Result.getSize();
    final String register1 = operand1Result.getRegister();
    final String register2 = operand2Result.getRegister();
    // Subtract the two values
    final String subResultValue = Helpers.generateSub(environment, offset, size, register1, register2, instructions);
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    Helpers.writeParityFlag(environment, offset, size, subResultValue, instructions);
    offset = baseOffset + instructions.size();
    // Write the result of the value back into the target operand
    Helpers.writeBack(environment, offset, operand1, subResultValue, size, operand1Result.getAddress(), operand1Result.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 40 with IOperandTree

use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.

the class TestTranslator method translate.

/**
   * Translates a TEST instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The TEST 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 TEST instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "test");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a test 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 size = targetResult.getSize();
    final String sourceRegister = sourceResult.getRegister();
    final String targetRegister = targetResult.getRegister();
    Helpers.generateAnd(environment, offset, size, sourceRegister, targetRegister, 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

IOperandTree (com.google.security.zynamics.zylib.disassembly.IOperandTree)60 OperandSize (com.google.security.zynamics.reil.OperandSize)53 TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)39 InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)35 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)2 TranslationResultType (com.google.security.zynamics.reil.translators.TranslationResultType)2 OperandType (com.google.security.zynamics.reil.OperandType)1 ReilOperand (com.google.security.zynamics.reil.ReilOperand)1 ReilOperandNode (com.google.security.zynamics.reil.ReilOperandNode)1 Triple (com.google.security.zynamics.zylib.general.Triple)1 ArrayList (java.util.ArrayList)1