Search in sources :

Example 11 with ReilInstruction

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

the class CWritesDescription method visit.

@Override
public Collection<CSpecialInstruction> visit(final ReilFunction reilCode, final ListMultimap<IAddress, INaviInstruction> instructionMap) {
    final Collection<CSpecialInstruction> instructions = new ArrayList<CSpecialInstruction>();
    final Set<INaviInstruction> calls = new HashSet<INaviInstruction>();
    for (final ReilBlock block : reilCode.getGraph()) {
        for (final ReilInstruction reilInstruction : block) {
            if (ReilHelpers.isFunctionCall(reilInstruction)) {
                calls.addAll(instructionMap.get(ReilHelpers.toNativeAddress(reilInstruction.getAddress())));
            }
        }
    }
    for (final ReilBlock block : reilCode.getGraph()) {
        for (final ReilInstruction reilInstruction : block) {
            if (reilInstruction.getMnemonic().equals(ReilHelpers.OPCODE_STM)) {
                final List<INaviInstruction> firstInstructions = instructionMap.get(ReilHelpers.toNativeAddress(reilInstruction.getAddress()));
                if (isAnyCall(firstInstructions, calls)) {
                    continue;
                }
                final List<INaviInstruction> nativeInstructions = instructionMap.get(ReilHelpers.toNativeAddress(reilInstruction.getAddress()));
                for (final INaviInstruction naviInstruction : nativeInstructions) {
                    instructions.add(new CSpecialInstruction(this, naviInstruction));
                }
            }
        }
    }
    return instructions;
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) INaviInstruction(com.google.security.zynamics.binnavi.disassembly.INaviInstruction)

Example 12 with ReilInstruction

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

the class StateCombiner method combine.

private static ValueTrackerElement combine(final ValueTrackerElement state1, final ValueTrackerElement state2) {
    final Map<IAloc, IValueElement> values1 = state1.getStates();
    final Map<IAloc, IValueElement> values2 = state2.getStates();
    final Map<IAloc, IValueElement> combinedState = new HashMap<IAloc, IValueElement>();
    final Set<ReilInstruction> combinedInfluences = state1.getInfluences();
    combinedInfluences.addAll(state2.getInfluences());
    final Map<String, Set<IAddress>> combinedWritten = new HashMap<String, Set<IAddress>>();
    combinedWritten.putAll(state1.getLastWritten());
    for (final Map.Entry<String, Set<IAddress>> lastWritten : state2.getLastWritten().entrySet()) {
        if (combinedWritten.containsKey(lastWritten.getKey())) {
            combinedWritten.get(lastWritten.getKey()).addAll(lastWritten.getValue());
        } else {
            combinedWritten.put(lastWritten.getKey(), new HashSet<IAddress>(lastWritten.getValue()));
        }
    }
    for (final Map.Entry<IAloc, IValueElement> entry : values1.entrySet()) {
        final IAloc aloc = entry.getKey();
        if (values2.containsKey(aloc)) {
            final IValueElement lhs = entry.getValue();
            final IValueElement rhs = values2.get(aloc);
            combinedState.put(aloc, combine(lhs, rhs));
        } else {
            combinedState.put(aloc, new Undefined());
        }
    }
    for (final Map.Entry<IAloc, IValueElement> entry : values2.entrySet()) {
        final IAloc aloc = entry.getKey();
        if (!values1.containsKey(aloc)) {
            combinedState.put(aloc, new Undefined());
        }
    }
    if ((combinedState.size() < state1.getStates().size()) || (combinedState.size() < state2.getStates().size())) {
        throw new IllegalStateException();
    }
    return new ValueTrackerElement(combinedInfluences, combinedState, combinedWritten);
}
Also used : Undefined(com.google.security.zynamics.reil.algorithms.mono.valuetracking.elements.Undefined) ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ValueTrackerElement(com.google.security.zynamics.reil.algorithms.mono.valuetracking.ValueTrackerElement) IAloc(com.google.security.zynamics.reil.algorithms.mono.valuetracking.elements.IAloc) IAddress(com.google.security.zynamics.zylib.disassembly.IAddress) IValueElement(com.google.security.zynamics.reil.algorithms.mono.valuetracking.elements.IValueElement) HashMap(java.util.HashMap) Map(java.util.Map)

Example 13 with ReilInstruction

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

the class BasicBlockGenerator method addInstruction.

private void addInstruction(final ReilInstruction reilInstruction, final HashSet<IAddress> jumpTargets, final ReilInstruction lastInstruction) {
    if (jumpTargets.contains(reilInstruction.getAddress()) && (currentBlock.size() != 0)) {
        final ReilBlock reilBlock = new ReilBlock(currentBlock);
        // final IAddress blockAddress = reilBlock.getAddress();
        blocks.add(reilBlock);
        // if ((reilBlock.getAddress().toLong() & 0xFFFFFFFFFFFFFF00L) ==
        // (reilInstruction.getAddress().toLong() & 0xFFFFFFFFFFFFFF00L))
        {
            edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, reilInstruction.getAddress(), EdgeType.JUMP_UNCONDITIONAL));
        }
        currentBlock = new ArrayList<ReilInstruction>();
    }
    currentBlock.add(reilInstruction);
    if (reilInstruction.getMnemonic().equals(ReilHelpers.OPCODE_JCC) && (ReilHelpers.isDelayedBranch(reilInstruction) || (reilInstruction != lastInstruction))) {
        // Every JCC instruction finishes a block. We skip the last instruction of a block
        // because those edges already exist in the native edge set.
        //
        // Delayed branches also finish a block, at least as far as edge creation goes.
        final ReilBlock reilBlock = new ReilBlock(currentBlock);
        blocks.add(reilBlock);
        currentBlock = new ArrayList<ReilInstruction>();
        final String jumpTarget = reilInstruction.getThirdOperand().getValue();
        if (ReilHelpers.isConditionalJump(reilInstruction)) {
            // If we have a conditional jump we have to add two edges.
            edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, null, EdgeType.JUMP_CONDITIONAL_FALSE));
            if (Convert.isDecString(jumpTarget)) {
                edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, toReilAddress(jumpTarget), EdgeType.JUMP_CONDITIONAL_TRUE));
            } else if (reilInstruction.getThirdOperand().getType() == OperandType.SUB_ADDRESS) {
                final String[] parts = jumpTarget.split("\\.");
                edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, toReilAddress(parts), EdgeType.JUMP_CONDITIONAL_TRUE));
            }
        } else if (ReilHelpers.isFunctionCall(reilInstruction)) {
            edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, null, EdgeType.JUMP_UNCONDITIONAL));
        } else if (Convert.isDecString(jumpTarget)) {
            edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, toReilAddress(jumpTarget), EdgeType.JUMP_UNCONDITIONAL));
        } else if (reilInstruction.getThirdOperand().getType() == OperandType.SUB_ADDRESS) {
            final String[] parts = jumpTarget.split("\\.");
            edgepairs.add(new Triple<ReilBlock, IAddress, EdgeType>(reilBlock, toReilAddress(parts), EdgeType.JUMP_UNCONDITIONAL));
        }
    }
}
Also used : Triple(com.google.security.zynamics.zylib.general.Triple) ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilBlock(com.google.security.zynamics.reil.ReilBlock) EdgeType(com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType) IAddress(com.google.security.zynamics.zylib.disassembly.IAddress)

Example 14 with ReilInstruction

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

the class ReilGraphGenerator method createGraphElements.

/**
   * Creates REIL basic blocks and edges from a list of REIL instructions.
   * 
   * @param instructionList A list of REIL instructions.
   * @param nativeJumpTargets Additional jump targets for the algorithm to consider.
   * 
   * @return A pair containing the blocks and edges created from the REIL instructions.
   */
public static Pair<List<ReilBlock>, List<ReilEdge>> createGraphElements(final Collection<List<ReilInstruction>> instructionList, final Collection<IAddress> nativeJumpTargets) {
    final BasicBlockGenerator generator = new BasicBlockGenerator(instructionList, nativeJumpTargets);
    final List<ReilBlock> blocks = generator.getBlocks();
    final ArrayList<Triple<ReilBlock, IAddress, EdgeType>> edgepairs = generator.getEdges();
    final List<ReilEdge> edges = new ArrayList<ReilEdge>();
    for (final Triple<ReilBlock, IAddress, EdgeType> p : edgepairs) {
        final ReilBlock source = p.first();
        final IAddress target = p.second();
        final EdgeType edgeType = p.third();
        if (target != null) {
            for (final ReilBlock block : blocks) {
                for (final ReilInstruction instruction : block.getInstructions()) {
                    if (target.equals(instruction.getAddress())) {
                        final ReilEdge edge = new ReilEdge(source, block, edgeType);
                        edges.add(edge);
                        ReilBlock.link(source, block, edge);
                    }
                }
            }
        } else {
            // Unknown target address
            final int index = blocks.indexOf(source);
            if (blocks.size() > (index + 1)) {
                final ReilEdge edge = new ReilEdge(source, blocks.get(index + 1), edgeType);
                edges.add(edge);
                ReilBlock.link(source, blocks.get(index + 1), edge);
            }
        }
    }
    return new Pair<List<ReilBlock>, List<ReilEdge>>(blocks, edges);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList) EdgeType(com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType) IAddress(com.google.security.zynamics.zylib.disassembly.IAddress) Triple(com.google.security.zynamics.zylib.general.Triple) Pair(com.google.security.zynamics.zylib.general.Pair)

Example 15 with ReilInstruction

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

the class ReilTranslator method translate.

/**
   * Translates a disassembled function to REIL code.
   * 
   * @param environment The translation environment for the translation process
   * @param function The disassembled function
   * 
   * @return The function translated to REIL code
   * 
   * @throws InternalTranslationException Thrown if an internal error occurs
   */
public ReilFunction translate(final ITranslationEnvironment environment, final IBlockContainer<InstructionType> function, final List<ITranslationExtension<InstructionType>> extensions) throws InternalTranslationException {
    final LinkedHashMap<ICodeContainer<InstructionType>, List<ReilInstruction>> instructionMap = new LinkedHashMap<ICodeContainer<InstructionType>, List<ReilInstruction>>();
    final Map<IInstruction, ReilInstruction> firstMap = new HashMap<IInstruction, ReilInstruction>();
    final Map<IInstruction, ReilInstruction> lastMap = new HashMap<IInstruction, ReilInstruction>();
    final List<List<ReilInstruction>> delayedTrueBranches = new ArrayList<List<ReilInstruction>>();
    for (final ICodeContainer<InstructionType> block : function.getBasicBlocks()) {
        final Iterable<InstructionType> blockInstructions = block.getInstructions();
        final IInstruction lastBlockInstruction = Iterables.getLast(blockInstructions);
        final boolean endsWithInlining = isInlineSource(block);
        final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
        instructionMap.put(block, instructions);
        for (final InstructionType instruction : blockInstructions) {
            environment.nextInstruction();
            final ITranslator<InstructionType> translator = m_translators.get(instruction.getArchitecture().toUpperCase());
            if (translator == null) {
                throw new InternalTranslationException("Could not translate instruction from unknown architecture " + instruction.getArchitecture());
            }
            try {
                final List<ReilInstruction> result = translator.translate(environment, instruction, extensions);
                instructions.addAll(result);
                if (endsWithInlining && (instruction == lastBlockInstruction)) {
                    // We skip the last JCC instruction of blocks that were split by inlining. In 99%
                    // of all cases this should be the inlined call; unless the user removed the
                    // call from the block.
                    final ReilInstruction lastInstruction = instructions.get(instructions.size() - 1);
                    if (lastInstruction.getMnemonic().equals(ReilHelpers.OPCODE_JCC) && lastInstruction.getMetaData().containsKey("isCall")) {
                        instructions.remove(instructions.size() - 1);
                        result.remove(result.size() - 1);
                    }
                }
                firstMap.put(instruction, getFirstInstruction(result));
                lastMap.put(instruction, getLastInstruction(result));
            } catch (final InternalTranslationException exception) {
                exception.setInstruction(instruction);
                throw exception;
            }
        }
        // In this step we have to consider delayed branches of the form
        //
        // BRANCH CONDITION, SOMEWHERE
        // EXECUTE ALWAYS
        //
        // We basically re-order the instructions to
        //
        // EVALUATE CONDITION -> TEMP
        // EXECUTE ALWAYS
        // BRANCH TEMP, SOMEWHERE
        final IInstruction secondLastInstruction = Iterables.size(block.getInstructions()) > 2 ? Iterables.get(block.getInstructions(), Iterables.size(block.getInstructions()) - 2, null) : null;
        if (secondLastInstruction != null) {
            final List<ReilInstruction> secondLastReil = getReilInstructions(secondLastInstruction, instructions);
            if (ReilHelpers.isDelayedBranch(secondLastReil.get(secondLastReil.size() - 1))) {
                final IInstruction lastInstruction = getLastInstruction(block);
                final List<ReilInstruction> lastReil = getReilInstructions(lastInstruction, instructions);
                if (secondLastReil.get(secondLastReil.size() - 1).getMnemonic().equals(ReilHelpers.OPCODE_JCC)) {
                    instructions.removeAll(lastReil);
                    instructions.addAll(instructions.size() - 1, lastReil);
                }
            } else if (ReilHelpers.isDelayedTrueBranch(secondLastReil.get(secondLastReil.size() - 1))) {
                final IInstruction lastInstruction = getLastInstruction(block);
                final List<ReilInstruction> lastReil = getReilInstructions(lastInstruction, instructions);
                delayedTrueBranches.add(lastReil);
            }
        }
    }
    // In this step we determine all jump targets of the input graph.
    // We need them later because not all original jump targets can be
    // found in the translated REIL graph. The reason for this is that
    // source instructions of edges in the input graph do not necessarily
    // have a reference to the address of the edge target. This happens
    // for example when removing the first instruction from a code node.
    // The edge still goes to the code node, but the jump instruction now
    // refers to the removed instruction.
    final Collection<IAddress> nativeJumpTargets = getBlockAddresses(function);
    final Pair<List<ReilBlock>, List<ReilEdge>> pair = ReilGraphGenerator.createGraphElements(instructionMap.values(), nativeJumpTargets);
    final List<ReilBlock> nodes = pair.first();
    final List<ReilEdge> edges = pair.second();
    // In a post-processing step all edges which could not be determined
    // from the REIL instructions alone are inserted into the graph.
    insertNativeEdges(function.getBasicBlockEdges(), nodes, edges, firstMap, lastMap);
    handleDelayedTrueBranches(nodes, edges, delayedTrueBranches);
    return new ReilFunction("REIL - " + function.getName(), new ReilGraph(nodes, edges));
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) IInstruction(com.google.security.zynamics.zylib.disassembly.IInstruction) ICodeContainer(com.google.security.zynamics.zylib.disassembly.ICodeContainer) ArrayList(java.util.ArrayList) List(java.util.List) ReilGraph(com.google.security.zynamics.reil.ReilGraph) ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ReilFunction(com.google.security.zynamics.reil.ReilFunction) IAddress(com.google.security.zynamics.zylib.disassembly.IAddress)

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