Search in sources :

Example 61 with ReilInstruction

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

the class PerInstructionTransformationProvider method transform.

@Override
public Pair<LatticeElementType, LatticeElementType> transform(final IInstructionGraphNode n, final LatticeElementType state) {
    final ReilInstruction ins = n.getReilInstruction();
    final Integer mnemonic = ins.getMnemonicCode();
    switch(mnemonic) {
        case ReilHelpers._OPCODE_ADD:
            return transformAdd(ins, state);
        case ReilHelpers._OPCODE_AND:
            return transformAnd(ins, state);
        case ReilHelpers._OPCODE_BISZ:
            return transformBisz(ins, state);
        case ReilHelpers._OPCODE_BSH:
            return transformBsh(ins, state);
        case ReilHelpers._OPCODE_DIV:
            return transformDiv(ins, state);
        case ReilHelpers._OPCODE_JCC:
            return transformJcc(ins, state);
        case ReilHelpers._OPCODE_LDM:
            return transformLdm(ins, state);
        case ReilHelpers._OPCODE_MOD:
            return transformMod(ins, state);
        case ReilHelpers._OPCODE_MUL:
            return transformMod(ins, state);
        case ReilHelpers._OPCODE_NOP:
            return transformNop(ins, state);
        case ReilHelpers._OPCODE_OR:
            return transformOr(ins, state);
        case ReilHelpers._OPCODE_STM:
            return transformStm(ins, state);
        case ReilHelpers._OPCODE_STR:
            return transformStr(ins, state);
        case ReilHelpers._OPCODE_SUB:
            return transformSub(ins, state);
        case ReilHelpers._OPCODE_UNDEF:
            return transformUndef(ins, state);
        case ReilHelpers._OPCODE_UNKNOWN:
            return transformUnknown(ins, state);
        case ReilHelpers._OPCODE_XOR:
            return transformXor(ins, state);
        default:
            return transformUnknownOpcode(ins, state);
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction)

Example 62 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction 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 63 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction 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 64 with ReilInstruction

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

Example 65 with ReilInstruction

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

Aggregations

ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)144 Test (org.junit.Test)102 TreeSet (java.util.TreeSet)73 ArrayList (java.util.ArrayList)35 IInstruction (com.google.security.zynamics.zylib.disassembly.IInstruction)18 OperandSize (com.google.security.zynamics.reil.OperandSize)16 ReilBlock (com.google.security.zynamics.reil.ReilBlock)16 MockInstruction (com.google.security.zynamics.zylib.disassembly.MockInstruction)16 MockOperandTree (com.google.security.zynamics.zylib.disassembly.MockOperandTree)16 MockOperandTreeNode (com.google.security.zynamics.zylib.disassembly.MockOperandTreeNode)16 ReilEdge (com.google.security.zynamics.reil.ReilEdge)12 HashMap (java.util.HashMap)12 TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)9 IAddress (com.google.security.zynamics.zylib.disassembly.IAddress)7 List (java.util.List)7 ReilGraph (com.google.security.zynamics.reil.ReilGraph)6 InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)6 BigInteger (java.math.BigInteger)6 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)5 ValueTrackerElement (com.google.security.zynamics.reil.algorithms.mono.valuetracking.ValueTrackerElement)5