Search in sources :

Example 36 with OperandSize

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

the class ImulTranslator method generateImul.

private TranslationResult generateImul(final ITranslationEnvironment environment, final long offset, final String operand1, final String operand2, final OperandSize size1, final OperandSize size2) {
    // The three steps to simulate signed multiplication using unsigned multiplication:
    // 1. Get the absolute values of the two operands
    // 2. Multiply the absolute values
    // 3. Change the sign of the result if the two operands had different signs.
    final long baseOffset = offset;
    long newOffset = baseOffset;
    final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
    final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
    final Pair<String, String> abs1 = Helpers.generateAbs(environment, newOffset, operand1, size1, instructions);
    newOffset = baseOffset + instructions.size();
    final Pair<String, String> abs2 = Helpers.generateAbs(environment, newOffset, operand2, size2, instructions);
    newOffset = baseOffset + instructions.size();
    final String lowerHalfMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
    final String multResult = environment.getNextVariableString();
    final String xoredSigns = environment.getNextVariableString();
    final String toggleMask = environment.getNextVariableString();
    final String decResult = environment.getNextVariableString();
    final String realResult = environment.getNextVariableString();
    final String maskedLowerHalf = environment.getNextVariableString();
    // Multiply the two operands
    instructions.add(ReilHelpers.createMul(newOffset, size1, abs1.second(), size2, abs2.second(), resultSize, multResult));
    // Find out if the two operands had different signs and adjust the result accordingly
    instructions.add(ReilHelpers.createXor(newOffset + 1, size1, abs1.first(), size2, abs2.first(), size1, xoredSigns));
    instructions.add(ReilHelpers.createSub(newOffset + 2, size1, "0", size1, xoredSigns, resultSize, toggleMask));
    instructions.add(ReilHelpers.createSub(newOffset + 3, resultSize, multResult, size1, xoredSigns, resultSize, decResult));
    instructions.add(ReilHelpers.createXor(newOffset + 4, resultSize, toggleMask, resultSize, decResult, resultSize, realResult));
    // Extract lower half of the result
    instructions.add(ReilHelpers.createAnd(newOffset + 5, resultSize, realResult, size1, lowerHalfMask, size1, maskedLowerHalf));
    // Extend the sign of the lower half of the result
    final TranslationResult foo = Helpers.extendSign(environment, newOffset + 6, maskedLowerHalf, size1, resultSize);
    instructions.addAll(foo.getInstructions());
    newOffset = newOffset + 6 + foo.getInstructions().size();
    final String cmpResult = environment.getNextVariableString();
    final String resultsEqual = environment.getNextVariableString();
    // Compare result to sign extension of lower half
    instructions.add(ReilHelpers.createSub(newOffset, resultSize, realResult, resultSize, foo.getRegister(), resultSize, cmpResult));
    instructions.add(ReilHelpers.createBisz(newOffset + 1, resultSize, cmpResult, OperandSize.BYTE, resultsEqual));
    // Set the flags according to the result
    instructions.add(ReilHelpers.createBisz(newOffset + 2, OperandSize.BYTE, resultsEqual, OperandSize.BYTE, Helpers.CARRY_FLAG));
    instructions.add(ReilHelpers.createBisz(newOffset + 3, OperandSize.BYTE, resultsEqual, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    instructions.add(ReilHelpers.createUndef(newOffset + 4, OperandSize.BYTE, Helpers.ZERO_FLAG));
    instructions.add(ReilHelpers.createUndef(newOffset + 5, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
    instructions.add(ReilHelpers.createUndef(newOffset + 6, OperandSize.BYTE, Helpers.PARITY_FLAG));
    return new TranslationResult(realResult, resultSize, 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 37 with OperandSize

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

the class CmpTranslator method translate.

/**
   * Translates a CMP instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The CMP 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 CMP instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "cmp");
    Preconditions.checkArgument(instruction.getOperands().size() == 2, "Error: Argument instruction is not a cmp 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 first operand.
    final TranslationResult firstResult = Helpers.translateOperand(environment, offset, targetOperand, true);
    instructions.addAll(firstResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    // Load second operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, sourceOperand, true);
    instructions.addAll(secondResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final String firstRegister = firstResult.getRegister();
    final String secondRegister = secondResult.getRegister();
    final OperandSize size = firstResult.getSize();
    // CMP = SUB without writing the result back into the target operand
    Helpers.generateSub(environment, offset, size, firstRegister, secondRegister, instructions);
}
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 38 with OperandSize

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

the class Helpers method processSimpleMemoryAccessFromCompoundAddress.

/**
   * If the operand involves arithmetic, once this arithmetic is done, the segment
   * base register (if present) has to be added in and the result has to be truncated
   * to 32 bits. This function performs this task.
   */
private static TranslationResult processSimpleMemoryAccessFromCompoundAddress(ITranslationEnvironment environment, IOperandTreeNode segmentOverride, OperandSize size, boolean loadOperand, TranslationResult intermediateResult) {
    final OperandSize archSize = environment.getArchitectureSize();
    final String truncationMask = String.valueOf(TranslationHelpers.getAllBitsMask(archSize));
    String childResult = intermediateResult.getRegister();
    // Add a segment register addition if a segment override prefix is present.
    if (segmentOverride != null) {
        final String pseudoRegister = getSegmentOverridePseudoRegister(segmentOverride);
        String nextVariableString = environment.getNextVariableString();
        intermediateResult.addInstruction(ReilHelpers.createAdd(0, /* reil address */
        archSize, childResult, archSize, pseudoRegister, archSize, nextVariableString));
        // Now make sure that the following code operates on the result of having
        // added the segment register in.
        childResult = nextVariableString;
    }
    // Truncate the results of the address arithmetic.
    final String truncatedAddress = environment.getNextVariableString();
    intermediateResult.addInstruction(ReilHelpers.createAnd(0, /* reil address */
    archSize, childResult, archSize, truncationMask, archSize, truncatedAddress));
    // Add the loading LDM instruction if this is desired.
    if (loadOperand) {
        final String loadedValue = environment.getNextVariableString();
        intermediateResult.addInstruction(// the TranslationResult.addInstruction.
        ReilHelpers.createLdm(0, /* reil address */
        archSize, truncatedAddress, size, loadedValue));
        intermediateResult.updateResult(loadedValue, size, truncatedAddress, TranslationResultType.MEMORY_ACCESS);
    } else {
        intermediateResult.updateResult(truncatedAddress, size, "", TranslationResultType.MEMORY_ACCESS);
    }
    return intermediateResult;
}
Also used : OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 39 with OperandSize

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

the class ImulTranslator method translate_1.

private void translate_1(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();
    // Generate multiplication code
    final TranslationResult multResult = generateImul(environment, offset, "eax", firstResult.getRegister(), OperandSize.DWORD, firstResult.getSize());
    instructions.addAll(multResult.getInstructions());
    offset = baseOffset + instructions.size();
    final OperandSize size = Helpers.getOperandSize(operands.get(0));
    // Write the result of the multiplication back to the proper registers
    instructions.addAll(Helpers.writeMulResult(environment, offset, multResult.getRegister(), size));
}
Also used : TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 40 with OperandSize

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

the class ImulTranslator method translate_3.

private void translate_3(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(1), true);
    instructions.addAll(firstResult.getInstructions());
    offset = baseOffset + instructions.size();
    // Load second operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(2), true);
    instructions.addAll(secondResult.getInstructions());
    offset = baseOffset + instructions.size();
    // Load target operand.
    final TranslationResult targetResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
    instructions.addAll(targetResult.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

OperandSize (com.google.security.zynamics.reil.OperandSize)442 IOperandTreeNode (com.google.security.zynamics.zylib.disassembly.IOperandTreeNode)257 IOperandTree (com.google.security.zynamics.zylib.disassembly.IOperandTree)53 InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)46 TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)45 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)16 ArrayList (java.util.ArrayList)15 BigInteger (java.math.BigInteger)12 CAddress (com.google.security.zynamics.zylib.disassembly.CAddress)5 OperandType (com.google.security.zynamics.reil.OperandType)2 ReilOperandNode (com.google.security.zynamics.reil.ReilOperandNode)2 TranslationResultType (com.google.security.zynamics.reil.translators.TranslationResultType)2 ReilBlock (com.google.security.zynamics.reil.ReilBlock)1 ReilEdge (com.google.security.zynamics.reil.ReilEdge)1 ReilGraph (com.google.security.zynamics.reil.ReilGraph)1 ReilOperand (com.google.security.zynamics.reil.ReilOperand)1 Pair (com.google.security.zynamics.zylib.general.Pair)1 EdgeType (com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType)1 HashMap (java.util.HashMap)1 StringTokenizer (java.util.StringTokenizer)1