use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class XorTranslator method translate.
/**
* Translates a XOR instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The XOR 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 XOR instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "xor");
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a xor 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);
// Load source operand.
final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, true);
instructions.addAll(sourceResult.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
// Load destination operand.
final TranslationResult targetResult = Helpers.translateOperand(environment, offset, targetOperand, true);
// Adjust the offset of the next REIL instruction.
instructions.addAll(targetResult.getInstructions());
offset = baseOffset + instructions.size();
final OperandSize size = targetResult.getSize();
final String sourceRegister = sourceResult.getRegister();
final String targetRegister = targetResult.getRegister();
final String xorResult = environment.getNextVariableString();
// Do the XOR operation
instructions.add(ReilHelpers.createXor(offset, size, sourceRegister, size, targetRegister, size, xorResult));
// Set the flags according to the result of the XOR operation
Helpers.generateBinaryOperationFlags(environment, offset + 1, xorResult, size, instructions);
offset = baseOffset + instructions.size();
// Write the result of the XOR operation into the target register
Helpers.writeBack(environment, offset, targetOperand, xorResult, size, targetResult.getAddress(), targetResult.getType(), instructions);
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class MulTranslator method translate.
/**
* Translates a MUL instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The MUL 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 MUL instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "mul");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not a mul instruction (invalid number of operand)");
}
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();
final String operand1 = firstResult.getRegister();
final String operand2 = "eax";
final OperandSize size1 = firstResult.getSize();
final OperandSize size2 = environment.getArchitectureSize();
final OperandSize resultSize = TranslationHelpers.getNextSize(size2);
final String result = environment.getNextVariableString();
final String upperHalf = environment.getNextVariableString();
final String upperHalfZero = environment.getNextVariableString();
final String maskUpper = String.valueOf(TranslationHelpers.getAllButMask(resultSize, size1));
// Multiply the operands
instructions.add(ReilHelpers.createMul(offset, size1, operand1, size2, operand2, resultSize, result));
// Clear the lower half of the result
instructions.add(ReilHelpers.createAnd(offset + 1, resultSize, result, resultSize, maskUpper, resultSize, upperHalf));
// Check whether upper half is zero
instructions.add(ReilHelpers.createBisz(offset + 2, resultSize, upperHalf, OperandSize.BYTE, upperHalfZero));
// CF = Upper half is zero
instructions.add(ReilHelpers.createBisz(offset + 3, resultSize, upperHalfZero, OperandSize.BYTE, Helpers.CARRY_FLAG));
// OF = Upper half is zero
instructions.add(ReilHelpers.createBisz(offset + 4, resultSize, upperHalfZero, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
// SF, ZF, AF and PF are undefined
instructions.add(ReilHelpers.createUndef(offset + 5, OperandSize.BYTE, Helpers.SIGN_FLAG));
instructions.add(ReilHelpers.createUndef(offset + 6, OperandSize.BYTE, Helpers.ZERO_FLAG));
instructions.add(ReilHelpers.createUndef(offset + 7, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
instructions.add(ReilHelpers.createUndef(offset + 8, OperandSize.BYTE, Helpers.PARITY_FLAG));
instructions.addAll(Helpers.writeMulResult(environment, offset + 9, result, size1));
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class NotTranslator method translate.
/**
* Translates an NOT instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The NOT 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 NOT instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "not");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not an not instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
// NOT 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 operandRegister = result.getRegister();
final OperandSize size = result.getSize();
final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size));
final String xorResult = environment.getNextVariableString();
// Flip all bits in the operand
instructions.add(ReilHelpers.createXor(offset, size, operandRegister, size, truncateMask, size, xorResult));
// Write the flipped value back to the operand
Helpers.writeBack(environment, offset + 1, operand, xorResult, size, result.getAddress(), result.getType(), instructions);
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class PushTranslator method translate.
/**
* Translates a PUSH instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The PUSH 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 PUSH instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "push");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not a push instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
// PUSH 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();
// A push with an 8-bit immediate is treated like a 32-bit push.
final OperandSize resultSize = (result.getSize() == OperandSize.BYTE) ? OperandSize.DWORD : result.getSize();
final String loadedValue = result.getRegister();
final String tempRegister;
if (result.getInstructions().isEmpty() && loadedValue.equalsIgnoreCase("esp")) {
// push esp must be handled separately
tempRegister = environment.getNextVariableString();
instructions.add(ReilHelpers.createStr(offset++, resultSize, loadedValue, resultSize, tempRegister));
} else {
tempRegister = loadedValue;
}
Helpers.generatePush(environment, offset, tempRegister, resultSize, instructions);
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class RclTranslator method translate.
// TODO:(timkornau@google.com) Check this code again
/**
* Translates a RCL instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The RCL 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 RCL instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "rcl");
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a rcl 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);
// Load source operand.
final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, true);
instructions.addAll(sourceResult.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
// Load target operand.
final TranslationResult targetResult = Helpers.translateOperand(environment, offset, targetOperand, true);
instructions.addAll(targetResult.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final OperandSize sourceSize = sourceResult.getSize();
final OperandSize targetSize = targetResult.getSize();
final OperandSize resultSize = TranslationHelpers.getNextSize(targetSize);
final String sourceRegister = sourceResult.getRegister();
final String targetRegister = targetResult.getRegister();
final String os = String.valueOf(targetSize.getBitSize());
final String rotateMask = environment.getNextVariableString();
final String rotateMaskZero = environment.getNextVariableString();
final String rotateMaskLessOne = environment.getNextVariableString();
final String rotateMaskOne = environment.getNextVariableString();
final String shiftedCf = environment.getNextVariableString();
final String realOp1 = environment.getNextVariableString();
final String shrValue = environment.getNextVariableString();
final String shredResult = environment.getNextVariableString();
final String shledResult = environment.getNextVariableString();
final String result = environment.getNextVariableString();
final String truncatedResult = environment.getNextVariableString();
final String msbResult = environment.getNextVariableString();
final String tempOf = environment.getNextVariableString();
final String tempOfLsb = environment.getNextVariableString();
final String carryMask = String.valueOf(Helpers.getCarryMask(targetSize));
final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(targetSize));
final String maskSize = String.valueOf(TranslationHelpers.getAllBitsMask(targetSize));
// TODO: + 1 ?
final String modVal = String.valueOf(targetSize.getBitSize() + 1);
final String shiftMsbLsb = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(targetSize));
final int linesBefore = instructions.size();
// Make sure to rotate less than the size of the register
instructions.add(ReilHelpers.createMod(offset, sourceSize, sourceRegister, sourceSize, os, OperandSize.BYTE, rotateMask));
// Find out if the rotate mask is 0
instructions.add(ReilHelpers.createBisz(offset + 1, OperandSize.BYTE, rotateMask, OperandSize.BYTE, rotateMaskZero));
// Find out if the rotate mask is 1
instructions.add(ReilHelpers.createSub(offset + 2, OperandSize.BYTE, rotateMask, OperandSize.BYTE, "1", OperandSize.BYTE, rotateMaskLessOne));
instructions.add(ReilHelpers.createBisz(offset + 3, OperandSize.BYTE, rotateMaskLessOne, OperandSize.BYTE, rotateMaskOne));
// Rotating through the carry flag is like rotating through a 33 bit register
// For rotating leftwards, the CF must be added at the MSB of the 32 bit register
instructions.add(ReilHelpers.createBsh(offset + 4, OperandSize.BYTE, Helpers.CARRY_FLAG, sourceSize, os, resultSize, shiftedCf));
instructions.add(ReilHelpers.createOr(offset + 5, targetSize, targetRegister, resultSize, shiftedCf, resultSize, realOp1));
// Perform the rotate
// y = ( x << n ) | ( x >> ( ( regsize + 1 ) - n ) )
instructions.add(ReilHelpers.createBsh(offset + 6, resultSize, realOp1, OperandSize.BYTE, rotateMask, resultSize, shledResult));
instructions.add(ReilHelpers.createAdd(offset + 7, OperandSize.BYTE, "-" + modVal, OperandSize.BYTE, rotateMask, OperandSize.BYTE, shrValue));
instructions.add(ReilHelpers.createBsh(offset + 8, resultSize, realOp1, OperandSize.BYTE, shrValue, resultSize, shredResult));
instructions.add(ReilHelpers.createOr(offset + 9, resultSize, shledResult, resultSize, shredResult, resultSize, result));
// Truncate the result
instructions.add(ReilHelpers.createAnd(offset + 10, resultSize, result, targetSize, maskSize, targetSize, truncatedResult));
// Don't change the flags if the rotate value was zero
final String jmpGoal = String.format("%d.%d", instruction.getAddress().toLong(), linesBefore + 20);
instructions.add(ReilHelpers.createJcc(offset + 11, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal));
// Set the CF to the MSB of the untruncated result
instructions.add(ReilHelpers.createAnd(offset + 12, resultSize, result, resultSize, carryMask, resultSize, msbResult));
instructions.add(ReilHelpers.createBsh(offset + 13, resultSize, msbResult, resultSize, "-" + os, OperandSize.BYTE, Helpers.CARRY_FLAG));
// The OF needs to be set to a different value if the rotate-mask was 1
final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), linesBefore + 17);
instructions.add(ReilHelpers.createJcc(offset + 14, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal2));
// Set the OF to undefined if the rotate-mask was positive but not 1
instructions.add(ReilHelpers.createUndef(offset + 15, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
// Jump to the end
final String jmpGoal3 = String.format("%d.%d", instruction.getAddress().toLong(), linesBefore + 20);
instructions.add(ReilHelpers.createJcc(offset + 16, OperandSize.BYTE, rotateMaskZero, OperandSize.ADDRESS, jmpGoal3));
// OF = MSB(DEST) XOR CF
instructions.add(ReilHelpers.createAnd(offset + 17, sourceSize, truncatedResult, sourceSize, msbMask, sourceSize, tempOf));
instructions.add(ReilHelpers.createBsh(offset + 18, sourceSize, tempOf, sourceSize, shiftMsbLsb, OperandSize.BYTE, tempOfLsb));
instructions.add(ReilHelpers.createBsh(offset + 19, OperandSize.BYTE, tempOfLsb, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG));
Helpers.writeBack(environment, offset + 20, targetOperand, truncatedResult, targetResult.getSize(), targetResult.getAddress(), targetResult.getType(), instructions);
}
Aggregations