Search in sources :

Example 31 with OperandSize

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

the class Helpers method writeMulResult.

public static ArrayList<ReilInstruction> writeMulResult(final ITranslationEnvironment environment, final long offset, final String result, final OperandSize size) {
    final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
    final OperandSize archSize = environment.getArchitectureSize();
    if (size == OperandSize.BYTE) {
        // Store the result in AX
        final String maskedEax = environment.getNextVariableString();
        instructions.add(ReilHelpers.createAnd(offset, archSize, "eax", archSize, "4294901760", archSize, maskedEax));
        instructions.add(ReilHelpers.createOr(offset + 1, OperandSize.WORD, result, archSize, maskedEax, archSize, "eax"));
        return instructions;
    } else if (size == OperandSize.WORD) {
        // Store the result in DX:AX
        final String maskResNeg = "4294901760";
        final String maskedEax = environment.getNextVariableString();
        final String maskedResult = environment.getNextVariableString();
        final String maskedEdx = environment.getNextVariableString();
        final String shiftedResult = environment.getNextVariableString();
        // Store the lower half in AX
        instructions.add(ReilHelpers.createAnd(offset, OperandSize.DWORD, "eax", OperandSize.DWORD, maskResNeg, OperandSize.DWORD, maskedEax));
        instructions.add(ReilHelpers.createAnd(offset + 1, OperandSize.DWORD, result, OperandSize.DWORD, "65535", OperandSize.DWORD, maskedResult));
        instructions.add(ReilHelpers.createOr(offset + 2, OperandSize.DWORD, maskedEax, OperandSize.DWORD, maskedResult, OperandSize.DWORD, "eax"));
        // Store the upper half in DX
        instructions.add(ReilHelpers.createAnd(offset + 3, OperandSize.DWORD, "edx", OperandSize.DWORD, maskResNeg, OperandSize.DWORD, maskedEdx));
        instructions.add(ReilHelpers.createBsh(offset + 4, OperandSize.DWORD, result, OperandSize.DWORD, "-16", OperandSize.DWORD, shiftedResult));
        instructions.add(ReilHelpers.createOr(offset + 5, OperandSize.DWORD, maskedEdx, OperandSize.DWORD, shiftedResult, OperandSize.DWORD, "edx"));
        return instructions;
    } else if (size == OperandSize.DWORD) {
        // Store the result in EDX:EAX
        instructions.add(ReilHelpers.createAnd(offset, OperandSize.QWORD, result, OperandSize.DWORD, "4294967295", OperandSize.DWORD, "eax"));
        instructions.add(ReilHelpers.createBsh(offset + 1, OperandSize.QWORD, result, OperandSize.QWORD, "-32", OperandSize.DWORD, "edx"));
        return instructions;
    } else {
        assert false;
        return instructions;
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 32 with OperandSize

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

the class Helpers method loadFirstDivOperand.

public static TranslationResult loadFirstDivOperand(final ITranslationEnvironment environment, final long offset, final OperandSize size) {
    final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
    final OperandSize archSize = environment.getArchitectureSize();
    if (size == OperandSize.BYTE) {
        final String dividend = environment.getNextVariableString();
        instructions.add(ReilHelpers.createAnd(offset, archSize, "eax", OperandSize.BYTE, "255", OperandSize.BYTE, dividend));
        return new TranslationResult(dividend, OperandSize.BYTE, TranslationResultType.REGISTER, null, instructions, offset);
    } else if (size == OperandSize.WORD) {
        final String extractedAx = environment.getNextVariableString();
        final String extractedDx = environment.getNextVariableString();
        final String shiftedDx = environment.getNextVariableString();
        final String dividend = environment.getNextVariableString();
        instructions.add(ReilHelpers.createAnd(offset, archSize, "eax", OperandSize.WORD, "65535", size, extractedAx));
        instructions.add(ReilHelpers.createAnd(offset + 1, archSize, "edx", OperandSize.WORD, "65535", size, extractedDx));
        instructions.add(ReilHelpers.createBsh(offset + 2, OperandSize.WORD, extractedDx, OperandSize.WORD, "16", OperandSize.DWORD, shiftedDx));
        instructions.add(ReilHelpers.createOr(offset + 3, OperandSize.WORD, extractedAx, OperandSize.DWORD, shiftedDx, OperandSize.DWORD, dividend));
        return new TranslationResult(dividend, OperandSize.DWORD, TranslationResultType.REGISTER, null, instructions, offset);
    } else if (size == OperandSize.DWORD) {
        final String shiftedEdx = environment.getNextVariableString();
        final String dividend = environment.getNextVariableString();
        instructions.add(ReilHelpers.createBsh(offset, OperandSize.DWORD, "edx", OperandSize.DWORD, "32", OperandSize.QWORD, shiftedEdx));
        instructions.add(ReilHelpers.createOr(offset + 1, OperandSize.DWORD, "eax", OperandSize.QWORD, shiftedEdx, OperandSize.QWORD, dividend));
        return new TranslationResult(dividend, OperandSize.QWORD, TranslationResultType.REGISTER, null, instructions, offset);
    } else {
        assert false;
        return null;
    }
}
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 33 with OperandSize

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

the class Helpers method generatePushAllRegisters.

/**
   * Pushes all registers onto the stack (in correct order for pusha/pushaw)
   *
   * @param environment A valid translation environment
   * @param baseOffset The next unused REIL offset
   * @param size The size of the registers to push (either WORD or DWORD)
   * @param instructions A list of REIL instructions where the new REIL code is added
   *
   * @throws IllegalArgumentException Thrown if any of the arguments are invalid
   */
public static void generatePushAllRegisters(final ITranslationEnvironment environment, final long baseOffset, final OperandSize size, final List<ReilInstruction> instructions) throws IllegalArgumentException {
    Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
    Preconditions.checkNotNull(size, "Error: Argument size can't be null");
    Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
    Preconditions.checkArgument((size == OperandSize.WORD) || (size == OperandSize.DWORD), "Error: Invalid size argument");
    long offset = baseOffset;
    final OperandSize archSize = environment.getArchitectureSize();
    final String tempEsp = environment.getNextVariableString();
    instructions.add(ReilHelpers.createStr(offset, archSize, "esp", archSize, tempEsp));
    generateRegisterPush(environment, offset + 1, "eax", size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, "ebx", size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, "ecx", size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, "edx", size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, tempEsp, size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, "ebp", size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, "esi", size, instructions);
    offset = baseOffset + instructions.size();
    generateRegisterPush(environment, offset, "edi", size, instructions);
    offset = baseOffset + instructions.size();
}
Also used : OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 34 with OperandSize

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

the class Helpers method loadOperand.

/**
   * Generates code that loads an x86 operand.
   *
   * This is done by first recursively calling loadOperand for all children of
   * the current node, and then processing the current node in the operand tree.
   *
   * @param environment A valid translation environment.
   * @param baseOffset Offset of the first instruction to translate.
   * @param expression The operand tree node to translate next
   * @param segmentOverride If any segment override was seen in the tree so far,
   *        it should be passed down the recursion
   * @param size The size of the operand.
   * @param loadOperand TODO(thomasdullien) The purpose of this argument is unknown.
   *
   * @return The result of the translation.
   *
   * @throws InternalTranslationException Thrown if an internal problem occurs
   */
private static TranslationResult loadOperand(final ITranslationEnvironment environment, final Long baseOffset, final IOperandTreeNode expression, final IOperandTreeNode segmentOverride, OperandSize size, final boolean loadOperand) throws InternalTranslationException {
    // Obtain the string that describes the current node in the operand tree.
    final String currentNodeValue = expression.getValue();
    // Obtain the number of children of the current node. This will be needed
    // in several places for different purposes, so we get it now.
    final int numberOfChildren = expression.getChildren().size();
    // reset the current operand size accordingly.
    if (TranslationHelpers.isSizeExpression(expression)) {
        size = OperandSize.sizeStringToValue(currentNodeValue);
    }
    // Now process all children of the current node and gather the results of
    // the translation of the child nodes.
    // Make a copy of baseOffset
    Long newBaseOffset = baseOffset.longValue();
    // so we can have reference semantics. It
    // gets modified inside translateChildrenOfNode
    // below.
    final OperandSize childrenSize = isMemoryAccess(currentNodeValue) ? environment.getArchitectureSize() : size;
    final List<TranslationResult> partialResults = translateChildrenOfNode(environment, expression, childrenSize, loadOperand, newBaseOffset);
    switch(numberOfChildren) {
        case 0:
            return processLeafNode(environment, newBaseOffset, expression, size, loadOperand);
        case 1:
            // - Memory access nodes.
            if (OperandSize.isSizeString(currentNodeValue)) {
                // translateChildrenOfNode. Just return the translation.
                return partialResults.get(0);
            } else if (isSegmentExpression(currentNodeValue)) {
                // translateChildrenOfNode. Just return the translation.
                return partialResults.get(0);
            } else if (isMemoryAccess(currentNodeValue)) {
                return processSimpleMemoryAccess(environment, segmentOverride, size, loadOperand, partialResults.get(0));
            } else {
                throw new InternalTranslationException("Error: Unknown node type with one child during address operand translation");
            }
        default:
            // always dealing with a compound memory dereference.
            return processInOperandArithmetic(partialResults, environment, newBaseOffset, expression);
    }
}
Also used : InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 35 with OperandSize

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

the class Helpers method processInOperandArithmetic.

/**
   * Deals with complicated arithmetic within operands, such as [ebx+ecx*2+2]
   *
   * @param partialResults The list of translations for the subtrees of the operand
   * @param environment The translation environment to track temp registers etc.
   * @param baseOffset The base address of this instruction.
   * @param expression The current node in the tree to process.
   * @return The result of the translation for the operand arithmetic.
   * @throws InternalTranslationException
   */
private static TranslationResult processInOperandArithmetic(List<TranslationResult> partialResults, ITranslationEnvironment environment, long baseOffset, IOperandTreeNode expression) throws InternalTranslationException {
    final String value = expression.getValue();
    final OperandSize archSize = environment.getArchitectureSize();
    final OperandSize nextSize = TranslationHelpers.getNextSize(archSize);
    // This result will be filled with the merged results from partialResults.
    TranslationResult finalResult = new TranslationResult("NEEDS_REPLACEMENT", archSize, TranslationResultType.REGISTER, "", new ArrayList<ReilInstruction>(), baseOffset);
    if (value.equals("+") || (value.equals("*"))) {
        // Join all the instructions from all partial results into a new list.
        ArrayList<ReilInstruction> allInstructions = new ArrayList<>();
        for (TranslationResult result : partialResults) {
            allInstructions.addAll(result.getInstructions());
        }
        finalResult.updateBaseAndReil(baseOffset, allInstructions);
        String source1 = partialResults.get(0).getRegister();
        String source2 = partialResults.get(1).getRegister();
        String currentTemporary = environment.getNextVariableString();
        // to not reuse the temporaries here in the future.
        for (int index = 2; index <= partialResults.size(); index++) {
            addPlusOrTimesInOperandArithmetic(environment, value, source1, source2, currentTemporary, finalResult);
            if (index < partialResults.size()) {
                source1 = partialResults.get(index).getRegister();
                source2 = currentTemporary;
            }
        }
        // Add an AND to mask off extra bits in the address calculation.
        final String truncationMask = String.valueOf(TranslationHelpers.getAllBitsMask(archSize));
        finalResult.addInstruction(ReilHelpers.createAnd(0, nextSize, currentTemporary, nextSize, truncationMask, archSize, currentTemporary));
        finalResult.updateResult(currentTemporary, archSize, "", TranslationResultType.REGISTER);
    } else if (value.equals(":")) {
        throw new InternalTranslationException("Error: Don't know how to deal with 1234:ABCD1234 (segment:address) operands.");
    }
    return finalResult;
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) 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