use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.
the class InstructionGraph method create.
/**
* Creates an instruction graph from a REIL graph.
*
* @param graph The REIL graph to convert.
*
* @return The created instruction graph.
*/
public static InstructionGraph create(final ReilGraph graph) {
Preconditions.checkNotNull(graph, "Error: graph argument can not be null");
final List<InstructionGraphNode> nodes = new ArrayList<InstructionGraphNode>();
final List<InstructionGraphEdge> edges = new ArrayList<InstructionGraphEdge>();
final HashMap<ReilBlock, InstructionGraphNode> firstNodeMapping = new HashMap<ReilBlock, InstructionGraphNode>();
final HashMap<ReilBlock, InstructionGraphNode> lastNodeMapping = new HashMap<ReilBlock, InstructionGraphNode>();
for (final ReilBlock block : graph) {
InstructionGraphNode lastNode = null;
final ReilInstruction lastInstruction = Iterables.getLast(block.getInstructions());
for (final ReilInstruction instruction : block) {
// NOPMD by
final InstructionGraphNode currentNode = new InstructionGraphNode(instruction);
// sp on
// 04.11.08
// 14:17
nodes.add(currentNode);
if (instruction == lastInstruction) {
lastNodeMapping.put(block, currentNode);
}
if (!firstNodeMapping.containsKey(block)) {
firstNodeMapping.put(block, currentNode);
}
if (lastNode != null) {
final InstructionGraphEdge edge = // NOPMD
new InstructionGraphEdge(lastNode, currentNode, EdgeType.JUMP_UNCONDITIONAL);
// by sp
// on
// 04.11.08
// 14:18
edges.add(edge);
InstructionGraphNode.link(lastNode, currentNode, edge);
}
lastNode = currentNode;
}
}
for (final ReilBlock block : graph) {
for (final ReilEdge edge : block.getOutgoingEdges()) {
final InstructionGraphEdge newEdge = new InstructionGraphEdge(lastNodeMapping.get(block), firstNodeMapping.get(edge.getTarget()), // NOPMD by sp on 04.11.08 14:18
edge.getType());
edges.add(newEdge);
InstructionGraphNode.link(lastNodeMapping.get(block), firstNodeMapping.get(edge.getTarget()), newEdge);
}
}
return new InstructionGraph(nodes, edges);
}
use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.
the class ReilTranslator method handleDelayedTrueBranches.
/**
* This function is responsible for modifying the generated graph at all likely delayed branches.
*
* @param nodes
* @param edges
* @param delayedTrueBranches
*/
private static void handleDelayedTrueBranches(final List<ReilBlock> nodes, final List<ReilEdge> edges, final List<List<ReilInstruction>> delayedTrueBranches) {
for (final List<ReilInstruction> lastReil : delayedTrueBranches) {
// In this post-processing step we consider all the delayed branches where the delayed
// instruction is only executed if the branch is taken.
//
// We solve the problem by removing the branch-delayed instruction from the original
// block. Then we take the removed instructions to form a new block. The true branch
// of the original block is connected with the new block. The false branch of the
// original block remains unchanged.
final ReilInstruction lastReilInstruction = lastReil.get(lastReil.size() - 1);
for (final ReilBlock node : nodes) {
final Iterable<ReilInstruction> nodeInstructions = node.getInstructions();
if (Iterables.getLast(nodeInstructions) == lastReilInstruction) {
// The situation we are having here is that have located the
// node that contains the delayed instruction. In fact this node
// contains only the code of the delayed instruction. It has one
// incoming edge and two outgoing edges.
//
// We now have to rewrite the edges to make sure the jump has
// the two outgoing edges.
final ReilEdge incomingEdge = node.getIncomingEdges().get(0);
final ReilBlock parentNode = incomingEdge.getSource();
edges.remove(incomingEdge);
boolean first = true;
for (final ReilEdge outgoingEdge : node.getOutgoingEdges()) {
if (first) {
first = false;
final ReilEdge newEdge = new ReilEdge(parentNode, node, EdgeType.JUMP_CONDITIONAL_TRUE);
ReilBlock.link(parentNode, node, newEdge);
edges.add(newEdge);
final ReilEdge newEdge2 = new ReilEdge(parentNode, outgoingEdge.getTarget(), EdgeType.JUMP_CONDITIONAL_FALSE);
ReilBlock.link(parentNode, outgoingEdge.getTarget(), newEdge2);
edges.add(newEdge2);
} else {
final ReilEdge newEdge2 = new ReilEdge(node, outgoingEdge.getTarget(), outgoingEdge.getType());
ReilBlock.link(node, outgoingEdge.getTarget(), newEdge2);
edges.add(newEdge2);
}
edges.remove(outgoingEdge);
ReilBlock.unlink(outgoingEdge.getSource(), outgoingEdge.getTarget(), outgoingEdge);
}
}
}
}
}
use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.
the class TestFollowZFIncomingBackwards method generateReilGraph.
private void generateReilGraph(final List<List<String>> instructions, final List<String> edges) {
final Map<Long, ReilBlock> blocks = new HashMap<Long, ReilBlock>();
for (final List<String> currentBlockInstructions : instructions) {
final List<ReilInstruction> reilInstructions = new ArrayList<ReilInstruction>();
for (final String addressAndInstruction : currentBlockInstructions) {
final StringTokenizer tokenizer = new StringTokenizer(addressAndInstruction, ": [,]", false);
final long offset = Long.parseLong(tokenizer.nextToken(), 16);
final String mnemonic = tokenizer.nextToken();
if (mnemonic.equalsIgnoreCase("bisz") || mnemonic.equalsIgnoreCase("str") || mnemonic.equalsIgnoreCase("ldm") || mnemonic.equalsIgnoreCase("stm") || mnemonic.equalsIgnoreCase("jcc")) {
final OperandSize firstSize = OperandSize.valueOf(tokenizer.nextToken());
final String firstValue = tokenizer.nextToken();
tokenizer.nextToken();
final OperandSize thirdSize = OperandSize.valueOf(tokenizer.nextToken());
final String thirdValue = tokenizer.nextToken();
if (mnemonic.equalsIgnoreCase("bisz")) {
reilInstructions.add(ReilHelpers.createBisz(offset, firstSize, firstValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("str")) {
reilInstructions.add(ReilHelpers.createStr(offset, firstSize, firstValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("jcc")) {
reilInstructions.add(ReilHelpers.createJcc(offset, firstSize, firstValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("ldm")) {
reilInstructions.add(ReilHelpers.createLdm(offset, firstSize, firstValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("stm")) {
reilInstructions.add(ReilHelpers.createStm(offset, firstSize, firstValue, thirdSize, thirdValue));
}
} else if (mnemonic.equalsIgnoreCase("nop")) {
reilInstructions.add(ReilHelpers.createNop(offset));
} else {
final OperandSize firstSize = OperandSize.valueOf(tokenizer.nextToken());
final String firstValue = tokenizer.nextToken();
final OperandSize secondSize = OperandSize.valueOf(tokenizer.nextToken());
final String secondValue = tokenizer.nextToken();
final OperandSize thirdSize = OperandSize.valueOf(tokenizer.nextToken());
final String thirdValue = tokenizer.nextToken();
if (mnemonic.equalsIgnoreCase("add")) {
reilInstructions.add(ReilHelpers.createAdd(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("and")) {
reilInstructions.add(ReilHelpers.createAnd(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("bsh")) {
reilInstructions.add(ReilHelpers.createBsh(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("div")) {
reilInstructions.add(ReilHelpers.createDiv(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("mod")) {
reilInstructions.add(ReilHelpers.createMod(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("mul")) {
reilInstructions.add(ReilHelpers.createMul(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("or")) {
reilInstructions.add(ReilHelpers.createOr(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("sub")) {
reilInstructions.add(ReilHelpers.createSub(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
if (mnemonic.equalsIgnoreCase("xor")) {
reilInstructions.add(ReilHelpers.createXor(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
}
}
}
blocks.put(reilInstructions.get(0).getAddress().toLong(), new ReilBlock(reilInstructions));
}
final List<ReilEdge> reilEdges = new ArrayList<ReilEdge>();
for (final String edge : edges) {
final StringTokenizer edgeTokenizer = new StringTokenizer(edge, " []->");
final Long sourceAddress = Long.parseLong(edgeTokenizer.nextToken(), 16);
final EdgeType type = Enum.valueOf(EdgeType.class, edgeTokenizer.nextToken().toUpperCase());
final Long targetAddress = Long.parseLong(edgeTokenizer.nextToken(), 16);
final ReilEdge reilEdge = new ReilEdge(blocks.get(sourceAddress), blocks.get(targetAddress), type);
ReilBlock.link(blocks.get(sourceAddress), blocks.get(targetAddress), reilEdge);
}
m_graph1 = new ReilGraph(Lists.newArrayList(blocks.values()), reilEdges);
}
use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.
the class InstructionGraphTest method testOneNode.
@Test
public void testOneNode() {
final ReilBlock block1 = new ReilBlock(Lists.newArrayList(ReilHelpers.createNop(0), ReilHelpers.createNop(0), ReilHelpers.createNop(0), ReilHelpers.createNop(0), ReilHelpers.createNop(0)));
final List<ReilBlock> blocks = Lists.<ReilBlock>newArrayList(block1);
final ReilGraph rg = new ReilGraph(blocks, new ArrayList<ReilEdge>());
final InstructionGraph g = InstructionGraph.create(rg);
assertEquals(5, g.nodeCount());
assertEquals(4, g.edgeCount());
}
use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.
the class OperandGraphTest method testTwoNodes.
@Test
public void testTwoNodes() {
final Collection<ReilInstruction> instructions1 = new ArrayList<ReilInstruction>();
instructions1.add(ReilHelpers.createAdd(0, OperandSize.DWORD, "eax", OperandSize.DWORD, "123", OperandSize.QWORD, "t0"));
final Collection<ReilInstruction> instructions2 = new ArrayList<ReilInstruction>();
instructions2.add(ReilHelpers.createAnd(1, OperandSize.QWORD, "t0", OperandSize.DWORD, String.valueOf(0xFFFFFFFF), OperandSize.DWORD, "t1"));
final ReilBlock block1 = new ReilBlock(instructions1);
final ReilBlock block2 = new ReilBlock(instructions2);
final ReilEdge edge1 = new ReilEdge(block1, block2, EdgeType.JUMP_CONDITIONAL_FALSE);
ReilBlock.link(block1, block2, edge1);
final List<ReilBlock> blocks = Lists.newArrayList(block1, block2);
final List<ReilEdge> edges = Lists.newArrayList(edge1);
final ReilGraph rg = new ReilGraph(blocks, edges);
final OperandGraph g = OperandGraph.create(rg);
assertEquals(6, g.nodeCount());
assertEquals(5, g.edgeCount());
}
Aggregations