use of com.google.security.zynamics.zylib.general.Pair 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.general.Pair 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.general.Pair in project binnavi by google.
the class ReilInterpreter method loadLongValue.
/**
* Loads the value of an operand into a long value.
*
* @param operand The operand to load
* @return A pair made of a bool and a long value. The bool indicates whether loading the value
* was successful.
*/
private Pair<Boolean, BigInteger> loadLongValue(final ReilOperand operand) {
final OperandType type = operand.getType();
String value = operand.getValue();
if (type == OperandType.INTEGER_LITERAL) {
return new Pair<Boolean, BigInteger>(true, new BigInteger(value));
} else if (type == OperandType.REGISTER) {
// Check if we have a negative prefix before the register name. This is
// a bit of a hack, because we never explicitly stated that we would allow
// a negation of a register operand in REIL.
// TODO(thomasdullien) remove this code once we have introduced explicit
// left-shift and right-shift instructions.
value = (value.charAt(0) == '-') ? operand.getValue().substring(1) : value;
return !isDefined(value) ? new Pair<Boolean, BigInteger>(false, BigInteger.ZERO) : new Pair<Boolean, BigInteger>(true, getVariableValue(value));
} else {
return new Pair<Boolean, BigInteger>(false, BigInteger.ZERO);
}
}
use of com.google.security.zynamics.zylib.general.Pair in project binnavi by google.
the class RegisterTrackingTransformationProvider method transformNormalInstructionForward.
private Pair<RegisterSetLatticeElement, RegisterSetLatticeElement> transformNormalInstructionForward(final ReilInstruction ins, final RegisterSetLatticeElement state) {
final ReilOperand in1 = ins.getFirstOperand();
final ReilOperand in2 = ins.getSecondOperand();
final ReilOperand out = ins.getThirdOperand();
final Set<String> inputRegisters = new TreeSet<String>();
if (in1.getType() == OperandType.REGISTER) {
inputRegisters.add(in1.getValue());
}
if (in2.getType() == OperandType.REGISTER) {
inputRegisters.add(in2.getValue());
}
// If the intersection of inputRegisters and state is empty, untaint the
// output register. Else, taint the output register.
final RegisterSetLatticeElement outputstate = state.copy();
if (!state.isTainted(inputRegisters)) {
outputstate.untaint(out.getValue());
} else {
for (final String register : inputRegisters) {
if (state.isTainted(register)) {
outputstate.addReadReg(register);
}
}
outputstate.taint(out.getValue());
}
// edge of a conditional branch.
return new Pair<RegisterSetLatticeElement, RegisterSetLatticeElement>(outputstate, null);
}
use of com.google.security.zynamics.zylib.general.Pair in project binnavi by google.
the class RegisterTrackingTransformationProvider method transformNormalInstructionBackward.
private Pair<RegisterSetLatticeElement, RegisterSetLatticeElement> transformNormalInstructionBackward(final ReilInstruction ins, final RegisterSetLatticeElement state) {
final ReilOperand in1 = ins.getFirstOperand();
final ReilOperand in2 = ins.getSecondOperand();
final ReilOperand out = ins.getThirdOperand();
final Set<String> inputRegisters = new TreeSet<String>();
if (in1.getType() == OperandType.REGISTER) {
inputRegisters.add(in1.getValue());
}
if (in2.getType() == OperandType.REGISTER) {
inputRegisters.add(in2.getValue());
}
final RegisterSetLatticeElement outputstate = state.copy();
if (state.isTainted(out.getValue())) {
if (inputRegisters.isEmpty()) {
outputstate.untaint(out.getValue());
} else {
outputstate.untaint(out.getValue());
outputstate.addReadReg(out.getValue());
for (final String register : inputRegisters) {
outputstate.taint(register);
}
}
}
// edge of a conditional branch.
return new Pair<RegisterSetLatticeElement, RegisterSetLatticeElement>(outputstate, null);
}
Aggregations