Search in sources :

Example 6 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.

the class ShlTranslator method translate.

// TODO(timkornau): Check this code again
/**
   * Translates a SHL instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The SHL 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 SHL 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");
    if (!instruction.getMnemonic().equals("shl") && !instruction.getMnemonic().equals("sal")) {
        throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (wrong mnemonic)");
    }
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a shl instruction (invalid number of operands)");
    }
    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();
    // Load destination operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
    instructions.addAll(secondResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = baseOffset + instructions.size();
    final OperandSize size1 = firstResult.getSize();
    final OperandSize size2 = secondResult.getSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
    final String operand1 = firstResult.getRegister();
    final String operand2 = secondResult.getRegister();
    final String shiftMsbLsbValue = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(size1));
    final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(size1));
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
    final String modValue = String.valueOf(size1.getBitSize());
    final String carryMask = String.valueOf(Helpers.getCarryMask(size1));
    final String shiftCarryValue = String.valueOf(-size1.getBitSize());
    final String shiftMask = environment.getNextVariableString();
    final String shiftMaskZero = environment.getNextVariableString();
    final String shiftMaskLessOne = environment.getNextVariableString();
    final String shiftMaskOne = environment.getNextVariableString();
    final String result = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    final String msbResult = environment.getNextVariableString();
    final String carryResult = environment.getNextVariableString();
    final int before = instructions.size();
    final List<ReilInstruction> writebackInstructions = new ArrayList<>();
    // Write the result of the SHR operation back into the target register
    Helpers.writeBack(environment, offset + 16, operands.get(0), truncatedResult, size1, firstResult.getAddress(), firstResult.getType(), writebackInstructions);
    // Make sure to shift less than the size1 of the register
    instructions.add(ReilHelpers.createMod(offset, size2, operand2, size2, modValue, size2, shiftMask));
    // Find out if the shift mask is 0 and negate the result
    instructions.add(ReilHelpers.createBisz(offset + 1, size2, shiftMask, OperandSize.BYTE, shiftMaskZero));
    // Find out if the shift mask is 1
    instructions.add(ReilHelpers.createSub(offset + 2, size2, "1", size2, shiftMask, size2, shiftMaskLessOne));
    instructions.add(ReilHelpers.createBisz(offset + 3, size2, shiftMaskLessOne, OperandSize.BYTE, shiftMaskOne));
    // Perform the shift
    instructions.add(ReilHelpers.createBsh(offset + 4, size1, operand1, size2, shiftMask, resultSize, result));
    // Truncate the result to the correct size1
    instructions.add(ReilHelpers.createAnd(offset + 5, resultSize, result, size1, truncateMask, size1, truncatedResult));
    // Don't change the flags if the shift value was zero (jump to writeBack).
    final String jmpGoalWriteBack = String.format("%d.%d", instruction.getAddress().toLong(), before + 16);
    instructions.add(ReilHelpers.createJcc(offset + 6, OperandSize.BYTE, shiftMaskZero, OperandSize.ADDRESS, jmpGoalWriteBack));
    // Extract the MSB of the result and shift it into the SF
    instructions.add(ReilHelpers.createAnd(offset + 7, resultSize, result, resultSize, msbMask, resultSize, msbResult));
    instructions.add(ReilHelpers.createBsh(offset + 8, resultSize, msbResult, resultSize, shiftMsbLsbValue, OperandSize.BYTE, Helpers.SIGN_FLAG));
    // Set the CF to the MSB of the result
    instructions.add(ReilHelpers.createAnd(offset + 9, resultSize, result, resultSize, carryMask, resultSize, carryResult));
    instructions.add(ReilHelpers.createBsh(offset + 10, resultSize, carryResult, resultSize, shiftCarryValue, OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Set the ZF
    instructions.add(ReilHelpers.createBisz(offset + 11, size1, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
    // The OF needs to be set to a different value if the shift-mask was 1
    final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), before + 15);
    instructions.add(ReilHelpers.createJcc(offset + 12, OperandSize.BYTE, shiftMaskOne, OperandSize.ADDRESS, jmpGoal2));
    // Set the OF to undefined if the shift-mask was positive but not 1
    instructions.add(ReilHelpers.createUndef(offset + 13, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Jump to writeBack.
    instructions.add(ReilHelpers.createJcc(offset + 14, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalWriteBack));
    // Set the OF if the shift-mask was 1.
    instructions.add(ReilHelpers.createXor(offset + 15, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Write back to the target register.
    instructions.addAll(writebackInstructions);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 7 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.

the class ShrTranslator method translate.

// TODO(timkornau): Check this code again
/**
   * Translates a SHR instruction to REIL code.
   *
   * @param environment A valid translation environment.
   * @param instruction The SHR 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 SHR instruction
   */
@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "shr");
    if (instruction.getOperands().size() != 2) {
        throw new InternalTranslationException("Error: Argument instruction is not a shr instruction (invalid number of operands)");
    }
    final long reilOffsetBase = instruction.getAddress().toLong() * 0x100;
    long offset = reilOffsetBase;
    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 = reilOffsetBase + instructions.size();
    // Load destination operand.
    final TranslationResult secondResult = Helpers.translateOperand(environment, offset, operands.get(1), true);
    instructions.addAll(secondResult.getInstructions());
    // Adjust the offset of the next REIL instruction.
    offset = reilOffsetBase + instructions.size();
    final OperandSize size1 = firstResult.getSize();
    final OperandSize size2 = secondResult.getSize();
    final OperandSize resultSize = TranslationHelpers.getNextSize(size1);
    final String operand1 = firstResult.getRegister();
    final String operand2 = secondResult.getRegister();
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size1));
    final String modValue = String.valueOf(size1.getBitSize());
    final String shiftMask = environment.getNextVariableString();
    final String shiftMaskZero = environment.getNextVariableString();
    final String shiftMaskLessOne = environment.getNextVariableString();
    final String shiftMaskOne = environment.getNextVariableString();
    final String shiftMaskNeg = environment.getNextVariableString();
    final String result = environment.getNextVariableString();
    final String truncatedResult = environment.getNextVariableString();
    final String incShiftMaskNeg = environment.getNextVariableString();
    final String decResult = environment.getNextVariableString();
    final int before = instructions.size();
    final List<ReilInstruction> writebackInstructions = new ArrayList<ReilInstruction>();
    // Write the result of the SHR operation back into the target register
    Helpers.writeBack(environment, offset + 17, operands.get(0), truncatedResult, size1, firstResult.getAddress(), firstResult.getType(), writebackInstructions);
    // Make sure to shift less than the size1 of the register
    instructions.add(ReilHelpers.createMod(offset, size2, operand2, size2, modValue, size2, shiftMask));
    // Find out if the shift mask is 0 and negate the result
    instructions.add(ReilHelpers.createBisz(offset + 1, size2, shiftMask, OperandSize.BYTE, shiftMaskZero));
    // Find out if the shift mask is 1
    instructions.add(ReilHelpers.createSub(offset + 2, size2, "1", size2, shiftMask, size2, shiftMaskLessOne));
    instructions.add(ReilHelpers.createBisz(offset + 3, size2, shiftMaskLessOne, OperandSize.BYTE, shiftMaskOne));
    // Negate the shift-mask => BSH to the right
    instructions.add(ReilHelpers.createSub(offset + 4, size2, "0", size2, shiftMask, size2, shiftMaskNeg));
    // Perform the shift
    instructions.add(ReilHelpers.createBsh(offset + 5, size1, operand1, size2, shiftMaskNeg, resultSize, result));
    // Truncate the result to the correct size1
    instructions.add(ReilHelpers.createAnd(offset + 6, resultSize, result, size1, truncateMask, size1, truncatedResult));
    // Don't change the flags if the shift value was zero (jump to writeBack).
    final String jmpGoalWriteBack = String.format("%d.%d", instruction.getAddress().toLong(), before + 17);
    instructions.add(ReilHelpers.createJcc(offset + 7, OperandSize.BYTE, shiftMaskZero, OperandSize.ADDRESS, jmpGoalWriteBack));
    // The SF is always 0
    instructions.add(ReilHelpers.createStr(offset + 8, OperandSize.BYTE, "0", OperandSize.BYTE, Helpers.SIGN_FLAG));
    // Set the CF to the last MSB shifted out of the register
    // Perform another shift, this time by one position less and take the LSB
    // This is only safe if the mask is not 0
    instructions.add(ReilHelpers.createAdd(offset + 9, size2, shiftMaskNeg, size2, "1", size2, incShiftMaskNeg));
    instructions.add(ReilHelpers.createBsh(offset + 10, size1, operand1, size2, incShiftMaskNeg, size1, decResult));
    instructions.add(ReilHelpers.createAnd(offset + 11, size1, decResult, OperandSize.BYTE, "1", OperandSize.BYTE, Helpers.CARRY_FLAG));
    // Set the ZF
    instructions.add(ReilHelpers.createBisz(offset + 12, size1, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG));
    // The OF needs to be set to a different value if the shift-mask was 1
    final String jmpGoal2 = String.format("%d.%d", instruction.getAddress().toLong(), before + 16);
    instructions.add(ReilHelpers.createJcc(offset + 13, OperandSize.BYTE, shiftMaskOne, OperandSize.ADDRESS, jmpGoal2));
    // Set the OF to undefined if the shift-mask was positive but not 1
    instructions.add(ReilHelpers.createUndef(offset + 14, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Jump to writeBack.
    instructions.add(ReilHelpers.createJcc(offset + 15, OperandSize.BYTE, "1", OperandSize.ADDRESS, jmpGoalWriteBack));
    // Set the OF if the shift-mask was 1
    instructions.add(ReilHelpers.createXor(offset + 16, OperandSize.BYTE, Helpers.SIGN_FLAG, OperandSize.BYTE, Helpers.CARRY_FLAG, OperandSize.BYTE, Helpers.OVERFLOW_FLAG));
    // Write back to the target register.
    instructions.addAll(writebackInstructions);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 8 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.

the class TranslatorX86 method translate.

/**
   * Translates an x86 instruction to REIL code
   *
   * @param environment A valid translation environment
   * @param instruction The x86 instruction to translate
   *
   * @return The list of REIL instruction the x86 instruction was translated to
   *
   * @throws InternalTranslationException An internal translation error occured
   * @throws IllegalArgumentException Any of the arguments passed to the function are invalid
   *
   */
@Override
public List<ReilInstruction> translate(final ITranslationEnvironment environment, final InstructionType instruction, final List<ITranslationExtension<InstructionType>> extensions) throws InternalTranslationException {
    Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
    Preconditions.checkNotNull(instruction, "Error: Argument instruction can't be null");
    final String mnemonic = instruction.getMnemonic();
    if (translators.containsKey(mnemonic)) {
        final IInstructionTranslator translator = translators.get(mnemonic);
        final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
        translator.translate(environment, instruction, instructions);
        for (final ITranslationExtension<InstructionType> extension : extensions) {
            extension.postProcess(environment, instruction, instructions);
        }
        return instructions;
    } else if (mnemonic == null) {
        return new ArrayList<ReilInstruction>();
    } else {
        System.out.println("Unknown mnemonic: " + mnemonic);
        return Lists.newArrayList(ReilHelpers.createUnknown(ReilHelpers.toReilAddress(instruction.getAddress()).toLong()));
    }
}
Also used : IInstructionTranslator(com.google.security.zynamics.reil.translators.IInstructionTranslator) ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList)

Example 9 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.

the class RepneTranslator method translate.

@Override
public void translate(final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException {
    final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong();
    final long offset = baseOffset;
    final OperandSize archSize = environment.getArchitectureSize();
    final String invertedEcx = environment.getNextVariableString();
    final List<ReilInstruction> innerInstructions = new ArrayList<ReilInstruction>();
    translator.generate(environment, ReilHelpers.toReilAddress(instruction.getAddress()).toLong() + 2, operandSize, innerInstructions);
    final String firstInstruction = String.format("%d.0", instruction.getAddress().toLong());
    final String jmpGoal = String.format("%d.%d", instruction.getAddress().toLong(), innerInstructions.size() + 6);
    instructions.add(ReilHelpers.createBisz(offset, archSize, "ecx", OperandSize.BYTE, invertedEcx));
    instructions.add(ReilHelpers.createJcc(offset + 1, OperandSize.BYTE, invertedEcx, OperandSize.ADDRESS, jmpGoal));
    instructions.addAll(innerInstructions);
    final String decrementedEcx = environment.getNextVariableString();
    final String invertedZF = environment.getNextVariableString();
    final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(OperandSize.DWORD));
    instructions.add(ReilHelpers.createSub(baseOffset + instructions.size(), OperandSize.DWORD, "ecx", OperandSize.DWORD, "1", OperandSize.QWORD, decrementedEcx));
    instructions.add(ReilHelpers.createAnd(baseOffset + instructions.size(), OperandSize.QWORD, decrementedEcx, OperandSize.DWORD, truncateMask, OperandSize.DWORD, "ecx"));
    instructions.add(ReilHelpers.createBisz(baseOffset + instructions.size(), OperandSize.DWORD, "ZF", OperandSize.BYTE, invertedZF));
    instructions.add(ReilHelpers.createJcc(baseOffset + instructions.size(), OperandSize.DWORD, invertedZF, OperandSize.ADDRESS, firstInstruction));
    instructions.add(ReilHelpers.createNop(baseOffset + instructions.size()));
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ArrayList(java.util.ArrayList) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 10 with ReilInstruction

use of com.google.security.zynamics.reil.ReilInstruction in project binnavi by google.

the class CReadsDescription method visit.

@Override
public Collection<CSpecialInstruction> visit(final ReilFunction reilCode, final ListMultimap<IAddress, INaviInstruction> instructionMap) {
    final Collection<CSpecialInstruction> instructions = new ArrayList<CSpecialInstruction>();
    final Set<INaviInstruction> calls = new HashSet<INaviInstruction>();
    for (final ReilBlock block : reilCode.getGraph()) {
        for (final ReilInstruction reilInstruction : block) {
            if (ReilHelpers.isFunctionCall(reilInstruction)) {
                calls.addAll(instructionMap.get(ReilHelpers.toNativeAddress(reilInstruction.getAddress())));
            }
        }
    }
    for (final ReilBlock block : reilCode.getGraph()) {
        for (final ReilInstruction reilInstruction : block) {
            if (reilInstruction.getMnemonic().equals(ReilHelpers.OPCODE_LDM)) {
                final List<INaviInstruction> firstInstructions = instructionMap.get(ReilHelpers.toNativeAddress(reilInstruction.getAddress()));
                if (isAnyCall(firstInstructions, calls)) {
                    continue;
                }
                final List<INaviInstruction> nativeInstructions = instructionMap.get(ReilHelpers.toNativeAddress(reilInstruction.getAddress()));
                for (final INaviInstruction naviInstruction : nativeInstructions) {
                    instructions.add(new CSpecialInstruction(this, naviInstruction));
                }
            }
        }
    }
    return instructions;
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) INaviInstruction(com.google.security.zynamics.binnavi.disassembly.INaviInstruction)

Aggregations

ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)144 Test (org.junit.Test)102 TreeSet (java.util.TreeSet)73 ArrayList (java.util.ArrayList)35 IInstruction (com.google.security.zynamics.zylib.disassembly.IInstruction)18 OperandSize (com.google.security.zynamics.reil.OperandSize)16 ReilBlock (com.google.security.zynamics.reil.ReilBlock)16 MockInstruction (com.google.security.zynamics.zylib.disassembly.MockInstruction)16 MockOperandTree (com.google.security.zynamics.zylib.disassembly.MockOperandTree)16 MockOperandTreeNode (com.google.security.zynamics.zylib.disassembly.MockOperandTreeNode)16 ReilEdge (com.google.security.zynamics.reil.ReilEdge)12 HashMap (java.util.HashMap)12 TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)9 IAddress (com.google.security.zynamics.zylib.disassembly.IAddress)7 List (java.util.List)7 ReilGraph (com.google.security.zynamics.reil.ReilGraph)6 InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)6 BigInteger (java.math.BigInteger)6 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)5 ValueTrackerElement (com.google.security.zynamics.reil.algorithms.mono.valuetracking.ValueTrackerElement)5