Search in sources :

Example 46 with InternalTranslationException

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

the class DivTranslator method translate.

/**
 * Translates a DIV instruction to REIL code.
 *
 * @param environment A valid translation environment
 * @param instruction The DIV 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 DIV instruction
 */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "div");
    if (instruction.getOperands().size() != 1) {
        throw new InternalTranslationException("Error: Argument instruction is not a div instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    final List<? extends IOperandTree> operands = instruction.getOperands();
    final IOperandTree divisorOperand = operands.get(0);
    final OperandSize size = Helpers.getOperandSize(divisorOperand);
    // 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();
    final String divResult = environment.getNextVariableString();
    final String modResult = environment.getNextVariableString();
    // Perform divison and modulo operation
    instructions.add(ReilHelpers.createDiv(offset++, size, dividend, size, divisor, size, divResult));
    instructions.add(ReilHelpers.createMod(offset++, size, dividend, size, divisor, size, modResult));
    // Write the result back and set the flags
    instructions.addAll(Helpers.writeDivResult(environment, offset++, divResult, modResult, size));
    offset = baseOffset + instructions.size();
    // Undefine flags
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.CARRY_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.PARITY_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.SIGN_FLAG));
    instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.ZERO_FLAG));
}
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 47 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 48 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 49 with InternalTranslationException

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

the class DecTranslator method translate.

/**
 * Translates an DEC instruction to REIL code.
 *
 * @param environment A valid translation environment
 * @param instruction The DEC 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 DEC instruction
 */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "dec");
    if (instruction.getOperands().size() != 1) {
        throw new InternalTranslationException("Error: Argument instruction is not an dec instruction (invalid number of operand)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    // DEC 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 loadedRegister = result.getRegister();
    final OperandSize registerSize = result.getSize();
    final OperandSize nextSize = TranslationHelpers.getNextSize(registerSize);
    final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(registerSize));
    final String shiftMsbLsbMask = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(registerSize));
    final String truncMask = String.valueOf(TranslationHelpers.getAllBitsMask(registerSize));
    final String maskedMsb = environment.getNextVariableString();
    final String decResult = environment.getNextVariableString();
    final String maskedMsbResult = environment.getNextVariableString();
    final String maskedMsbNeg = environment.getNextVariableString();
    final String tempOF = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    // Isolate the MSB of the operand
    instructions.add(ReilHelpers.createAnd(offset, registerSize, loadedRegister, registerSize, msbMask, registerSize, maskedMsb));
    // Decrement the value
    instructions.add(ReilHelpers.createSub(offset + 1, registerSize, loadedRegister, registerSize, "1", nextSize, decResult));
    // Isolate the MSB of the result and put it into the Sign Flag
    instructions.add(ReilHelpers.createAnd(offset + 2, nextSize, decResult, registerSize, msbMask, registerSize, maskedMsbResult));
    instructions.add(ReilHelpers.createBsh(offset + 3, registerSize, maskedMsbResult, registerSize, shiftMsbLsbMask, OperandSize.BYTE, Helpers.SIGN_FLAG));
    // The OF is only set if the result of the dec operation is 0x7F
    // OF = ( MSB(old) == 1 ) AND ( MSB(new) == 0 )
    // OF = MSB(old) AND NOT(MSB(new))
    instructions.add(ReilHelpers.createXor(offset + 4, registerSize, maskedMsbResult, registerSize, msbMask, registerSize, maskedMsbNeg));
    instructions.add(ReilHelpers.createAnd(offset + 5, registerSize, maskedMsb, registerSize, maskedMsbNeg, registerSize, tempOF));
    // Write the result into the Overflow Flag
    instructions.add(ReilHelpers.createBsh(offset + 6, registerSize, tempOF, registerSize, shiftMsbLsbMask, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Truncate the result to fit into the target
    instructions.add(ReilHelpers.createAnd(offset + 7, nextSize, decResult, registerSize, truncMask, registerSize, truncatedResult));
    // Update the Zero Flag
    instructions.add(ReilHelpers.createBisz(offset + 8, registerSize, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
    // Write the truncated result back into the operand
    Helpers.writeBack(environment, offset + 9, operand, truncatedResult, registerSize, 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 50 with InternalTranslationException

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

the class BtrTranslator method translate.

/**
 * Translates a BTR instruction to REIL code.
 *
 * @param environment A valid translation environment
 * @param instruction The BTR 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 BTR instruction
 */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "btr");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a btr instruction (invalid number of operands)");
    }
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    final IOperandTree targetOperand = instruction.getOperands().get(0);
    final IOperandTree sourceOperand = instruction.getOperands().get(1);
    // Load the target operand.
    final TranslationResult targetResult = Helpers.translateOperand(environment, offset, targetOperand, true);
    instructions.addAll(targetResult.getInstructions());
    offset = baseOffset + instructions.size();
    // Load the source operand.
    final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, true);
    instructions.addAll(sourceResult.getInstructions());
    offset = baseOffset + instructions.size();
    final String negatedIndex = environment.getNextVariableString();
    // final String truncatedNegatedIndex = environment.getNextVariableString();
    final String shiftedTarget = environment.getNextVariableString();
    // TODO: Due to a bug in the REIL BSH specification we can not truncate the result
    // of the subtraction here. See the tests for an example of what goes wrong.
    instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, "0", sourceResult.getSize(), sourceResult.getRegister(), OperandSize.WORD, negatedIndex));
    // instructions.add(ReilHelpers.createAnd(offset++, OperandSize.WORD, negatedIndex,
    // OperandSize.BYTE, "255", OperandSize.BYTE, truncatedNegatedIndex));
    instructions.add(ReilHelpers.createBsh(offset++, targetResult.getSize(), targetResult.getRegister(), OperandSize.BYTE, negatedIndex, targetResult.getSize(), shiftedTarget));
    instructions.add(ReilHelpers.createAnd(offset++, targetResult.getSize(), shiftedTarget, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Clear the bit in the destination
    final String shiftedIndex = environment.getNextVariableString();
    final String negatedShiftedIndex = environment.getNextVariableString();
    final String andedResult = environment.getNextVariableString();
    // Shift the mask to the right bit
    instructions.add(ReilHelpers.createBsh(offset++, OperandSize.BYTE, "1", sourceResult.getSize(), sourceResult.getRegister(), targetResult.getSize(), shiftedIndex));
    // Toggle the bits of the shift mask
    instructions.add(ReilHelpers.createXor(offset++, targetResult.getSize(), shiftedIndex, targetResult.getSize(), String.valueOf(TranslationHelpers.getAllBitsMask(targetResult.getSize())), targetResult.getSize(), negatedShiftedIndex));
    // Preserve all original bits except for the one at the shift position which is cleared
    instructions.add(ReilHelpers.createAnd(offset++, targetResult.getSize(), targetResult.getRegister(), targetResult.getSize(), negatedShiftedIndex, targetResult.getSize(), andedResult));
    Helpers.writeBack(environment, offset++, targetOperand, andedResult, 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)

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