use of com.google.security.zynamics.reil.ReilInstruction 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.ReilInstruction in project binnavi by google.
the class ReilInterpreter method interpret.
/**
* Interprets a list of instructions in the current REIL interpreter
*
* @param instructions The instructions to interpret
* @param entryPoint The offset of the first instruction to interpret
* @throws InterpreterException
*/
public void interpret(final HashMap<BigInteger, List<ReilInstruction>> instructions, final BigInteger entryPoint) throws InterpreterException {
cpuPolicy.start(this);
interpreterPolicy.start();
final String programCounter = cpuPolicy.getProgramCounter();
Preconditions.checkNotNull(programCounter, "Error: CPU Policy returned an invalid program counter");
// Set the program counter to the entry point
setRegister(programCounter, entryPoint, cpuPolicy.getRegisterSize(programCounter), ReilRegisterStatus.DEFINED);
while (true) {
BigInteger pc = nativeToReil(getVariableValue(programCounter));
interpreterPolicy.nextInstruction(this);
log("Interpreting: %X%n", pc.longValue());
if (!instructions.containsKey(pc)) {
throw new InterpreterException(String.format("Error: Instruction at offset %X not found", pc));
}
final List<ReilInstruction> instructionList = instructions.get(pc);
if ((instructionList == null) || (instructionList.size() == 0)) {
throw new InterpreterException(String.format("Error: Instruction at offset %X has invalid REIL code", pc));
}
setRegister(SUB_PC, BigInteger.ZERO, OperandSize.DWORD, ReilRegisterStatus.DEFINED);
int subPc = getVariableValue(SUB_PC).intValue();
while (subPc < instructionList.size()) {
final ReilInstruction inst = instructionList.get(subPc);
log("Next instruction: " + inst.toString().replaceAll("%", ""));
for (final ReilRegister r : registers.values()) {
log("%s: %X%n", r.getRegister(), r.getValue());
}
interpretInstruction(inst, programCounter);
final int newSubPc = getVariableValue(SUB_PC).intValue();
if (subPc == newSubPc) {
subPc = newSubPc + 1;
} else {
subPc = newSubPc;
}
setRegister(SUB_PC, BigInteger.valueOf(subPc), OperandSize.DWORD, ReilRegisterStatus.DEFINED);
}
final BigInteger pcNew = getVariableValue(programCounter);
if (pc.equals(nativeToReil(pcNew))) {
pc = pcNew.add(BigInteger.ONE);
} else {
pc = pcNew;
}
if (pcNew.equals(BigInteger.valueOf(4294967295L))) {
break;
}
if (!searchNextPc(pc, instructions, programCounter)) {
break;
}
}
interpreterPolicy.end();
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class ReilTranslator method insertNativeEdges.
/**
* Inserts missing edges that could not be deduced automatically from the REIL instructions and
* their operands.
*
* @param nativeEdges List of native edges of the input graph.
* @param nodes List of translated REIL nodes.
* @param edges List of translated REIL edges. This list is extended by the function.
* @param firstMap Maps between native instructions and their first REIL instructions.
* @param lastMap Maps between native instructions and their last REIL instructions.
*/
private static void insertNativeEdges(final List<? extends ICodeEdge<?>> nativeEdges, final List<ReilBlock> nodes, final List<ReilEdge> edges, final Map<IInstruction, ReilInstruction> firstMap, final Map<IInstruction, ReilInstruction> lastMap) {
for (final ICodeEdge<?> nativeEdge : nativeEdges) {
final Object source = nativeEdge.getSource();
final Object target = nativeEdge.getTarget();
if ((source instanceof ICodeContainer) && (target instanceof ICodeContainer)) {
final ICodeContainer<?> sourceCodeNode = (ICodeContainer<?>) source;
final ICodeContainer<?> targetCodeNode = (ICodeContainer<?>) target;
final IInstruction sourceInstruction = getLastInstruction(sourceCodeNode);
final IInstruction targetInstruction = getFirstInstruction(targetCodeNode);
final ReilInstruction sourceReilInstruction = lastMap.get(sourceInstruction);
final ReilInstruction targetReilInstruction = firstMap.get(targetInstruction);
insertNativeEdge(nodes, edges, nativeEdge, sourceReilInstruction, targetReilInstruction);
}
}
}
use of com.google.security.zynamics.reil.ReilInstruction 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.ReilInstruction in project binnavi by google.
the class ARMBaseTranslator method countInnerInstructions.
protected int countInnerInstructions(final IInstruction instruction) throws InternalTranslationException {
final List<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
translateCore(new StandardEnvironment(), instruction, instructions);
return instructions.size();
}
Aggregations