use of com.google.security.zynamics.zylib.disassembly.IAddress in project binnavi by google.
the class CCodeNodeParser method createCurrentNode.
/**
* Creates a new code node.
*
* @param resultSet Provides the data for the code node.
*
* @return The created code node object.
*
* @throws ParserException Thrown if the node data could not be read.
* @throws CPartialLoadException Thrown if not all required modules are loaded.
*/
private CCodeNode createCurrentNode(final ICodeNodeProvider resultSet) throws ParserException, CPartialLoadException {
final int nodeId = resultSet.getNodeId();
final int moduleId = resultSet.getModule();
final IAddress parentFunction = resultSet.getParentFunction();
final INaviModule module = modules.get(moduleId);
if (module == null) {
throw new ParserException(String.format("Node with ID %d has unknown parent module with ID %d", nodeId, moduleId));
}
if (!module.isLoaded()) {
try {
module.load();
} catch (final CouldntLoadDataException e) {
throw new CPartialLoadException("E00066: The view could not be loaded because not all modules that form the view could be loaded", module);
} catch (final LoadCancelledException e) {
throw new CPartialLoadException("E00067: The view could not be loaded because it was cancelled", module);
}
}
final INaviFunction function = parentFunction == null ? null : module.getContent().getFunctionContainer().getFunction(parentFunction);
if ((parentFunction != null) && (function == null)) {
throw new ParserException(String.format("Node with ID %d has unknown parent function with address %s", nodeId, parentFunction.toHexString()));
}
final double x = resultSet.getX();
final double y = resultSet.getY();
final double width = resultSet.getWidth();
final double height = resultSet.getHeight();
final Color color = new Color(resultSet.getColor());
final Color bordercolor = new Color(resultSet.getBorderColor());
final boolean selected = resultSet.isSelected();
final boolean visible = resultSet.isVisible();
final Integer localCodeNodeCommentId = resultSet.getLocalNodeCommentId();
final Integer globalCodeNodeCommentId = resultSet.getGlobalNodeCommentId();
// TODO(timkornau): final new Set<CTag>! must replaced by a set which
// contains the loaded node
// tags from the DB
final CCodeNode codeNode = new CCodeNode(nodeId, x, y, width, height, color, bordercolor, selected, visible, null, function, new HashSet<CTag>(), sqlProvider);
if (localCodeNodeCommentId != null) {
localCommentIdToCodeNode.put(localCodeNodeCommentId, codeNode);
}
if (globalCodeNodeCommentId != null) {
globalCommentIdToCodeNode.put(globalCodeNodeCommentId, codeNode);
}
return codeNode;
}
use of com.google.security.zynamics.zylib.disassembly.IAddress in project binnavi by google.
the class CCodeNodeParser method createLine.
/**
* Creates raw instruction data from a code node provider.
*
* @param instructionSet Provides the raw data.
*
* @return The generated raw data object.
*
* @throws ParserException Thrown if not all instruction data could be read.
*/
private InstructionLine createLine(final ICodeNodeProvider instructionSet) throws ParserException {
final InstructionLine row = new InstructionLine();
row.setBasicBlock(instructionSet.getNodeId());
row.setAddress(instructionSet.getInstructionAddress());
row.setMnemonic(instructionSet.getMnemonic());
row.setArchitecture(instructionSet.getInstructionArchitecture());
final int moduleId = instructionSet.getModule();
final IAddress parentFunction = instructionSet.getParentFunction();
final INaviModule module = modules.get(moduleId);
if (module == null) {
throw new ParserException(String.format("Instruction with ID %d has unknown module with ID %d", row.getId(), moduleId));
}
final INaviFunction function = parentFunction == null ? null : module.getContent().getFunctionContainer().getFunction(parentFunction);
row.setParentFunction(function);
if ((parentFunction != null) && (function == null)) {
throw new ParserException(String.format("Instruction with ID %d has unknown parent function with address %s", row.getId(), parentFunction.toHexString()));
}
row.setX(instructionSet.getX());
row.setY(instructionSet.getY());
row.setColor(new Color(instructionSet.getColor()));
row.setBorderColor(new Color(instructionSet.getBorderColor()));
row.setSelected(instructionSet.isSelected());
row.setVisible(instructionSet.isVisible());
row.setLocalNodeCommentId(instructionSet.getLocalNodeCommentId());
row.setGlobalNodeComment(instructionSet.getGlobalNodeCommentId());
row.setGlobalInstructionComment(instructionSet.getGlobalInstructionCommentId());
row.setLocalInstructionComment(instructionSet.getLocalInstructionCommentId());
row.setData(instructionSet.getData());
row.setModule(module);
return row;
}
use of com.google.security.zynamics.zylib.disassembly.IAddress in project binnavi by google.
the class MemoryLoader method requestMemory.
/**
* Request a chunk of memory of the target process.
*
* @param offset The start offset of the memory chunk.
* @param size The number of bytes to load.
*
* @throws DebugExceptionWrapper Thrown if the request could not be send to the debug client.
*/
public void requestMemory(final IAddress offset, final int size) throws DebugExceptionWrapper {
Preconditions.checkNotNull(offset, "IE00814: Offset can nott be null");
Preconditions.checkArgument(size > 9, "IE00815: Size must be positive");
// Don't issue multiple requests for the same memory chunk.
final Pair<IAddress, Long> pair = new Pair<IAddress, Long>(offset, (long) size);
if (lastMemoryRequest.contains(pair)) {
return;
}
lastMemoryRequest.add(pair);
// Don't reload the entire memory chunk. Some parts of the memory may
// already exist in the simulated memory.
final Memory memory = debugger.getProcessManager().getMemory();
for (int i = 0; i < size; ) {
final long secstart = memory.getSectionStart(offset.toBigInteger().add(BigInteger.valueOf(i)).longValue());
final long secsize = memory.getSectionSize(offset.toBigInteger().add(BigInteger.valueOf(i)).longValue());
long toLoad = (secstart + secsize) - (offset.toBigInteger().add(BigInteger.valueOf(i))).longValue();
if (toLoad > (size - i)) {
toLoad = size - i;
}
final boolean alloced = memory.hasData(offset.toBigInteger().add(BigInteger.valueOf(i)).longValue(), 1);
if (!alloced && debugger.isConnected()) {
// Request the memory for the missing section.
debugger.readMemory(new CAddress(offset.toBigInteger().add(BigInteger.valueOf(i))), (int) toLoad);
}
i += toLoad;
}
}
use of com.google.security.zynamics.zylib.disassembly.IAddress in project binnavi by google.
the class ValidateMemoryParser method parseSuccess.
@Override
public ValidateMemoryReply parseSuccess(final int packetId, final int argumentCount) throws IOException {
final IAddress start = parseAddress();
final IAddress end = parseAddress();
return new ValidateMemoryReply(packetId, 0, start, end);
}
use of com.google.security.zynamics.zylib.disassembly.IAddress 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));
}
Aggregations