Search in sources :

Example 51 with InternalTranslationException

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"));
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 52 with InternalTranslationException

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));
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 53 with InternalTranslationException

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;
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) OperandType(com.google.security.zynamics.reil.OperandType) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 54 with InternalTranslationException

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++));
}
Also used : IOperandTree(com.google.security.zynamics.zylib.disassembly.IOperandTree) InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) TranslationResult(com.google.security.zynamics.reil.translators.TranslationResult) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 55 with InternalTranslationException

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));
}
Also used : InternalTranslationException(com.google.security.zynamics.reil.translators.InternalTranslationException) OperandSize(com.google.security.zynamics.reil.OperandSize)

Aggregations

InternalTranslationException (com.google.security.zynamics.reil.translators.InternalTranslationException)62 OperandSize (com.google.security.zynamics.reil.OperandSize)46 TranslationResult (com.google.security.zynamics.reil.translators.TranslationResult)42 IOperandTree (com.google.security.zynamics.zylib.disassembly.IOperandTree)35 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)6 ArrayList (java.util.ArrayList)5 TranslationResultType (com.google.security.zynamics.reil.translators.TranslationResultType)3 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)2 OperandType (com.google.security.zynamics.reil.OperandType)2 IOperandTreeNode (com.google.security.zynamics.zylib.disassembly.IOperandTreeNode)2 BigInteger (java.math.BigInteger)2 MockCodeNodeData (com.google.security.zynamics.binnavi.Database.MockClasses.MockCodeNodeData)1 MockCodeNodeProvider (com.google.security.zynamics.binnavi.Database.MockClasses.MockCodeNodeProvider)1 MockSqlProvider (com.google.security.zynamics.binnavi.Database.MockClasses.MockSqlProvider)1 CCodeNodeParser (com.google.security.zynamics.binnavi.Database.NodeParser.CCodeNodeParser)1 MaybeNullException (com.google.security.zynamics.binnavi.Exceptions.MaybeNullException)1 CCodeNode (com.google.security.zynamics.binnavi.disassembly.CCodeNode)1 INaviCodeNode (com.google.security.zynamics.binnavi.disassembly.INaviCodeNode)1 MockFunction (com.google.security.zynamics.binnavi.disassembly.MockFunction)1 MockModule (com.google.security.zynamics.binnavi.disassembly.Modules.MockModule)1