use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.
the class JccTranslator method translate.
/**
* Translates a conditional jump instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The conditional jump 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 conditional jump instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
Preconditions.checkNotNull(instruction, "Error: Argument instruction can't be null");
Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
Preconditions.checkArgument(instruction.getOperands().size() == 1, "Error: Argument instruction is not a conditional jump instruction (invalid number of operands)");
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
// JCC 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());
final String jumpTarget = result.getRegister();
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final Pair<OperandSize, String> condition = conditionGenerator.generate(environment, offset, instructions);
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
instructions.add(ReilHelpers.createJcc(offset, condition.first(), condition.second(), environment.getArchitectureSize(), jumpTarget));
}
use of com.google.security.zynamics.zylib.disassembly.IOperandTree 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.zylib.disassembly.IOperandTree in project binnavi by google.
the class ShrdTranslator method translate.
/**
* Translates a SHRD instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The SHRD 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 SHRD instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "shrd");
if (instruction.getOperands().size() != 3) {
throw new InternalTranslationException("Error: Argument instruction is not a shrd instruction (invalid number of operands)");
}
// Distinct behaviour:
// 1. Shift value is 0
// 2. Shift value is 1
// 3. Shift value is too large
// 4. Shift value has right size
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final List<? extends IOperandTree> operands = instruction.getOperands();
// Load target value
final TranslationResult firstResult = Helpers.translateOperand(environment, offset, operands.get(0), true);
instructions.addAll(firstResult.getInstructions());
offset = baseOffset + instructions.size();
final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
instructions.addAll(secondResult.getInstructions());
offset = baseOffset + instructions.size();
// Load shift value
final TranslationResult thirdResult = Helpers.translateOperand(environment, offset, operands.get(2), true);
instructions.addAll(thirdResult.getInstructions());
final String truncatedShiftValue = environment.getNextVariableString();
final String truncatedShiftValueZero = environment.getNextVariableString();
offset = baseOffset + instructions.size();
// Test whether the shift value is zero (leads to no operation)
instructions.add(ReilHelpers.createAnd(offset++, thirdResult.getSize(), thirdResult.getRegister(), OperandSize.BYTE, "31", OperandSize.BYTE, truncatedShiftValue));
instructions.add(ReilHelpers.createBisz(offset++, OperandSize.BYTE, truncatedShiftValue, OperandSize.BYTE, truncatedShiftValueZero));
final int jumpInsertIndex1 = (int) (offset - baseOffset);
offset++;
// Placeholder for jcc
// instructions.add(ReilHelpers.createJcc(offset++, OperandSize.BYTE, truncatedShiftValue,
// OperandSize.ADDRESS, endAddress));
// If a shift happens, AF is undefined
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.AUXILIARY_FLAG));
// Test whether the shift value is too large (leads to an undefined result)
final String sizeSubtractionResult = environment.getNextVariableString();
final String sizeMaskingResult = environment.getNextVariableString();
instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, String.valueOf(firstResult.getSize().getBitSize()), OperandSize.BYTE, truncatedShiftValue, OperandSize.WORD, sizeSubtractionResult));
instructions.add(ReilHelpers.createAnd(offset++, OperandSize.WORD, sizeSubtractionResult, OperandSize.WORD, String.valueOf(0x8000), OperandSize.WORD, sizeMaskingResult));
final int jumpInsertIndex2 = (int) (offset - baseOffset);
offset++;
// Placeholder for createJcc(offset++, OperandSize.WORD, sizeMaskingResult, OperandSize.ADDRESS,
// largeValueHandler));
// From here on, we know that the shift value is valid
final String shiftedSecondInput = environment.getNextVariableString();
final String shiftMask = String.valueOf(firstResult.getSize().getBitSize());
final OperandSize combinedSize = TranslationHelpers.getNextSize(firstResult.getSize());
final OperandSize extendedSize = TranslationHelpers.getNextSize(combinedSize);
final String combinedSource = environment.getNextVariableString();
final String shiftedResult = environment.getNextVariableString();
// Combine the operands into one operand
instructions.add(ReilHelpers.createBsh(offset++, secondResult.getSize(), secondResult.getRegister(), secondResult.getSize(), shiftMask, combinedSize, shiftedSecondInput));
instructions.add(ReilHelpers.createOr(offset++, combinedSize, shiftedSecondInput, firstResult.getSize(), firstResult.getRegister(), combinedSize, combinedSource));
// Negate the shift-mask
final String negatedShiftMask = environment.getNextVariableString();
final String truncatedNegatedShiftMask = environment.getNextVariableString();
instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, "0", OperandSize.BYTE, truncatedShiftValue, OperandSize.WORD, negatedShiftMask));
instructions.add(ReilHelpers.createAnd(offset++, OperandSize.WORD, negatedShiftMask, OperandSize.BYTE, "255", OperandSize.BYTE, truncatedNegatedShiftMask));
// Less-1 shift to determine the CF
final String incShiftMaskNeg = environment.getNextVariableString();
final String decResult = environment.getNextVariableString();
instructions.add(ReilHelpers.createAdd(offset++, OperandSize.BYTE, truncatedNegatedShiftMask, OperandSize.BYTE, "1", OperandSize.WORD, incShiftMaskNeg));
instructions.add(ReilHelpers.createBsh(offset++, combinedSize, combinedSource, OperandSize.WORD, incShiftMaskNeg, combinedSize, decResult));
instructions.add(ReilHelpers.createAnd(offset++, combinedSize, decResult, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
// Do the shift
instructions.add(ReilHelpers.createBsh(offset++, combinedSize, combinedSource, OperandSize.BYTE, truncatedNegatedShiftMask, extendedSize, shiftedResult));
// Isolate the result
final String isolationMask = getAllButMask(combinedSize, firstResult.getSize());
final String isolationResult = environment.getNextVariableString();
final String shiftedIsolationResult = environment.getNextVariableString();
instructions.add(ReilHelpers.createAnd(offset++, extendedSize, shiftedResult, combinedSize, isolationMask, combinedSize, isolationResult));
instructions.add(ReilHelpers.createBsh(offset++, combinedSize, isolationResult, OperandSize.BYTE, "-" + shiftMask, firstResult.getSize(), shiftedIsolationResult));
// Set the flags (TODO: Parity)
instructions.add(ReilHelpers.createBisz(offset++, firstResult.getSize(), shiftedIsolationResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
Helpers.generateSignFlagCode(environment, offset, shiftedIsolationResult, firstResult.getSize(), instructions);
offset = baseOffset + instructions.size() + 2;
/** JCC placeholder **/
// final String tempCf = environment.getNextVariableString();
// Store the original input value in a temp register for OF calculation
final String tempInput = environment.getNextVariableString();
instructions.add(ReilHelpers.createStr(offset++, firstResult.getSize(), firstResult.getRegister(), firstResult.getSize(), tempInput));
// Write the result back
Helpers.writeBack(environment, offset, operands.get(0), shiftedIsolationResult, firstResult.getSize(), firstResult.getAddress(), firstResult.getType(), instructions);
offset = baseOffset + instructions.size() + 2;
/** JCC placeholder **/
// Test whether the shift value is 1
final String shiftValueOne = environment.getNextVariableString();
instructions.add(ReilHelpers.createSub(offset++, OperandSize.BYTE, truncatedShiftValue, OperandSize.BYTE, "1", OperandSize.WORD, shiftValueOne));
final int jumpInsertIndex3 = (int) (offset - baseOffset);
offset++;
// Placeholder for createJcc(offset++, OperandSize.WORD, shiftValueOne, OperandSize.ADDRESS,
// notOneHandler));
// The shift-value was 1 => Calculate the OF
final String xoredMsb = environment.getNextVariableString();
final String maskedMsb = environment.getNextVariableString();
final long msbMask = TranslationHelpers.getMsbMask(firstResult.getSize());
final long msbShift = TranslationHelpers.getShiftMsbLsbMask(firstResult.getSize());
instructions.add(ReilHelpers.createXor(offset++, firstResult.getSize(), tempInput, firstResult.getSize(), shiftedIsolationResult, firstResult.getSize(), xoredMsb));
instructions.add(ReilHelpers.createAnd(offset++, firstResult.getSize(), xoredMsb, OperandSize.BYTE, String.valueOf(msbMask), OperandSize.BYTE, maskedMsb));
instructions.add(ReilHelpers.createBsh(offset++, firstResult.getSize(), maskedMsb, OperandSize.BYTE, String.valueOf(msbShift), OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
final int jumpInsertIndex4 = (int) (offset - baseOffset);
offset++;
// Placeholder for createJcc(offset++, OperandSize.BYTE, "1", OperandSize.ADDRESS, endAddress));
// Handle mod-value too large
final String largeValueHandler = String.format("%d.%d", instruction.getAddress().toLong(), offset - baseOffset);
final IOperandTree inputOperand = operands.get(0);
if (firstResult.getType() == TranslationResultType.REGISTER) {
final String operand = Helpers.getLeafValue(inputOperand.getRootNode());
final String undefRegister = Helpers.getOperandSize(inputOperand) == environment.getArchitectureSize() ? operand : Helpers.getParentRegister(operand);
instructions.add(ReilHelpers.createUndef(offset++, environment.getArchitectureSize(), undefRegister));
}
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.CARRY_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.SIGN_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.ZERO_FLAG));
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.PARITY_FLAG));
// Handle shift value > 1 || shift value too large
final String notOneHandler = String.format("%d.%d", instruction.getAddress().toLong(), offset - baseOffset);
instructions.add(ReilHelpers.createUndef(offset++, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
// The End
final String jmpGoalEnd = String.format("%d.%d", instruction.getAddress().toLong(), offset - baseOffset);
instructions.add(ReilHelpers.createNop(offset++));
instructions.add(jumpInsertIndex1, ReilHelpers.createJcc(baseOffset + jumpInsertIndex1, OperandSize.BYTE, truncatedShiftValueZero, OperandSize.ADDRESS, jmpGoalEnd));
instructions.add(jumpInsertIndex2, ReilHelpers.createJcc(baseOffset + jumpInsertIndex2, OperandSize.WORD, sizeMaskingResult, OperandSize.ADDRESS, largeValueHandler));
instructions.add(jumpInsertIndex3, ReilHelpers.createJcc(baseOffset + jumpInsertIndex3, OperandSize.WORD, shiftValueOne, OperandSize.ADDRESS, notOneHandler));
instructions.add(jumpInsertIndex4, ReilHelpers.createJcc(baseOffset + jumpInsertIndex4, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalEnd));
}
use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.
the class SubTranslator method translate.
/**
* Translates a SUB instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The SUB 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 SUB instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "sub");
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a sub instruction (invalid number of operands)");
}
final long baseOffset = instruction.getAddress().toLong() * 0x100;
long offset = baseOffset;
final List<? extends IOperandTree> operands = instruction.getOperands();
final IOperandTree operand1 = operands.get(0);
final IOperandTree operand2 = operands.get(1);
// Load source operand.
final TranslationResult operand2Result = Helpers.translateOperand(environment, offset, operand2, true);
instructions.addAll(operand2Result.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
// Load destination operand.
final TranslationResult operand1Result = Helpers.translateOperand(environment, offset, operand1, true);
instructions.addAll(operand1Result.getInstructions());
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
final OperandSize size = operand1Result.getSize();
final String register1 = operand1Result.getRegister();
final String register2 = operand2Result.getRegister();
// Subtract the two values
final String subResultValue = Helpers.generateSub(environment, offset, size, register1, register2, instructions);
// Adjust the offset of the next REIL instruction.
offset = baseOffset + instructions.size();
Helpers.writeParityFlag(environment, offset, size, subResultValue, instructions);
offset = baseOffset + instructions.size();
// Write the result of the value back into the target operand
Helpers.writeBack(environment, offset, operand1, subResultValue, size, operand1Result.getAddress(), operand1Result.getType(), instructions);
}
use of com.google.security.zynamics.zylib.disassembly.IOperandTree in project binnavi by google.
the class TestTranslator method translate.
/**
* Translates a TEST instruction to REIL code.
*
* @param environment A valid translation environment.
* @param instruction The TEST 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 TEST instruction
*/
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "test");
if (instruction.getOperands().size() != 2) {
throw new InternalTranslationException("Error: Argument instruction is not a test 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 size = targetResult.getSize();
final String sourceRegister = sourceResult.getRegister();
final String targetRegister = targetResult.getRegister();
Helpers.generateAnd(environment, offset, size, sourceRegister, targetRegister, instructions);
}
Aggregations