Search in sources :

Example 36 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult 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 37 with TranslationResult

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

the class Helpers method extractRegister.

/**
   * Extracts a subregister (like AX, AL, AH) from a parent register (like EAX)
   *
   * @param environment A valid translation environment
   * @param offset The next unused REIL offset where the new REIL code can be placed
   * @param subRegister The subregister that should be extracted
   *
   * @return The result of the translation
   *
   * @throws InternalTranslationException Thrown if an internal problem occurs
   */
private static TranslationResult extractRegister(final ITranslationEnvironment environment, final long offset, final String subRegister) throws InternalTranslationException {
    final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
    final String parentRegister = getParentRegister(subRegister);
    final OperandSize archSize = environment.getArchitectureSize();
    if (isHigher8BitRegister(subRegister)) {
        // The sub-register is not at the low end of the parent
        // register. Mask + shift is necessary here.
        final String maskResult = environment.getNextVariableString();
        final String shiftResult = environment.getNextVariableString();
        // Add the mask + shift instructions
        instructions.add(ReilHelpers.createAnd(offset, archSize, parentRegister, OperandSize.WORD, "65280", OperandSize.WORD, maskResult));
        instructions.add(ReilHelpers.createBsh(offset + 1, OperandSize.WORD, maskResult, OperandSize.WORD, "-8", OperandSize.BYTE, shiftResult));
        return new TranslationResult(shiftResult, OperandSize.BYTE, TranslationResultType.REGISTER, null, instructions, offset);
    } else {
        // The sub-register is already at the low end of the parent register.
        // Masking is enough.
        final OperandSize subRegisterSize = getRegisterSize(subRegister);
        final String mask = String.valueOf(TranslationHelpers.getAllBitsMask(subRegisterSize));
        final String result = environment.getNextVariableString();
        // Add the mask instruction
        instructions.add(ReilHelpers.createAnd(offset, archSize, parentRegister, subRegisterSize, mask, subRegisterSize, result));
        return new TranslationResult(result, subRegisterSize, TranslationResultType.REGISTER, null, instructions, offset);
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 38 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult 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 39 with TranslationResult

use of com.google.security.zynamics.reil.translators.TranslationResult 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 40 with TranslationResult

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

the class ImulTranslator method translate_2.

private void translate_2(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    final List<? extends IOperandTree> operands = instruction.getOperands();
    final long baseOffset = instruction.getAddress().toLong() * 0x100;
    long offset = baseOffset;
    // Load source operand.
    final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
    instructions.addAll(firstResult.getInstructions());
    offset = baseOffset + instructions.size();
    // Load second operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
    instructions.addAll(secondResult.getInstructions());
    offset = baseOffset + instructions.size();
    // IMUL instructions with 2 or 3 operands must have an output register
    final OperandSize resultSize = OperandSize.sizeStringToValue(operands.get(0).getRootNode().getValue());
    final String resultRegister = operands.get(0).getRootNode().getChildren().get(0).getValue();
    generateImul3(environment, offset, resultSize, resultRegister, firstResult.getSize(), firstResult.getRegister(), secondResult.getSize(), secondResult.getRegister(), instructions);
}
Also used : 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