Search in sources :

Example 1 with ReilEdge

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

the class COperandsDeterminer method getRegisters.

/**
   * Returns the registers read and written by a native instruction.
   * 
   * @param instruction The instruction whose accessed registers are returned.
   * 
   * @return The read and written registers of the instruction.
   * 
   * @throws InternalTranslationException Thrown if the instruction could not be translated to REIL.
   */
public static Pair<Set<String>, Set<String>> getRegisters(final INaviInstruction instruction) throws InternalTranslationException {
    final Set<String> inSet = new HashSet<String>();
    final Set<String> outSet = new HashSet<String>();
    final ReilTranslator<INaviInstruction> translator = new ReilTranslator<INaviInstruction>();
    final DirectedGraph<ReilBlock, ReilEdge> reilCode = translator.translate(new StandardEnvironment(), instruction);
    final boolean translatingReil = instruction.getArchitecture().equals("REIL");
    for (final ReilBlock reilBlock : reilCode) {
        for (final ReilInstruction reilInstruction : reilBlock) {
            if (writesThirdOperand(reilInstruction, translatingReil)) {
                outSet.add(reilInstruction.getThirdOperand().getValue());
            }
            if (!writesThirdOperand(reilInstruction, translatingReil) && isRegister(reilInstruction.getThirdOperand(), translatingReil)) {
                // JCC + STM
                inSet.add(reilInstruction.getThirdOperand().getValue());
            }
            if (isRegister(reilInstruction.getFirstOperand(), translatingReil)) {
                inSet.add(reilInstruction.getFirstOperand().getValue());
            }
            if (isRegister(reilInstruction.getSecondOperand(), translatingReil)) {
                inSet.add(reilInstruction.getSecondOperand().getValue());
            }
        }
    }
    return new Pair<Set<String>, Set<String>>(inSet, outSet);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ReilTranslator(com.google.security.zynamics.reil.translators.ReilTranslator) HashSet(java.util.HashSet) INaviInstruction(com.google.security.zynamics.binnavi.disassembly.INaviInstruction) StandardEnvironment(com.google.security.zynamics.reil.translators.StandardEnvironment) Pair(com.google.security.zynamics.zylib.general.Pair)

Example 2 with ReilEdge

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

the class CReilViewCreator method create.

/**
   * Creates a REIL view object from a REIL graph.
   * 
   * @param container The container in which the new REIL view is created.
   * @param graph The graph that contains the REIL code to be shown in the view.
   * 
   * @return The created REIL code view.
   */
public static INaviView create(final INaviModule container, final ReilGraph graph) {
    Preconditions.checkNotNull(container, "IE01809: Container argument can not be null");
    Preconditions.checkNotNull(graph, "IE01815: Graph argument can not be null");
    final INaviView view = container.getContent().getViewContainer().createView("REIL View", "");
    final Map<ReilBlock, CCodeNode> nodeMap = new HashMap<ReilBlock, CCodeNode>();
    for (final ReilBlock block : graph) {
        final List<INaviInstruction> instructions = new ArrayList<INaviInstruction>();
        for (final ReilInstruction reilInstruction : block) {
            final List<COperandTree> operands = new ArrayList<COperandTree>();
            if (reilInstruction.getFirstOperand().getType() == OperandType.EMPTY) {
                operands.add(getEmptyOperand(container));
            } else {
                operands.add(convert(container, reilInstruction.getFirstOperand()));
            }
            if (reilInstruction.getSecondOperand().getType() == OperandType.EMPTY) {
                operands.add(getEmptyOperand(container));
            } else {
                operands.add(convert(container, reilInstruction.getSecondOperand()));
            }
            if (reilInstruction.getThirdOperand().getType() == OperandType.EMPTY) {
                operands.add(getEmptyOperand(container));
            } else {
                operands.add(convert(container, reilInstruction.getThirdOperand()));
            }
            final INaviInstruction convertedInstruction = container.createInstruction(reilInstruction.getAddress(), reilInstruction.getMnemonic(), operands, new byte[0], "REIL");
            instructions.add(convertedInstruction);
        }
        final CCodeNode node = view.getContent().createCodeNode(null, instructions);
        node.setColor(ConfigManager.instance().getColorSettings().getBasicBlocksColor());
        nodeMap.put(block, node);
    }
    for (final ReilEdge edge : graph.getEdges()) {
        final CNaviViewEdge reilEdge = view.getContent().createEdge(nodeMap.get(edge.getSource()), nodeMap.get(edge.getTarget()), edge.getType());
        EdgeInitializer.adjustColor(reilEdge);
    }
    return view;
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) HashMap(java.util.HashMap) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList) CNaviViewEdge(com.google.security.zynamics.binnavi.disassembly.CNaviViewEdge) INaviView(com.google.security.zynamics.binnavi.disassembly.views.INaviView) CCodeNode(com.google.security.zynamics.binnavi.disassembly.CCodeNode) COperandTree(com.google.security.zynamics.binnavi.disassembly.COperandTree) INaviInstruction(com.google.security.zynamics.binnavi.disassembly.INaviInstruction)

Example 3 with ReilEdge

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

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

Example 5 with ReilEdge

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

the class ReilTranslator method insertNativeEdge.

/**
   * Inserts a single missing edge that could not be deduced automatically from the REIL
   * instructions and their operands.
   * 
   * @param nodes List of translated REIL nodes.
   * @param edges List of translated REIL edges. This list is extended by the function.
   * @param nativeEdge The native to check for and add if necessary.
   * @param sourceReilInstruction Source REIL instruction of the edge.
   * @param targetReilInstruction Target REIL instruction of the edge.
   */
private static void insertNativeEdge(final List<ReilBlock> nodes, final List<ReilEdge> edges, final ICodeEdge<?> nativeEdge, final ReilInstruction sourceReilInstruction, final ReilInstruction targetReilInstruction) {
    for (final ReilBlock node : nodes) {
        if ((sourceReilInstruction == getLastInstruction(node)) && !hasEdge(nodes, node, targetReilInstruction)) {
            final EdgeType edgeType = ReilHelpers.isJump(sourceReilInstruction) ? nativeEdge.getType() : EdgeType.JUMP_UNCONDITIONAL;
            final ReilBlock targetNode = getNode(targetReilInstruction, nodes);
            final ReilEdge newEdge = new ReilEdge(node, targetNode, edgeType);
            ReilBlock.link(node, targetNode, newEdge);
            edges.add(newEdge);
        }
    }
}
Also used : ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) EdgeType(com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType)

Aggregations

ReilBlock (com.google.security.zynamics.reil.ReilBlock)16 ReilEdge (com.google.security.zynamics.reil.ReilEdge)16 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)11 ReilGraph (com.google.security.zynamics.reil.ReilGraph)10 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)4 ReilFunction (com.google.security.zynamics.reil.ReilFunction)3 InstructionGraph (com.google.security.zynamics.reil.algorithms.mono.InstructionGraph)3 OperandGraph (com.google.security.zynamics.reil.algorithms.mono.OperandGraph)3 EdgeType (com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType)3 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)2 InstructionGraphNode (com.google.security.zynamics.reil.algorithms.mono.InstructionGraphNode)2 ValueTrackerElement (com.google.security.zynamics.reil.algorithms.mono.valuetracking.ValueTrackerElement)2 IAddress (com.google.security.zynamics.zylib.disassembly.IAddress)2 Pair (com.google.security.zynamics.zylib.general.Pair)2 CCodeNode (com.google.security.zynamics.binnavi.disassembly.CCodeNode)1 CNaviViewEdge (com.google.security.zynamics.binnavi.disassembly.CNaviViewEdge)1 COperandTree (com.google.security.zynamics.binnavi.disassembly.COperandTree)1 INaviView (com.google.security.zynamics.binnavi.disassembly.views.INaviView)1