use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class TranslatorMIPS method translate.
/**
* Translates a MIPS instruction to REIL code
*
* @param environment A valid translation environment
* @param instruction The MIPS instruction to translate
*
* @return The list of REIL instruction the MIPS instruction was translated to
*
* @throws InternalTranslationException An internal translation error occurred
* @throws IllegalArgumentException Any of the arguments passed to the function are invalid
*
*/
@Override
public List<ReilInstruction> translate(final ITranslationEnvironment environment, final InstructionType instruction, final List<ITranslationExtension<InstructionType>> extensions) throws InternalTranslationException {
Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
Preconditions.checkNotNull(instruction, "Error: Argument instruction can't be null");
final String mnemonic = instruction.getMnemonic();
// final long instLength = instruction.getLength();
if (mnemonic == null) {
return new ArrayList<ReilInstruction>();
}
final IInstructionTranslator translator = translators.get(mnemonic.toLowerCase());
if (translators.containsKey(mnemonic.toLowerCase())) {
final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
translator.translate(environment, instruction, instructions);
for (final ITranslationExtension<InstructionType> extension : extensions) {
extension.postProcess(environment, instruction, instructions);
}
return instructions;
} else {
return Lists.newArrayList(ReilHelpers.createUnknown(ReilHelpers.toReilAddress(instruction.getAddress()).toLong()));
}
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class TranslatorARM method translate.
/**
* Translates an ARM or THUMB instruction to REIL code
*
* @param environment A valid translation environment
* @param instruction The ARM or THUMB instruction to translate
*
* @return The list of REIL instruction the ARM instruction was translated to
*
* @throws InternalTranslationException An internal translation error occurred
* @throws IllegalArgumentException Any of the arguments passed to the function are invalid
*
*/
@Override
public List<ReilInstruction> translate(final ITranslationEnvironment environment, final InstructionType instruction, final List<ITranslationExtension<InstructionType>> extensions) throws InternalTranslationException {
Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
Preconditions.checkNotNull(instruction, "Error: Argument instruction can't be null");
final String mnemonic = instruction.getMnemonic();
final long instLength = instruction.getLength();
// TODO: >= 4 is a workaround because IDA merges multiple instructions into 1
final String normalizedMnemonic = instLength >= 4 ? mnemonic : "THUMB" + mnemonic;
final IInstructionTranslator translator = translators.get(normalizedMnemonic);
if (translators.containsKey(normalizedMnemonic)) {
final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
translator.translate(environment, instruction, instructions);
return instructions;
} else if (mnemonic == null) {
return new ArrayList<ReilInstruction>();
} else {
return Lists.newArrayList(ReilHelpers.createUnknown(ReilHelpers.toReilAddress(instruction.getAddress()).toLong()));
}
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class COperandsDeterminer method getRegisters.
/**
* Returns the registers read and written by a native instruction.
*
* @param instruction The instruction whose accessed registers are returned.
*
* @return The read and written registers of the instruction.
*
* @throws InternalTranslationException Thrown if the instruction could not be translated to REIL.
*/
public static Pair<Set<String>, Set<String>> getRegisters(final INaviInstruction instruction) throws InternalTranslationException {
final Set<String> inSet = new HashSet<String>();
final Set<String> outSet = new HashSet<String>();
final ReilTranslator<INaviInstruction> translator = new ReilTranslator<INaviInstruction>();
final DirectedGraph<ReilBlock, ReilEdge> reilCode = translator.translate(new StandardEnvironment(), instruction);
final boolean translatingReil = instruction.getArchitecture().equals("REIL");
for (final ReilBlock reilBlock : reilCode) {
for (final ReilInstruction reilInstruction : reilBlock) {
if (writesThirdOperand(reilInstruction, translatingReil)) {
outSet.add(reilInstruction.getThirdOperand().getValue());
}
if (!writesThirdOperand(reilInstruction, translatingReil) && isRegister(reilInstruction.getThirdOperand(), translatingReil)) {
// JCC + STM
inSet.add(reilInstruction.getThirdOperand().getValue());
}
if (isRegister(reilInstruction.getFirstOperand(), translatingReil)) {
inSet.add(reilInstruction.getFirstOperand().getValue());
}
if (isRegister(reilInstruction.getSecondOperand(), translatingReil)) {
inSet.add(reilInstruction.getSecondOperand().getValue());
}
}
}
return new Pair<Set<String>, Set<String>>(inSet, outSet);
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class CReilViewCreator method create.
/**
* Creates a REIL view object from a REIL graph.
*
* @param container The container in which the new REIL view is created.
* @param graph The graph that contains the REIL code to be shown in the view.
*
* @return The created REIL code view.
*/
public static INaviView create(final INaviModule container, final ReilGraph graph) {
Preconditions.checkNotNull(container, "IE01809: Container argument can not be null");
Preconditions.checkNotNull(graph, "IE01815: Graph argument can not be null");
final INaviView view = container.getContent().getViewContainer().createView("REIL View", "");
final Map<ReilBlock, CCodeNode> nodeMap = new HashMap<ReilBlock, CCodeNode>();
for (final ReilBlock block : graph) {
final List<INaviInstruction> instructions = new ArrayList<INaviInstruction>();
for (final ReilInstruction reilInstruction : block) {
final List<COperandTree> operands = new ArrayList<COperandTree>();
if (reilInstruction.getFirstOperand().getType() == OperandType.EMPTY) {
operands.add(getEmptyOperand(container));
} else {
operands.add(convert(container, reilInstruction.getFirstOperand()));
}
if (reilInstruction.getSecondOperand().getType() == OperandType.EMPTY) {
operands.add(getEmptyOperand(container));
} else {
operands.add(convert(container, reilInstruction.getSecondOperand()));
}
if (reilInstruction.getThirdOperand().getType() == OperandType.EMPTY) {
operands.add(getEmptyOperand(container));
} else {
operands.add(convert(container, reilInstruction.getThirdOperand()));
}
final INaviInstruction convertedInstruction = container.createInstruction(reilInstruction.getAddress(), reilInstruction.getMnemonic(), operands, new byte[0], "REIL");
instructions.add(convertedInstruction);
}
final CCodeNode node = view.getContent().createCodeNode(null, instructions);
node.setColor(ConfigManager.instance().getColorSettings().getBasicBlocksColor());
nodeMap.put(block, node);
}
for (final ReilEdge edge : graph.getEdges()) {
final CNaviViewEdge reilEdge = view.getContent().createEdge(nodeMap.get(edge.getSource()), nodeMap.get(edge.getTarget()), edge.getType());
EdgeInitializer.adjustColor(reilEdge);
}
return view;
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class ShlTranslator method translate.
// TODO(timkornau): Check this code again
/**
* Translates a SHL instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The SHL instruction to translate.
* @param instructions The generated REIL code will be added to this list
*
* @throws InternalTranslationException if any of the arguments are null the passed instruction is
* not an SHL instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
Preconditions.checkNotNull(instruction, "Error: Argument instruction can't be null");
Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
if (!instruction.getMnemonic().equals("shl") && !instruction.getMnemonic().equals("sal")) {
throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (wrong mnemonic)");
}
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final List<? extends IOperandTree> operands = instruction.getOperands();
// Load source operand.
final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
instructions.addAll(firstResult.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
// Load destination operand.
final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
instructions.addAll(secondResult.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final OperandSize size1 = firstResult.getSize();
final OperandSize size2 = secondResult.getSize();
final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
final String operand1 = firstResult.getRegister();
final String operand2 = secondResult.getRegister();
final String shiftMsbLsbValue = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(size1));
final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(size1));
final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
final String modValue = String.valueOf(size1.getBitSize());
final String carryMask = String.valueOf(Helpers.getCarryMask(size1));
final String shiftCarryValue = String.valueOf(-size1.getBitSize());
final String shiftMask = environment.getNextVariableString();
final String shiftMaskZero = environment.getNextVariableString();
final String shiftMaskLessOne = environment.getNextVariableString();
final String shiftMaskOne = environment.getNextVariableString();
final String result = environment.getNextVariableString();
final String truncatedResult = environment.getNextVariableString();
final String msbResult = environment.getNextVariableString();
final String carryResult = environment.getNextVariableString();
final int before = instructions.size();
final List<ReilInstruction> writebackInstructions = new ArrayList<>();
// Write the result of the SHR operation back into the target register
Helpers.writeBack(environment, offset + 16, operands.get(0), truncatedResult, size1, firstResult.getAddress(), firstResult.getType(), writebackInstructions);
// Make sure to shift less than the size1 of the register
instructions.add(ReilHelpers.createMod(offset, size2, operand2, size2, modValue, size2, shiftMask));
// Find out if the shift mask is 0 and negate the result
instructions.add(ReilHelpers.createBisz(offset + 1, size2, shiftMask, OperandSize.BYTE, shiftMaskZero));
// Find out if the shift mask is 1
instructions.add(ReilHelpers.createSub(offset + 2, size2, "1", size2, shiftMask, size2, shiftMaskLessOne));
instructions.add(ReilHelpers.createBisz(offset + 3, size2, shiftMaskLessOne, OperandSize.BYTE, shiftMaskOne));
// Perform the shift
instructions.add(ReilHelpers.createBsh(offset + 4, size1, operand1, size2, shiftMask, resultSize, result));
// Truncate the result to the correct size1
instructions.add(ReilHelpers.createAnd(offset + 5, resultSize, result, size1, truncateMask, size1, truncatedResult));
// Don't change the flags if the shift value was zero (jump to writeBack).
final String jmpGoalWriteBack = String.format("%d.%d", instruction.getAddress().toLong(), before + 16);
instructions.add(ReilHelpers.createJcc(offset + 6, OperandSize.BYTE, shiftMaskZero, OperandSize.ADDRESS, jmpGoalWriteBack));
// Extract the MSB of the result and shift it into the SF
instructions.add(ReilHelpers.createAnd(offset + 7, resultSize, result, resultSize, msbMask, resultSize, msbResult));
instructions.add(ReilHelpers.createBsh(offset + 8, resultSize, msbResult, resultSize, shiftMsbLsbValue, OperandSize.BYTE, Helpers.SIGN_FLAG));
// Set the CF to the MSB of the result
instructions.add(ReilHelpers.createAnd(offset + 9, resultSize, result, resultSize, carryMask, resultSize, carryResult));
instructions.add(ReilHelpers.createBsh(offset + 10, resultSize, carryResult, resultSize, shiftCarryValue, OperandSize.BYTE, Helpers.CARRY_FLAG));
// Set the ZF
instructions.add(ReilHelpers.createBisz(offset + 11, size1, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
// The OF needs to be set to a different value if the shift-mask was 1
final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), before + 15);
instructions.add(ReilHelpers.createJcc(offset + 12, OperandSize.BYTE, shiftMaskOne, OperandSize.ADDRESS, jmpGoal2));
// Set the OF to undefined if the shift-mask was positive but not 1
instructions.add(ReilHelpers.createUndef(offset + 13, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
// Jump to writeBack.
instructions.add(ReilHelpers.createJcc(offset + 14, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalWriteBack));
// Set the OF if the shift-mask was 1.
instructions.add(ReilHelpers.createXor(offset + 15, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
// Write back to the target register.
instructions.addAll(writebackInstructions);
}
Aggregations