use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class Helpers method processInOperandArithmetic.
/**
* Deals with complicated arithmetic within operands, such as [ebx+ecx*2+2]
*
* @param partialResults The list of translations for the subtrees of the operand
* @param environment The translation environment to track temp registers etc.
* @param baseOffset The base address of this instruction.
* @param expression The current node in the tree to process.
* @return The result of the translation for the operand arithmetic.
* @throws InternalTranslationException
*/
private static TranslationResult processInOperandArithmetic(List<TranslationResult> partialResults, ITranslationEnvironment environment, long baseOffset, IOperandTreeNode expression) throws InternalTranslationException {
final String value = expression.getValue();
final OperandSize archSize = environment.getArchitectureSize();
final OperandSize nextSize = TranslationHelpers.getNextSize(archSize);
// This result will be filled with the merged results from partialResults.
TranslationResult finalResult = new TranslationResult("NEEDS_REPLACEMENT", archSize, TranslationResultType.REGISTER, "", new ArrayList<ReilInstruction>(), baseOffset);
if (value.equals("+") || (value.equals("*"))) {
// Join all the instructions from all partial results into a new list.
ArrayList<ReilInstruction> allInstructions = new ArrayList<>();
for (TranslationResult result : partialResults) {
allInstructions.addAll(result.getInstructions());
}
finalResult.updateBaseAndReil(baseOffset, allInstructions);
String source1 = partialResults.get(0).getRegister();
String source2 = partialResults.get(1).getRegister();
String currentTemporary = environment.getNextVariableString();
// to not reuse the temporaries here in the future.
for (int index = 2; index <= partialResults.size(); index++) {
addPlusOrTimesInOperandArithmetic(environment, value, source1, source2, currentTemporary, finalResult);
if (index < partialResults.size()) {
source1 = partialResults.get(index).getRegister();
source2 = currentTemporary;
}
}
// Add an AND to mask off extra bits in the address calculation.
final String truncationMask = String.valueOf(TranslationHelpers.getAllBitsMask(archSize));
finalResult.addInstruction(ReilHelpers.createAnd(0, nextSize, currentTemporary, nextSize, truncationMask, archSize, currentTemporary));
finalResult.updateResult(currentTemporary, archSize, "", TranslationResultType.REGISTER);
} else if (value.equals(":")) {
throw new InternalTranslationException("Error: Don't know how to deal with 1234:ABCD1234 (segment:address) operands.");
}
return finalResult;
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class ImulTranslator method generateImul.
private TranslationResult generateImul(final ITranslationEnvironment environment, final long offset, final String operand1, final String operand2, final OperandSize size1, final OperandSize size2) {
// The three steps to simulate signed multiplication using unsigned multiplication:
// 1. Get the absolute values of the two operands
// 2. Multiply the absolute values
// 3. Change the sign of the result if the two operands had different signs.
final long baseOffset = offset;
long newOffset = baseOffset;
final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
final Pair<String, String> abs1 = Helpers.generateAbs(environment, newOffset, operand1, size1, instructions);
newOffset = baseOffset + instructions.size();
final Pair<String, String> abs2 = Helpers.generateAbs(environment, newOffset, operand2, size2, instructions);
newOffset = baseOffset + instructions.size();
final String lowerHalfMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
final String multResult = environment.getNextVariableString();
final String xoredSigns = environment.getNextVariableString();
final String toggleMask = environment.getNextVariableString();
final String decResult = environment.getNextVariableString();
final String realResult = environment.getNextVariableString();
final String maskedLowerHalf = environment.getNextVariableString();
// Multiply the two operands
instructions.add(ReilHelpers.createMul(newOffset, size1, abs1.second(), size2, abs2.second(), resultSize, multResult));
// Find out if the two operands had different signs and adjust the result accordingly
instructions.add(ReilHelpers.createXor(newOffset + 1, size1, abs1.first(), size2, abs2.first(), size1, xoredSigns));
instructions.add(ReilHelpers.createSub(newOffset + 2, size1, "0", size1, xoredSigns, resultSize, toggleMask));
instructions.add(ReilHelpers.createSub(newOffset + 3, resultSize, multResult, size1, xoredSigns, resultSize, decResult));
instructions.add(ReilHelpers.createXor(newOffset + 4, resultSize, toggleMask, resultSize, decResult, resultSize, realResult));
// Extract lower half of the result
instructions.add(ReilHelpers.createAnd(newOffset + 5, resultSize, realResult, size1, lowerHalfMask, size1, maskedLowerHalf));
// Extend the sign of the lower half of the result
final TranslationResult foo = Helpers.extendSign(environment, newOffset + 6, maskedLowerHalf, size1, resultSize);
instructions.addAll(foo.getInstructions());
newOffset = newOffset + 6 + foo.getInstructions().size();
final String cmpResult = environment.getNextVariableString();
final String resultsEqual = environment.getNextVariableString();
// Compare result to sign extension of lower half
instructions.add(ReilHelpers.createSub(newOffset, resultSize, realResult, resultSize, foo.getRegister(), resultSize, cmpResult));
instructions.add(ReilHelpers.createBisz(newOffset + 1, resultSize, cmpResult, OperandSize.BYTE, resultsEqual));
// Set the flags according to the result
instructions.add(ReilHelpers.createBisz(newOffset + 2, OperandSize.BYTE, resultsEqual, OperandSize.BYTE, Helpers.CARRY_FLAG));
instructions.add(ReilHelpers.createBisz(newOffset + 3, OperandSize.BYTE, resultsEqual, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
instructions.add(ReilHelpers.createUndef(newOffset + 4, OperandSize.BYTE, Helpers.ZERO_FLAG));
instructions.add(ReilHelpers.createUndef(newOffset + 5, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
instructions.add(ReilHelpers.createUndef(newOffset + 6, OperandSize.BYTE, Helpers.PARITY_FLAG));
return new TranslationResult(realResult, resultSize, TranslationResultType.REGISTER, null, instructions, offset);
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class TranslatorPPC method translate.
/**
* Translates an x86 instruction to REIL code
*
* @param environment A valid translation environment
* @param instruction The x86 instruction to translate
*
* @return The list of REIL instruction the x86 instruction was translated to
*
* @throws InternalTranslationException An internal translation error occured
* @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();
if (translators.containsKey(mnemonic)) {
final IInstructionTranslator translator = translators.get(mnemonic);
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 if (mnemonic == null) {
return new ArrayList<ReilInstruction>();
} else {
System.out.println("Unknown mnemonic: " + mnemonic);
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 OperandGraphTest method testOneNode.
@Test
public void testOneNode() {
final Collection<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
instructions.add(ReilHelpers.createAdd(0, OperandSize.DWORD, "eax", OperandSize.DWORD, "123", OperandSize.QWORD, "t0"));
instructions.add(ReilHelpers.createAnd(1, OperandSize.QWORD, "t0", OperandSize.DWORD, String.valueOf(0xFFFFFFFF), OperandSize.DWORD, "t1"));
final ReilBlock block1 = new ReilBlock(instructions);
final List<ReilBlock> blocks = Lists.<ReilBlock>newArrayList(block1);
final ReilGraph rg = new ReilGraph(blocks, new ArrayList<ReilEdge>());
final OperandGraph g = OperandGraph.create(rg);
assertEquals(6, g.nodeCount());
assertEquals(5, g.edgeCount());
}
use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.
the class AddTransformerTest method testAddConstants.
@Test
public void testAddConstants() {
final ReilInstruction instruction = ReilHelpers.createAdd(0x100, OperandSize.DWORD, "2", OperandSize.DWORD, "4", OperandSize.QWORD, "t0");
final ValueTrackerElement state = new ValueTrackerElement();
final ValueTrackerElement result = AddTransformer.transform(instruction, state);
assertTrue(result.getState("t0") instanceof Literal);
assertEquals(6, ((Literal) result.getState("t0")).getValue().longValue());
}
Aggregations