use of com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType 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);
}
}
}
use of com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType 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);
}
use of com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType 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));
}
}
}
use of com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType in project binnavi by google.
the class CInliningHelper method inlineFunctionNode.
/**
* Replaces a function node in a view with the basic blocks of the functions represented by the
* function node.
*
* @param view View where the inline operation takes place.
* @param node Node that is inlined.
*/
public static void inlineFunctionNode(final INaviView view, final INaviFunctionNode node) {
Preconditions.checkNotNull(view, "IE00119: View argument can not be null");
Preconditions.checkNotNull(node, "IE00120: Node argument can not be null");
Preconditions.checkArgument(view.isLoaded(), "IE00122: View must be loaded before it can be inlined");
Preconditions.checkArgument(view.getGraph().getNodes().contains(node), "IE00123: Code node does not belong to the view");
Preconditions.checkArgument(node.getFunction().isLoaded(), "IE00124: Function must be loaded before it can be inlined");
Preconditions.checkArgument(node.getFunction().getBasicBlockCount() != 0, "IE00125: Functions with 0 blocks can not be inlined");
GroupHelpers.expandParents(node);
final INaviGroupNode parentGroup = node.getParentGroup();
final List<INaviEdge> oldIncomingEdges = node.getIncomingEdges();
view.getContent().deleteNode(node);
// Insert the nodes and edges from the loaded function
final Triple<CCodeNode, List<CCodeNode>, ArrayList<CCodeNode>> nodes = CInliningHelper.insertNodes(view, node.getFunction(), parentGroup);
final INaviCodeNode entryNode = nodes.first();
final ArrayList<CCodeNode> returnNodes = nodes.third();
for (final INaviEdge incomingEdge : oldIncomingEdges) {
// Create edges from the parent nodes of the original block to entry node
// of the inlined function.
final EdgeType edgeType = incomingEdge.getType();
view.getContent().createEdge(incomingEdge.getSource(), entryNode, edgeType);
}
final List<INaviViewNode> graphNodes = view.getGraph().getNodes();
for (final INaviCodeNode newNode : returnNodes) {
newNode.setX(node.getX());
newNode.setY(node.getY());
for (final INaviInstruction instruction : newNode.getInstructions()) {
final List<IReference> references = getCodeReferences(instruction);
for (final IReference reference : references) {
final List<INaviViewNode> targetNodes = getTargetNode(reference, graphNodes);
for (final INaviViewNode targetNode : targetNodes) {
view.getContent().createEdge(newNode, targetNode, EdgeType.JUMP_UNCONDITIONAL);
}
}
}
}
}
use of com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType 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