use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.
the class DivTranslator method translate.
/**
* Translates a DIV instruction to REIL code.
*
* @param environment A valid translation environment
* @param instruction The DIV 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 DIV instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "div");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not a div instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final List<? extends IOperandTree> operands = instruction.getOperands();
final IOperandTree divisorOperand = operands.get(0);
final OperandSize size = Helpers.getOperandSize(divisorOperand);
// Load the dividend
final TranslationResult resultDividend = Helpers.loadFirstDivOperand(environment, offset, size);
instructions.addAll(resultDividend.getInstructions());
// Adjust the offset of the next REIL instruction
offset = baseOffset + instructions.size();
final String dividend = resultDividend.getRegister();
// Load the divisor
final TranslationResult resultDivisor = Helpers.translateOperand(environment, offset, divisorOperand, true);
instructions.addAll(resultDivisor.getInstructions());
// Adjust the offset of the next REIL instruction
offset = baseOffset + instructions.size();
final String divisor = resultDivisor.getRegister();
final String divResult = environment.getNextVariableString();
final String modResult = environment.getNextVariableString();
// Perform divison and modulo operation
instructions.add(ReilHelpers.createDiv(offset++, size, dividend, size, divisor, size, divResult));
instructions.add(ReilHelpers.createMod(offset++, size, dividend, size, divisor, size, modResult));
// Write the result back and set the flags
instructions.addAll(Helpers.writeDivResult(environment, offset++, divResult, modResult, size));
offset = baseOffset + instructions.size();
// Undefine flags
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.CARRY_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.PARITY_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.SIGN_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.ZERO_FLAG));
}
use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.
the class Helpers method extractRegister.
/**
* Extracts a subregister (like AX, AL, AH) from a parent register (like EAX)
*
* @param environment A valid translation environment
* @param offset The next unused REIL offset where the new REIL code can be placed
* @param subRegister The subregister that should be extracted
*
* @return The result of the translation
*
* @throws InternalTranslationException Thrown if an internal problem occurs
*/
private static TranslationResult extractRegister(final ITranslationEnvironment environment, final long offset, final String subRegister) throws InternalTranslationException {
final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
final String parentRegister = getParentRegister(subRegister);
final OperandSize archSize = environment.getArchitectureSize();
if (isHigher8BitRegister(subRegister)) {
// The sub-register is not at the low end of the parent
// register. Mask + shift is necessary here.
final String maskResult = environment.getNextVariableString();
final String shiftResult = environment.getNextVariableString();
// Add the mask + shift instructions
instructions.add(ReilHelpers.createAnd(offset, archSize, parentRegister, OperandSize.WORD, "65280", OperandSize.WORD, maskResult));
instructions.add(ReilHelpers.createBsh(offset + 1, OperandSize.WORD, maskResult, OperandSize.WORD, "-8", OperandSize.BYTE, shiftResult));
return new TranslationResult(shiftResult, OperandSize.BYTE, TranslationResultType.REGISTER, null, instructions, offset);
} else {
// The sub-register is already at the low end of the parent register.
// Masking is enough.
final OperandSize subRegisterSize = getRegisterSize(subRegister);
final String mask = String.valueOf(TranslationHelpers.getAllBitsMask(subRegisterSize));
final String result = environment.getNextVariableString();
// Add the mask instruction
instructions.add(ReilHelpers.createAnd(offset, archSize, parentRegister, subRegisterSize, mask, subRegisterSize, result));
return new TranslationResult(result, subRegisterSize, TranslationResultType.REGISTER, null, instructions, offset);
}
}
use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.
the class Helpers method processLeafNode.
private static TranslationResult processLeafNode(final ITranslationEnvironment environment, final long baseOffset, final IOperandTreeNode expression, OperandSize size, boolean loadOperand) throws InternalTranslationException {
// All leaves are either registers or integer literals. They are translated
// into "STR leaf, , nextVariable" instructions. Optimizations are handled
// during the translation of their parent nodes.
// Get the type of the leaf.
final String value = expression.getValue();
final OperandType operandType = OperandType.getOperandType(value);
TranslationResultType nodeType = null;
switch(operandType) {
case REGISTER:
nodeType = TranslationResultType.REGISTER;
break;
case INTEGER_LITERAL:
nodeType = TranslationResultType.LITERAL;
break;
default:
throw new InternalTranslationException("Error: Leaf has invalid type");
}
final List<ReilInstruction> instructions = new ArrayList<>();
final String nextVariableString = environment.getNextVariableString();
if ((operandType == OperandType.INTEGER_LITERAL) || !needsExtraction(environment, value)) {
if (loadOperand) {
instructions.add(ReilHelpers.createStr(baseOffset, size, value, size, nextVariableString));
return new TranslationResult(nextVariableString, size, nodeType, null, instructions, baseOffset);
} else {
// str t3, --, ebx
return new TranslationResult(value, size, nodeType, null, instructions, baseOffset);
}
} else {
// Mask smaller operands
return extractRegister(environment, baseOffset, value);
}
}
use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.
the class IdivTranslator method translate.
/**
* Translates a IDIV instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The IDIV 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 IDIV instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "idiv");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not a idiv instruction (invalid number of operands)");
}
final List<? extends IOperandTree> operands = instruction.getOperands();
final IOperandTree divisorOperand = operands.get(0);
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final OperandSize size = Helpers.getOperandSize(operands.get(0));
// Load the dividend
final TranslationResult resultDividend = Helpers.loadFirstDivOperand(environment, offset, size);
instructions.addAll(resultDividend.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final String dividend = resultDividend.getRegister();
// Load the divisor
final TranslationResult resultDivisor = Helpers.translateOperand(environment, offset, divisorOperand, true);
instructions.addAll(resultDivisor.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final String divisor = resultDivisor.getRegister();
// Here's how to express signed division using unsigned division:
// 1. Get the absolute value of both operands
// 2. Divide unsigned
// 3. Change the sign of the result if the signs of the operands were different
// Get the absolute value of the two factors for unsigned multiplication
final Pair<String, String> absDividend = Helpers.generateAbs(environment, offset, dividend, size, instructions);
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final Pair<String, String> absDivisor = Helpers.generateAbs(environment, offset, divisor, size, instructions);
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
// Perform division and modulo operation
final String divResult = environment.getNextVariableString();
final String modResult = environment.getNextVariableString();
instructions.add(ReilHelpers.createDiv(offset, size, absDividend.second(), size, absDivisor.second(), size, divResult));
instructions.add(ReilHelpers.createMod(offset + 1, size, absDividend.second(), size, absDivisor.second(), size, modResult));
// Find out if the two operands had different signs and create a sign mask
final String xoredSigns = environment.getNextVariableString();
final String toggleMask = environment.getNextVariableString();
instructions.add(ReilHelpers.createXor(offset + 2, size, absDividend.first(), size, absDividend.second(), size, xoredSigns));
instructions.add(ReilHelpers.createSub(offset + 3, size, "0", size, xoredSigns, size, toggleMask));
// Adjust the div result
final String decDivResult = environment.getNextVariableString();
final String realDivResult = environment.getNextVariableString();
instructions.add(ReilHelpers.createSub(offset + 4, size, divResult, size, xoredSigns, size, decDivResult));
instructions.add(ReilHelpers.createXor(offset + 5, size, decDivResult, size, toggleMask, size, realDivResult));
// Adjust the mod result (the sign of the mod result is the sign of the first operand)
final String modToggleMask = environment.getNextVariableString();
final String decModResult = environment.getNextVariableString();
final String realModResult = environment.getNextVariableString();
instructions.add(ReilHelpers.createSub(offset + 6, size, "0", size, absDividend.first(), size, modToggleMask));
instructions.add(ReilHelpers.createSub(offset + 7, size, modResult, size, absDividend.first(), size, decModResult));
instructions.add(ReilHelpers.createXor(offset + 8, size, decModResult, size, modToggleMask, size, realModResult));
// Write the result back and set the flags
instructions.addAll(Helpers.writeDivResult(environment, offset + 9, realDivResult, realModResult, size));
}
use of com.google.security.zynamics.reil.translators.TranslationResult in project binnavi by google.
the class ImulTranslator method translate_2.
private void translate_2(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
final List<? extends IOperandTree> operands = instruction.getOperands();
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
// Load source operand.
final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
instructions.addAll(firstResult.getInstructions());
offset = baseOffset + instructions.size();
// Load second operand.
final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
instructions.addAll(secondResult.getInstructions());
offset = baseOffset + instructions.size();
// IMUL instructions with 2 or 3 operands must have an output register
final OperandSize resultSize = OperandSize.sizeStringToValue(operands.get(0).getRootNode().getValue());
final String resultRegister = operands.get(0).getRootNode().getChildren().get(0).getValue();
generateImul3(environment, offset, resultSize, resultRegister, firstResult.getSize(), firstResult.getRegister(), secondResult.getSize(), secondResult.getRegister(), instructions);
}
Aggregations