use of com.google.security.zynamics.reil.translators.InternalTranslationException 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.InternalTranslationException in project binnavi by google.
the class Helpers method writeBack.
/**
* Writes a value back into a target.
*
* @param environment A valid translation environment.
* @param offset The next unused REIL offset; the new code is written there.
* @param targetOperand The target operand where the value is written to
* @param sourceValue The value that's written
* @param size
* @param address Target address (in case the type is MEMORY_ACCESS) or null (in case it's not)
* @param targetType Target type (Either REGISTER or MEMORY_ACCESS)
* @param instructions The new code is added to this list of instructions
*
* @throws IllegalArgumentException Thrown if invalid arguments were passed to the function.
* @throws InternalTranslationException Thrown if invalid argument combinations were passed to the
* function.
*/
public static void writeBack(final ITranslationEnvironment environment, final long offset, final IOperandTree targetOperand, final String sourceValue, final OperandSize size, final String address, final TranslationResultType targetType, final List<ReilInstruction> instructions) throws IllegalArgumentException, InternalTranslationException {
Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
Preconditions.checkNotNull(targetOperand, "Error: Argument targetOperand can't be null");
Preconditions.checkNotNull(sourceValue, "Error: Argument sourceValue can't be null");
Preconditions.checkNotNull(size, "Error: Argument size can't be null");
Preconditions.checkNotNull(targetType, "Error: Argument targetType can't be null");
Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
// TODO: Exact meaning of parameter size
final OperandSize archSize = environment.getArchitectureSize();
if (targetType == TranslationResultType.REGISTER) {
if (address != null) {
throw new InternalTranslationException("Error: Invalid combination of parameters");
}
// The target is a register. Either write the value directly or mask it into the target
final String target = getLeafValue(targetOperand.getRootNode());
if ((size == archSize) || isSegment(target)) {
instructions.add(ReilHelpers.createStr(offset, size, sourceValue, size, target));
} else {
moveAndMask(environment, offset, size, sourceValue, target, instructions);
}
} else if (targetType == TranslationResultType.MEMORY_ACCESS) {
// The target is a memory address. Store the value there.
instructions.add(ReilHelpers.createStm(offset, size, sourceValue, archSize, address));
} else {
throw new InternalTranslationException("Error: Invalid target type");
}
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException 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.InternalTranslationException in project binnavi by google.
the class DecTranslator method translate.
/**
* Translates an DEC instruction to REIL code.
*
* @param environment A valid translation environment
* @param instruction The DEC 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 DEC instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "dec");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not an dec instruction (invalid number of operand)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
// DEC instructions have exactly one operand.
final IOperandTree operand = instruction.getOperands().get(0);
// Load the operand.
final TranslationResult result = Helpers.translateOperand(environment, offset, operand, true);
instructions.addAll(result.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final String loadedRegister = result.getRegister();
final OperandSize registerSize = result.getSize();
final OperandSize nextSize = TranslationHelpers.getNextSize(registerSize);
final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(registerSize));
final String shiftMsbLsbMask = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(registerSize));
final String truncMask = String.valueOf(TranslationHelpers.getAllBitsMask(registerSize));
final String maskedMsb = environment.getNextVariableString();
final String decResult = environment.getNextVariableString();
final String maskedMsbResult = environment.getNextVariableString();
final String maskedMsbNeg = environment.getNextVariableString();
final String tempOF = environment.getNextVariableString();
final String truncatedResult = environment.getNextVariableString();
// Isolate the MSB of the operand
instructions.add(ReilHelpers.createAnd(offset, registerSize, loadedRegister, registerSize, msbMask, registerSize, maskedMsb));
// Decrement the value
instructions.add(ReilHelpers.createSub(offset + 1, registerSize, loadedRegister, registerSize, "1", nextSize, decResult));
// Isolate the MSB of the result and put it into the Sign Flag
instructions.add(ReilHelpers.createAnd(offset + 2, nextSize, decResult, registerSize, msbMask, registerSize, maskedMsbResult));
instructions.add(ReilHelpers.createBsh(offset + 3, registerSize, maskedMsbResult, registerSize, shiftMsbLsbMask, OperandSize.BYTE, Helpers.SIGN_FLAG));
// The OF is only set if the result of the dec operation is 0x7F
// OF = ( MSB(old) == 1 ) AND ( MSB(new) == 0 )
// OF = MSB(old) AND NOT(MSB(new))
instructions.add(ReilHelpers.createXor(offset + 4, registerSize, maskedMsbResult, registerSize, msbMask, registerSize, maskedMsbNeg));
instructions.add(ReilHelpers.createAnd(offset + 5, registerSize, maskedMsb, registerSize, maskedMsbNeg, registerSize, tempOF));
// Write the result into the Overflow Flag
instructions.add(ReilHelpers.createBsh(offset + 6, registerSize, tempOF, registerSize, shiftMsbLsbMask, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
// Truncate the result to fit into the target
instructions.add(ReilHelpers.createAnd(offset + 7, nextSize, decResult, registerSize, truncMask, registerSize, truncatedResult));
// Update the Zero Flag
instructions.add(ReilHelpers.createBisz(offset + 8, registerSize, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
// Write the truncated result back into the operand
Helpers.writeBack(environment, offset + 9, operand, truncatedResult, registerSize, result.getAddress(), result.getType(), instructions);
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class BtrTranslator method translate.
/**
* Translates a BTR instruction to REIL code.
*
* @param environment A valid translation environment
* @param instruction The BTR 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 a BTR instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "btr");
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a btr instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final IOperandTree targetOperand = instruction.getOperands().get(0);
final IOperandTree sourceOperand = instruction.getOperands().get(1);
// Load the target operand.
final TranslationResult targetResult = Helpers.translateOperand(environment, offset, targetOperand, true);
instructions.addAll(targetResult.getInstructions());
offset = baseOffset + instructions.size();
// Load the source operand.
final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, true);
instructions.addAll(sourceResult.getInstructions());
offset = baseOffset + instructions.size();
final String negatedIndex = environment.getNextVariableString();
// final String truncatedNegatedIndex = environment.getNextVariableString();
final String shiftedTarget = environment.getNextVariableString();
// TODO: Due to a bug in the REIL BSH specification we can not truncate the result
// of the subtraction here. See the tests for an example of what goes wrong.
instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, "0", sourceResult.getSize(), sourceResult.getRegister(), OperandSize.WORD, negatedIndex));
// instructions.add(ReilHelpers.createAnd(offset++, OperandSize.WORD, negatedIndex,
// OperandSize.BYTE, "255", OperandSize.BYTE, truncatedNegatedIndex));
instructions.add(ReilHelpers.createBsh(offset++, targetResult.getSize(), targetResult.getRegister(), OperandSize.BYTE, negatedIndex, targetResult.getSize(), shiftedTarget));
instructions.add(ReilHelpers.createAnd(offset++, targetResult.getSize(), shiftedTarget, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
// Clear the bit in the destination
final String shiftedIndex = environment.getNextVariableString();
final String negatedShiftedIndex = environment.getNextVariableString();
final String andedResult = environment.getNextVariableString();
// Shift the mask to the right bit
instructions.add(ReilHelpers.createBsh(offset++, OperandSize.BYTE, "1", sourceResult.getSize(), sourceResult.getRegister(), targetResult.getSize(), shiftedIndex));
// Toggle the bits of the shift mask
instructions.add(ReilHelpers.createXor(offset++, targetResult.getSize(), shiftedIndex, targetResult.getSize(), String.valueOf(TranslationHelpers.getAllBitsMask(targetResult.getSize())), targetResult.getSize(), negatedShiftedIndex));
// Preserve all original bits except for the one at the shift position which is cleared
instructions.add(ReilHelpers.createAnd(offset++, targetResult.getSize(), targetResult.getRegister(), targetResult.getSize(), negatedShiftedIndex, targetResult.getSize(), andedResult));
Helpers.writeBack(environment, offset++, targetOperand, andedResult, targetResult.getSize(), targetResult.getAddress(), targetResult.getType(), instructions);
}
Aggregations