Search in sources :

Example 41 with InternalTranslationException

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

the class Helpers method writeBack.

/**
   * Writes a value back into a target.
   *
   * @param environment A valid translation environment.
   * @param offset The next unused REIL offset; the new code is written there.
   * @param targetOperand The target operand where the value is written to
   * @param sourceValue The value that's written
   * @param size
   * @param address Target address (in case the type is MEMORY_ACCESS) or null (in case it's not)
   * @param targetType Target type (Either REGISTER or MEMORY_ACCESS)
   * @param instructions The new code is added to this list of instructions
   *
   * @throws IllegalArgumentException Thrown if invalid arguments were passed to the function.
   * @throws InternalTranslationException Thrown if invalid argument combinations were passed to the
   *         function.
   */
public static void writeBack(final ITranslationEnvironment environment, final long offset, final IOperandTree targetOperand, final String sourceValue, final OperandSize size, final String address, final TranslationResultType targetType, final List<ReilInstruction> instructions) throws IllegalArgumentException, InternalTranslationException {
    Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
    Preconditions.checkNotNull(targetOperand, "Error: Argument targetOperand can't be null");
    Preconditions.checkNotNull(sourceValue, "Error: Argument sourceValue can't be null");
    Preconditions.checkNotNull(size, "Error: Argument size can't be null");
    Preconditions.checkNotNull(targetType, "Error: Argument targetType can't be null");
    Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
    // TODO: Exact meaning of parameter size
    final OperandSize archSize = environment.getArchitectureSize();
    if (targetType == TranslationResultType.REGISTER) {
        if (address != null) {
            throw new InternalTranslationException("Error: Invalid combination of parameters");
        }
        // The target is a register. Either write the value directly or mask it into the target
        final String target = getLeafValue(targetOperand.getRootNode());
        if ((size == archSize) || isSegment(target)) {
            instructions.add(ReilHelpers.createStr(offset, size, sourceValue, size, target));
        } else {
            moveAndMask(environment, offset, size, sourceValue, target, instructions);
        }
    } else if (targetType == TranslationResultType.MEMORY_ACCESS) {
        // The target is a memory address. Store the value there.
        instructions.add(ReilHelpers.createStm(offset, size, sourceValue, archSize, address));
    } else {
        throw new InternalTranslationException("Error: Invalid target type");
    }
}
Also used : InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 42 with InternalTranslationException

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

the class Helpers method processLeafNode.

private static TranslationResult processLeafNode(final ITranslationEnvironment environment, final long baseOffset, final IOperandTreeNode expression, OperandSize size, boolean loadOperand) throws InternalTranslationException {
    // All leaves are either registers or integer literals. They are translated
    // into "STR leaf, , nextVariable" instructions. Optimizations are handled
    // during the translation of their parent nodes.
    // Get the type of the leaf.
    final String value = expression.getValue();
    final OperandType operandType = OperandType.getOperandType(value);
    TranslationResultType nodeType = null;
    switch(operandType) {
        case REGISTER:
            nodeType = TranslationResultType.REGISTER;
            break;
        case INTEGER_LITERAL:
            nodeType = TranslationResultType.LITERAL;
            break;
        default:
            throw new InternalTranslationException("Error: Leaf has invalid type");
    }
    final List<ReilInstruction> instructions = new ArrayList<>();
    final String nextVariableString = environment.getNextVariableString();
    if ((operandType == OperandType.INTEGER_LITERAL) || !needsExtraction(environment, value)) {
        if (loadOperand) {
            instructions.add(ReilHelpers.createStr(baseOffset, size, value, size, nextVariableString));
            return new TranslationResult(nextVariableString, size, nodeType, null, instructions, baseOffset);
        } else {
            //      str t3, --, ebx
            return new TranslationResult(value, size, nodeType, null, instructions, baseOffset);
        }
    } else {
        // Mask smaller operands
        return extractRegister(environment, baseOffset, value);
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) OperandType(com.google.security.zynamics.reil.OperandType) TranslationResultType(com.google.security.zynamics.reil.translators.TranslationResultType) ArrayList(java.util.ArrayList) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult)

Example 43 with InternalTranslationException

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

the class IdivTranslator method translate.

/**
   * Translates a IDIV instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The IDIV 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 IDIV instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "idiv");
    if (instruction.getOperands().size() != 1) {
        throw new InternalTranslationException("Error: Argument instruction is not a idiv instruction (invalid number of operands)");
    }
    final List<? extends IOperandTree> operands = instruction.getOperands();
    final IOperandTree divisorOperand = operands.get(0);
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    final OperandSize size = Helpers.getOperandSize(operands.get(0));
    // Load the dividend
    final TranslationResult resultDividend = Helpers.loadFirstDivOperand(environment, offset, size);
    instructions.addAll(resultDividend.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final String dividend = resultDividend.getRegister();
    // Load the divisor
    final TranslationResult resultDivisor = Helpers.translateOperand(environment, offset, divisorOperand, true);
    instructions.addAll(resultDivisor.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final String divisor = resultDivisor.getRegister();
    // Here's how to express signed division using unsigned division:
    // 1. Get the absolute value of both operands
    // 2. Divide unsigned
    // 3. Change the sign of the result if the signs of the operands were different
    // Get the absolute value of the two factors for unsigned multiplication
    final Pair<String, String> absDividend = Helpers.generateAbs(environment, offset, dividend, size, instructions);
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final Pair<String, String> absDivisor = Helpers.generateAbs(environment, offset, divisor, size, instructions);
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    // Perform division and modulo operation
    final String divResult = environment.getNextVariableString();
    final String modResult = environment.getNextVariableString();
    instructions.add(ReilHelpers.createDiv(offset, size, absDividend.second(), size, absDivisor.second(), size, divResult));
    instructions.add(ReilHelpers.createMod(offset + 1, size, absDividend.second(), size, absDivisor.second(), size, modResult));
    // Find out if the two operands had different signs and create a sign mask
    final String xoredSigns = environment.getNextVariableString();
    final String toggleMask = environment.getNextVariableString();
    instructions.add(ReilHelpers.createXor(offset + 2, size, absDividend.first(), size, absDividend.second(), size, xoredSigns));
    instructions.add(ReilHelpers.createSub(offset + 3, size, "0", size, xoredSigns, size, toggleMask));
    // Adjust the div result
    final String decDivResult = environment.getNextVariableString();
    final String realDivResult = environment.getNextVariableString();
    instructions.add(ReilHelpers.createSub(offset + 4, size, divResult, size, xoredSigns, size, decDivResult));
    instructions.add(ReilHelpers.createXor(offset + 5, size, decDivResult, size, toggleMask, size, realDivResult));
    // Adjust the mod result (the sign of the mod result is the sign of the first operand)
    final String modToggleMask = environment.getNextVariableString();
    final String decModResult = environment.getNextVariableString();
    final String realModResult = environment.getNextVariableString();
    instructions.add(ReilHelpers.createSub(offset + 6, size, "0", size, absDividend.first(), size, modToggleMask));
    instructions.add(ReilHelpers.createSub(offset + 7, size, modResult, size, absDividend.first(), size, decModResult));
    instructions.add(ReilHelpers.createXor(offset + 8, size, decModResult, size, modToggleMask, size, realModResult));
    // Write the result back and set the flags
    instructions.addAll(Helpers.writeDivResult(environment, offset + 9, realDivResult, realModResult, size));
}
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 44 with InternalTranslationException

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

the class LahfTranslator method translate.

/**
   * Translates a LAHF instruction to REIL code.
   * 
   * @param environment A valid translation environment.
   * @param instruction The LAHF 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, "lahf");
    if (instruction.getOperands().size() != 0) {
        throw new InternalTranslationException("Error: Argument instruction is not a lahf instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    final OperandSize archSize = environment.getArchitectureSize();
    final String clearedEax = environment.getNextVariableString();
    final String shiftedSf = environment.getNextVariableString();
    final String clearedEaxSf = environment.getNextVariableString();
    final String shiftedZf = environment.getNextVariableString();
    final String clearedEaxZf = environment.getNextVariableString();
    final String shiftedAf = environment.getNextVariableString();
    final String clearedEaxAf = environment.getNextVariableString();
    final String shiftedPf = environment.getNextVariableString();
    final String clearedEaxPf = environment.getNextVariableString();
    final String shiftedCf = environment.getNextVariableString();
    final String clearedEaxCf = environment.getNextVariableString();
    // Clear AH
    instructions.add(ReilHelpers.createAnd(baseOffset, archSize, "eax", archSize, "4294902015", archSize, clearedEax));
    // Move the SF into the highest bit of AH
    instructions.add(ReilHelpers.createBsh(baseOffset + 1, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, "15", OperandSize.WORD, shiftedSf));
    instructions.add(ReilHelpers.createOr(baseOffset + 2, archSize, clearedEax, OperandSize.WORD, shiftedSf, archSize, clearedEaxSf));
    // Move the ZF into the 6th bit of AH
    instructions.add(ReilHelpers.createBsh(baseOffset + 3, OperandSize.BYTE, Helpers.ZERO_FLAG, OperandSize.BYTE, "14", OperandSize.WORD, shiftedZf));
    instructions.add(ReilHelpers.createOr(baseOffset + 4, archSize, clearedEaxSf, OperandSize.WORD, shiftedZf, archSize, clearedEaxZf));
    // Move the AF into the 4th bit of AH
    instructions.add(ReilHelpers.createBsh(baseOffset + 5, OperandSize.BYTE, Helpers.AUXILIARY_FLAG, OperandSize.BYTE, "12", OperandSize.WORD, shiftedAf));
    instructions.add(ReilHelpers.createOr(baseOffset + 6, archSize, clearedEaxZf, OperandSize.WORD, shiftedAf, archSize, clearedEaxAf));
    // Move the PF into the 2nd bit of AH
    instructions.add(ReilHelpers.createBsh(baseOffset + 7, OperandSize.BYTE, Helpers.PARITY_FLAG, OperandSize.BYTE, "10", OperandSize.WORD, shiftedPf));
    instructions.add(ReilHelpers.createOr(baseOffset + 8, archSize, clearedEaxAf, OperandSize.WORD, shiftedPf, archSize, clearedEaxPf));
    // Move the CF into the LSB of AH
    instructions.add(ReilHelpers.createBsh(baseOffset + 9, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, "8", OperandSize.WORD, shiftedCf));
    instructions.add(ReilHelpers.createOr(baseOffset + 10, archSize, clearedEaxPf, OperandSize.WORD, shiftedCf, archSize, clearedEaxCf));
    // The 1st bit of AH ( = 8th bit of EAX) is set to 1
    instructions.add(ReilHelpers.createOr(baseOffset + 11, archSize, clearedEaxCf, archSize, "512", archSize, "eax"));
}
Also used : InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 45 with InternalTranslationException

use of com.google.security.zynamics.reil.translators.InternalTranslationException 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)

Aggregations

InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)62 OperandSize (com.google.security.zynamics.reil.OperandSize)46 TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)42 IOperandTree (com.google.security.zynamics.zylib.disassembly.IOperandTree)35 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)6 ArrayList (java.util.ArrayList)5 TranslationResultType (com.google.security.zynamics.reil.translators.TranslationResultType)3 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)2 OperandType (com.google.security.zynamics.reil.OperandType)2 IOperandTreeNode (com.google.security.zynamics.zylib.disassembly.IOperandTreeNode)2 BigInteger (java.math.BigInteger)2 MockCodeNodeData (com.google.security.zynamics.binnavi.Database.MockClasses.MockCodeNodeData)1 MockCodeNodeProvider (com.google.security.zynamics.binnavi.Database.MockClasses.MockCodeNodeProvider)1 MockSqlProvider (com.google.security.zynamics.binnavi.Database.MockClasses.MockSqlProvider)1 CCodeNodeParser (com.google.security.zynamics.binnavi.Database.NodeParser.CCodeNodeParser)1 MaybeNullException (com.google.security.zynamics.binnavi.Exceptions.MaybeNullException)1 CCodeNode (com.google.security.zynamics.binnavi.disassembly.CCodeNode)1 INaviCodeNode (com.google.security.zynamics.binnavi.disassembly.INaviCodeNode)1 MockFunction (com.google.security.zynamics.binnavi.disassembly.MockFunction)1 MockModule (com.google.security.zynamics.binnavi.disassembly.Modules.MockModule)1