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 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.InternalTranslationException in project binnavi by google.
the class LahfTranslator method translate.
/**
* Translates a LAHF instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The LAHF 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 LAHF instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "lahf");
if (instruction.getOperands().size() != 0) {
throw new InternalTranslationException("Error: Argument instruction is not a lahf instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
final OperandSize archSize = environment.getArchitectureSize();
final String clearedEax = environment.getNextVariableString();
final String shiftedSf = environment.getNextVariableString();
final String clearedEaxSf = environment.getNextVariableString();
final String shiftedZf = environment.getNextVariableString();
final String clearedEaxZf = environment.getNextVariableString();
final String shiftedAf = environment.getNextVariableString();
final String clearedEaxAf = environment.getNextVariableString();
final String shiftedPf = environment.getNextVariableString();
final String clearedEaxPf = environment.getNextVariableString();
final String shiftedCf = environment.getNextVariableString();
final String clearedEaxCf = environment.getNextVariableString();
// Clear AH
instructions.add(ReilHelpers.createAnd(baseOffset, archSize, "eax", archSize, "4294902015", archSize, clearedEax));
// Move the SF into the highest bit of AH
instructions.add(ReilHelpers.createBsh(baseOffset + 1, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, "15", OperandSize.WORD, shiftedSf));
instructions.add(ReilHelpers.createOr(baseOffset + 2, archSize, clearedEax, OperandSize.WORD, shiftedSf, archSize, clearedEaxSf));
// Move the ZF into the 6th bit of AH
instructions.add(ReilHelpers.createBsh(baseOffset + 3, OperandSize.BYTE, Helpers.ZERO_FLAG, OperandSize.BYTE, "14", OperandSize.WORD, shiftedZf));
instructions.add(ReilHelpers.createOr(baseOffset + 4, archSize, clearedEaxSf, OperandSize.WORD, shiftedZf, archSize, clearedEaxZf));
// Move the AF into the 4th bit of AH
instructions.add(ReilHelpers.createBsh(baseOffset + 5, OperandSize.BYTE, Helpers.AUXILIARY_FLAG, OperandSize.BYTE, "12", OperandSize.WORD, shiftedAf));
instructions.add(ReilHelpers.createOr(baseOffset + 6, archSize, clearedEaxZf, OperandSize.WORD, shiftedAf, archSize, clearedEaxAf));
// Move the PF into the 2nd bit of AH
instructions.add(ReilHelpers.createBsh(baseOffset + 7, OperandSize.BYTE, Helpers.PARITY_FLAG, OperandSize.BYTE, "10", OperandSize.WORD, shiftedPf));
instructions.add(ReilHelpers.createOr(baseOffset + 8, archSize, clearedEaxAf, OperandSize.WORD, shiftedPf, archSize, clearedEaxPf));
// Move the CF into the LSB of AH
instructions.add(ReilHelpers.createBsh(baseOffset + 9, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, "8", OperandSize.WORD, shiftedCf));
instructions.add(ReilHelpers.createOr(baseOffset + 10, archSize, clearedEaxPf, OperandSize.WORD, shiftedCf, archSize, clearedEaxCf));
// The 1st bit of AH ( = 8th bit of EAX) is set to 1
instructions.add(ReilHelpers.createOr(baseOffset + 11, archSize, clearedEaxCf, archSize, "512", archSize, "eax"));
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class LeaTranslator method translate.
// TODO: Check the code again
/**
* Translates a LEA instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The LEA 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 LAHF instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "lea");
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a lea instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final List<? extends IOperandTree> operands = instruction.getOperands();
final IOperandTree targetOperand = operands.get(0);
final IOperandTree sourceOperand = operands.get(1);
// The first operand must be a register.
final String destination = Helpers.getLeafValue(targetOperand.getRootNode());
final OperandSize size = Helpers.getOperandSize(targetOperand);
// Load the operand.
final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, false);
String sourceRegister = sourceResult.getRegister() != null ? sourceResult.getRegister() : sourceResult.getAddress();
sourceResult.getType();
final List<ReilInstruction> sourceInstructions = sourceResult.getInstructions();
// The source operand must always be loaded.
instructions.addAll(sourceInstructions);
// Adjust the offset of the next REIL instruction
offset = baseOffset + instructions.size();
if (size == OperandSize.WORD) {
// Destination size is a sub-register
final OperandType operandType = OperandType.getOperandType(sourceRegister);
if (operandType == OperandType.INTEGER_LITERAL) {
// Integer literals can be truncated directly.
sourceRegister = String.valueOf(Long.valueOf(sourceRegister) & 0xFFFF);
} else if (operandType == OperandType.REGISTER) {
// Registers must be truncated later
// => Add an AND instruction that truncates.
final String truncatedValue = environment.getNextVariableString();
final OperandSize registerSize = sourceInstructions.size() == 0 ? Helpers.getRegisterSize(sourceRegister) : environment.getArchitectureSize();
// Add the truncating instruction
instructions.add(ReilHelpers.createAnd(offset, registerSize, sourceRegister, OperandSize.WORD, "65535", OperandSize.WORD, truncatedValue));
offset++;
sourceRegister = truncatedValue;
} else {
// Shouldn't be possible.
assert false;
}
// Write the loaded value into the destination register.
Helpers.writeBack(environment, offset, targetOperand, sourceRegister, size, null, TranslationResultType.REGISTER, instructions);
} else if (size == OperandSize.DWORD) {
// Destination is a DWORD register
// Handling DWORD values is easier. Just add a STR
// instruction that writes the loaded source value
// into the destination register.
instructions.add(ReilHelpers.createStr(offset, size, sourceRegister, size, destination));
// instructions.addAll(Helpers.writeBack(environment, offset, targetOperand, sourceRegister,
// size, null, TranslationResultType.REGISTER));
} else {
assert false;
}
}
Aggregations