use of com.google.security.zynamics.reil.ReilBlock in project binnavi by google.
the class CombineTest method testSimple.
@Test
public void testSimple() {
final ReilInstruction instruction1 = ReilHelpers.createStr(100, OperandSize.DWORD, "0", OperandSize.DWORD, "eax");
final ReilInstruction instruction2 = ReilHelpers.createJcc(101, OperandSize.DWORD, "eax", OperandSize.DWORD, "104");
final ReilInstruction instruction3 = ReilHelpers.createAdd(102, OperandSize.DWORD, "eax", OperandSize.DWORD, "4", OperandSize.DWORD, "ebx");
final ReilInstruction instruction4 = ReilHelpers.createJcc(103, OperandSize.DWORD, "1", OperandSize.DWORD, "104");
final ReilInstruction instruction5 = ReilHelpers.createAdd(104, OperandSize.DWORD, "eax", OperandSize.DWORD, "8", OperandSize.DWORD, "ebx");
final ReilInstruction instruction6 = ReilHelpers.createStr(105, OperandSize.DWORD, "ebx", OperandSize.DWORD, "ecx");
final ReilBlock block1 = new ReilBlock(Lists.newArrayList(instruction1, instruction2));
final ReilBlock block2 = new ReilBlock(Lists.newArrayList(instruction3, instruction4));
final ReilBlock block3 = new ReilBlock(Lists.newArrayList(instruction5));
final ReilBlock block4 = new ReilBlock(Lists.newArrayList(instruction6));
final ReilEdge edge1 = new ReilEdge(block1, block2, EdgeType.JUMP_UNCONDITIONAL);
final ReilEdge edge2 = new ReilEdge(block1, block3, EdgeType.JUMP_UNCONDITIONAL);
final ReilEdge edge3 = new ReilEdge(block2, block4, EdgeType.JUMP_UNCONDITIONAL);
final ReilEdge edge4 = new ReilEdge(block3, block4, EdgeType.JUMP_UNCONDITIONAL);
ReilBlock.link(block1, block2, edge1);
ReilBlock.link(block1, block3, edge2);
ReilBlock.link(block2, block4, edge3);
ReilBlock.link(block3, block4, edge4);
final ReilFunction function = new ReilFunction("Fark", new ReilGraph(Lists.newArrayList(block1, block2, block3, block4), Lists.newArrayList(edge1, edge2, edge3, edge4)));
System.out.println(function.getGraph());
final IStateVector<InstructionGraphNode, ValueTrackerElement> result = ValueTracker.track(function);
System.out.println(result);
}
use of com.google.security.zynamics.reil.ReilBlock in project binnavi by google.
the class CReilInstructionDialog method reilGraphToText.
/**
* Converts a given REIL graph to its text representation.
*
* @param graph The REIL graph
* @return The text representation of the REIL graph
*/
private static String reilGraphToText(final ReilGraph graph) {
final List<ReilInstruction> reilInstructions = new ArrayList<ReilInstruction>();
for (final ReilBlock reilBlock : graph.getNodes()) {
reilInstructions.addAll(Lists.newArrayList(reilBlock.getInstructions()));
}
Collections.sort(reilInstructions, new Comparator<ReilInstruction>() {
@Override
public int compare(final ReilInstruction lhs, final ReilInstruction rhs) {
return (int) (lhs.getAddress().toLong() - rhs.getAddress().toLong());
}
});
final StringBuilder buffer = new StringBuilder();
for (final ReilInstruction reilInstruction : reilInstructions) {
buffer.append(reilInstruction.toString());
buffer.append('\n');
}
return buffer.toString();
}
use of com.google.security.zynamics.reil.ReilBlock 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.ReilBlock 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.ReilBlock 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);
}
Aggregations