use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class CallTranslator method translate.
/**
* Translates a CALL instruction to REIL code.
*
* @param environment A valid translation environment
* @param instruction The CALL 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 CALL instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "call");
if (instruction.getOperands().size() != 1) {
throw new InternalTranslationException("Error: Argument instruction is not a call instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final OperandSize archSize = environment.getArchitectureSize();
final OperandSize nextSize = TranslationHelpers.getNextSize(archSize);
final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(archSize));
final String tempEsp = environment.getNextVariableString();
final String returnAddress = String.valueOf(instruction.getAddress().toLong() + instruction.getLength());
// Move the stack, make sure to truncate potential overflows
instructions.add(ReilHelpers.createSub(offset, archSize, "esp", archSize, "4", nextSize, tempEsp));
instructions.add(ReilHelpers.createAnd(offset + 1, nextSize, tempEsp, archSize, truncateMask, archSize, "esp"));
// Push the return address onto the stack
instructions.add(ReilHelpers.createStm(offset + 2, archSize, returnAddress, archSize, "esp"));
// CALL instructions have exactly one operand
final IOperandTree targetOperand = instruction.getOperands().get(0);
// Load the operand.
final TranslationResult result = Helpers.translateOperand(environment, offset + 3, targetOperand, true);
instructions.addAll(result.getInstructions());
// Adjust the offset of the next REIL instruction
offset = baseOffset + instructions.size();
// Add the unconditional jump to the target
instructions.add(ReilHelpers.createJcc(offset, OperandSize.DWORD, "1", result.getSize(), result.getRegister(), "isCall", "true"));
}
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 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;
}
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class BsfBsrTranslatorCommon method translateBsfOrBsr.
public static void translateBsfOrBsr(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions, boolean translateBsf) throws InternalTranslationException {
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a bsr/bsf 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 source operand.
final TranslationResult sourceResult = Helpers.translateOperand(environment, offset, sourceOperand, true);
instructions.addAll(sourceResult.getInstructions());
offset = baseOffset + instructions.size();
final OperandSize sourceSize = sourceResult.getSize();
final String targetRegister = Helpers.getLeafValue(targetOperand.getRootNode());
final String labelNotZero = String.format("%d.%d", instruction.getAddress().toLong(), instructions.size() + 4);
final String labelLoopStart = String.format("%d.%d", instruction.getAddress().toLong(), instructions.size() + 7);
final String labelLoopEnd = String.format("%d.%d", instruction.getAddress().toLong(), instructions.size() + 12);
final String labelEnd = String.format("%d.%d", instruction.getAddress().toLong(), instructions.size() + 13);
instructions.add(ReilHelpers.createJcc(offset++, sourceSize, sourceResult.getRegister(), OperandSize.ADDRESS, labelNotZero));
// Input value is 0
instructions.add(ReilHelpers.createStr(offset++, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.ZERO_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, environment.getArchitectureSize(), targetRegister));
instructions.add(ReilHelpers.createJcc(offset++, OperandSize.BYTE, "1", OperandSize.ADDRESS, labelEnd));
// Input value is not 0
final String counter = environment.getNextVariableString();
final String shiftedValue = environment.getNextVariableString();
final String isolatedMsb = environment.getNextVariableString();
instructions.add(ReilHelpers.createStr(offset++, OperandSize.BYTE, "0", OperandSize.BYTE, Helpers.ZERO_FLAG));
instructions.add(ReilHelpers.createStr(offset++, sourceSize, sourceResult.getRegister(), sourceSize, shiftedValue));
if (translateBsf) {
instructions.add(ReilHelpers.createStr(offset++, OperandSize.BYTE, "0", OperandSize.BYTE, counter));
instructions.add(ReilHelpers.createAnd(offset++, sourceSize, shiftedValue, sourceSize, "1", sourceSize, isolatedMsb));
} else {
instructions.add(ReilHelpers.createStr(offset++, OperandSize.BYTE, "31", OperandSize.BYTE, counter));
// Generate the instruction for a BSR, e.g. bitmask is 0x80000000.
instructions.add(ReilHelpers.createAnd(offset++, sourceSize, shiftedValue, sourceSize, String.valueOf(TranslationHelpers.getMsbMask(sourceSize)), sourceSize, isolatedMsb));
}
instructions.add(ReilHelpers.createJcc(offset++, sourceSize, isolatedMsb, OperandSize.ADDRESS, labelLoopEnd));
if (translateBsf) {
instructions.add(ReilHelpers.createAdd(offset++, OperandSize.BYTE, counter, OperandSize.BYTE, "1", OperandSize.BYTE, counter));
instructions.add(ReilHelpers.createBsh(offset++, sourceSize, shiftedValue, sourceSize, "-1", sourceSize, shiftedValue));
} else {
instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, counter, OperandSize.BYTE, "1", OperandSize.BYTE, counter));
instructions.add(ReilHelpers.createBsh(offset++, sourceSize, shiftedValue, sourceSize, "1", sourceSize, shiftedValue));
}
instructions.add(ReilHelpers.createJcc(offset++, OperandSize.BYTE, "1", OperandSize.ADDRESS, labelLoopStart));
instructions.add(ReilHelpers.createStr(offset++, OperandSize.DWORD, counter, OperandSize.DWORD, targetRegister));
instructions.add(ReilHelpers.createNop(offset++));
}
use of com.google.security.zynamics.reil.translators.InternalTranslationException in project binnavi by google.
the class BswapTranslator method translate.
/**
* Translates a BSWAP instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The BSWAP 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 BSWAP instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "bswap");
if (instruction.getOperands().size() != 1) {
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 operand = instruction.getOperands().get(0).getRootNode().getChildren().get(0).getValue();
final String masked1st = environment.getNextVariableString();
final String masked2nd = environment.getNextVariableString();
final String masked3rd = environment.getNextVariableString();
final String masked4th = environment.getNextVariableString();
final String shifted1st = environment.getNextVariableString();
final String shifted2nd = environment.getNextVariableString();
final String shifted3rd = environment.getNextVariableString();
final String shifted4th = environment.getNextVariableString();
final String combined1 = environment.getNextVariableString();
final String combined2 = environment.getNextVariableString();
instructions.add(ReilHelpers.createAnd(baseOffset + 0, archSize, operand, archSize, "255", archSize, masked1st));
instructions.add(ReilHelpers.createAnd(baseOffset + 1, archSize, operand, archSize, "65280", archSize, masked2nd));
instructions.add(ReilHelpers.createAnd(baseOffset + 2, archSize, operand, archSize, "16711680", archSize, masked3rd));
instructions.add(ReilHelpers.createAnd(baseOffset + 3, archSize, operand, archSize, "4278190080", archSize, masked4th));
instructions.add(ReilHelpers.createBsh(baseOffset + 4, archSize, masked1st, archSize, "24", archSize, shifted1st));
instructions.add(ReilHelpers.createBsh(baseOffset + 5, archSize, masked2nd, archSize, "8", archSize, shifted2nd));
instructions.add(ReilHelpers.createBsh(baseOffset + 6, archSize, masked3rd, archSize, "-8", archSize, shifted3rd));
instructions.add(ReilHelpers.createBsh(baseOffset + 7, archSize, masked4th, archSize, "-24", archSize, shifted4th));
instructions.add(ReilHelpers.createOr(baseOffset + 8, archSize, shifted1st, archSize, shifted2nd, archSize, combined1));
instructions.add(ReilHelpers.createOr(baseOffset + 9, archSize, shifted3rd, archSize, shifted4th, archSize, combined2));
instructions.add(ReilHelpers.createOr(baseOffset + 10, archSize, combined1, archSize, combined2, archSize, operand));
}
Aggregations