@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "beqlr"); final IOperandTreeNode BIOperand = instruction.getOperands().get(0).getRootNode().getChildren().get(0); String suffix = ""; if (instruction.getMnemonic().endsWith("+")) { suffix = "+"; } if (instruction.getMnemonic().endsWith("-")) { suffix = "-"; } BranchGenerator.generate( instruction.getAddress().toLong() * 0x100, environment, instruction, instructions, "beqlr" + suffix, String.valueOf((Helpers.getCRRegisterIndex(BIOperand.getValue()) * 4) + 2), Helpers.LINK_REGISTER, false, false, false, false, true, false); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "sh"); final String rt = instruction.getOperands().get(0).getRootNode().getChildren().get(0).getValue(); final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong(); long offset = baseOffset; final String address = SignExtendGenerator.extendAndAdd( offset, environment, instruction.getOperands().get(1), instructions); offset = baseOffset + instructions.size(); final OperandSize dw = OperandSize.DWORD; final OperandSize wd = OperandSize.WORD; final String isolatedHalfword = environment.getNextVariableString(); instructions.add( ReilHelpers.createAnd(offset++, dw, rt, wd, String.valueOf(0xFFFFL), wd, isolatedHalfword)); instructions.add(ReilHelpers.createStm(offset++, wd, isolatedHalfword, dw, address)); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "bnel"); final List<? extends IOperandTree> operands = instruction.getOperands(); final String rs = operands.get(0).getRootNode().getChildren().get(0).getValue(); final String rt = operands.get(1).getRootNode().getChildren().get(0).getValue(); final IOperandTreeNode target = operands.get(2).getRootNode().getChildren().get(0); final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong(); long offset = baseOffset; final OperandSize dw = OperandSize.DWORD; final OperandSize qw = OperandSize.QWORD; final String subtractedValue = environment.getNextVariableString(); instructions.add(ReilHelpers.createSub(offset++, dw, rs, dw, rt, qw, subtractedValue)); Helpers.generateDelayBranchLikely(instructions, offset, qw, subtractedValue, dw, target); }
@Override protected void translateCore( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) { final IOperandTreeNode registerOperand1 = instruction.getOperands().get(0).getRootNode().getChildren().get(0); final IOperandTreeNode registerOperand2 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final String targetRegister = (registerOperand1.getValue()); final String sourceRegister = (registerOperand2.getValue()); final OperandSize dw = OperandSize.DWORD; final OperandSize bt = OperandSize.BYTE; long baseOffset = (instruction.getAddress().toLong() * 0x100) + instructions.size(); instructions.add(ReilHelpers.createStr(baseOffset++, dw, sourceRegister, dw, targetRegister)); if (instruction.getMnemonic().endsWith("S")) { /* the assumption is made that we receive an S even though its not there */ // N Flag instructions.add( ReilHelpers.createBsh( baseOffset++, dw, targetRegister, dw, String.valueOf(-31), bt, "N")); // Z Flag instructions.add(ReilHelpers.createBisz(baseOffset++, dw, targetRegister, bt, "Z")); } }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "subfic"); final IOperandTreeNode registerOperand1 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final IOperandTreeNode literalOperand1 = instruction.getOperands().get(2).getRootNode().getChildren().get(0); SubGenerator.generate( instruction.getAddress().toLong() * 0x100, environment, instruction, instructions, "subfic", registerOperand1.getValue(), literalOperand1.getValue(), false, false, true, false); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "bta"); final IOperandTreeNode addressOperand1 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final IOperandTreeNode BIOperand = instruction.getOperands().get(0).getRootNode().getChildren().get(0); BranchGenerator.generate( instruction.getAddress().toLong() * 0x100, environment, instruction, instructions, "bta", BIOperand.getValue(), addressOperand1.getValue(), false, false, false, false, true, false); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "mfsrr0"); final IOperandTreeNode targetRegister = instruction.getOperands().get(0).getRootNode().getChildren().get(0); Long baseOffset = instruction.getAddress().toLong() * 0x100; final OperandSize dw = OperandSize.DWORD; instructions.add( ReilHelpers.createStr(baseOffset++, dw, "SRR0", dw, targetRegister.getValue())); }
@Override protected void translateCore( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) { final IOperandTreeNode sourceOperand = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final String sourceRegister = (sourceOperand.getValue()); final OperandSize bt = OperandSize.BYTE; final OperandSize dw = OperandSize.DWORD; final String tmpZ = environment.getNextVariableString(); final String tmpC = environment.getNextVariableString(); final String tmpV = environment.getNextVariableString(); final String tmpQ = environment.getNextVariableString(); long baseOffset = (instruction.getAddress().toLong() * 0x100) + instructions.size(); instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, String.valueOf(-31), bt, "N")); instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, String.valueOf(-30), bt, tmpZ)); instructions.add( ReilHelpers.createAnd(baseOffset++, bt, tmpZ, bt, String.valueOf(1L), bt, "Z")); instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, String.valueOf(-29), bt, tmpC)); instructions.add( ReilHelpers.createAnd(baseOffset++, bt, tmpC, bt, String.valueOf(1L), bt, "C")); instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, String.valueOf(-28), bt, tmpV)); instructions.add( ReilHelpers.createAnd(baseOffset++, bt, tmpV, bt, String.valueOf(1L), bt, "C")); instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, String.valueOf(-29), bt, tmpQ)); instructions.add( ReilHelpers.createAnd(baseOffset++, bt, tmpQ, bt, String.valueOf(1L), bt, "C")); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "tlti"); final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong(); instructions.add(ReilHelpers.createUnknown(baseOffset)); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "cmpi"); final List<? extends IOperandTree> operands = instruction.getOperands(); final String rx = operands.get(0).getRootNode().getChildren().get(0).getValue(); final String immediate = operands.get(1).getRootNode().getChildren().get(0).getValue(); final OperandSize dw = OperandSize.DWORD; final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong(); final long offset = baseOffset; instructions.add( ReilHelpers.createXor(offset, dw, rx, dw, immediate, dw, Helpers.getTRegister())); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "blel"); Long baseOffset = instruction.getAddress().toLong() * 0x100; final String jumpOperand = environment.getNextVariableString(); final IOperandTreeNode addressOperand1 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final IOperandTreeNode BIOperand = instruction.getOperands().get(0).getRootNode().getChildren().get(0); instructions.add( ReilHelpers.createOr( baseOffset++, OperandSize.BYTE, String.valueOf((Helpers.getCRRegisterIndex(BIOperand.getValue()) * 4) + 2), OperandSize.BYTE, String.valueOf((Helpers.getCRRegisterIndex(BIOperand.getValue()) * 4) + 0), OperandSize.BYTE, jumpOperand)); BranchGenerator.generate( baseOffset, environment, instruction, instructions, "blel", jumpOperand, addressOperand1.getValue(), true, false, false, false, false, false); }
/** * Translates a PUSHFW instruction to REIL code. * * @param environment A valid translation environment. * @param instruction The PUSHFW 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 PUSHFW instruction */ @Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "pushfw"); if (instruction.getOperands().size() != 0) { throw new InternalTranslationException( "Error: Argument instruction is not a pushfw instruction (invalid number of operands)"); } final long baseOffset = instruction.getAddress().toLong() * 0x100; long offset = baseOffset; final String result = Helpers.shiftFlagsIntoValue(environment, offset, OperandSize.WORD, instructions); offset = baseOffset + instructions.size(); Helpers.generatePush(environment, offset, result, OperandSize.WORD, instructions); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "addzeo."); final IOperandTreeNode registerOperand1 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); AddGenerator.generate( instruction.getAddress().toLong() * 0x100, environment, instruction, instructions, "addzeo.", registerOperand1.getValue(), String.valueOf(0x0L), true, true, true, true); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { SignExtendGenerator.generate( instruction.getAddress().toLong() * 0x100, environment, instruction, instructions, "extsb", OperandSize.BYTE, false); }
public static void generate( long baseOffset, final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions, final String mnemonic, final boolean isSimplified, final boolean setCr) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, mnemonic); final IOperandTreeNode registerOperand1 = instruction.getOperands().get(0).getRootNode().getChildren().get(0); final IOperandTreeNode registerOperand2 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final IOperandTreeNode integerOperand1 = instruction.getOperands().get(2).getRootNode().getChildren().get(0); final IOperandTreeNode integerOperand2 = (instruction.getOperands().size() >= 4) ? instruction.getOperands().get(3).getRootNode().getChildren().get(0) : null; final IOperandTreeNode integerOperand3 = (instruction.getOperands().size() == 5) ? instruction.getOperands().get(4).getRootNode().getChildren().get(0) : null; final String targetRegister = registerOperand1.getValue(); final String sourceRegister = registerOperand2.getValue(); String SH = ""; String MB = ""; String ME = ""; final String crTemp = environment.getNextVariableString(); final String rotateVar1 = environment.getNextVariableString(); final String rotateVar2 = environment.getNextVariableString(); final String rotateVar3 = environment.getNextVariableString(); final String rotateVar4 = environment.getNextVariableString(); /** * possible workaround for ida exporter issues with powerpc * * <p>try { int intOp1 = Integer.decode(integerOperand1.getValue()); } * * <p>catch (final NumberFormatException e) { final String [] foo = * integerOperand1.getValue().split(","); int intOp1 = Integer.decode(foo[2]); } */ if (isSimplified) { if (instruction.getMnemonic().equals("extlwi") || instruction.getMnemonic().equals("extlwi.")) { // extlwi rA,rS,n,b (n > 0) equivalent to rlwinm rA,rS,b,0,n - 1 SH = integerOperand2.getValue(); MB = String.valueOf(0L); ME = String.valueOf(Integer.decode(integerOperand1.getValue()) - 1); } else if (instruction.getMnemonic().equals("extrwi") || instruction.getMnemonic().equals("extrwi.")) { // extrwi rA,rS,n,b (n > 0) equivalent to rlwinm rA,rS,b + n,32 - n,31 SH = String.valueOf( Integer.decode(integerOperand2.getValue()) + Integer.decode(integerOperand1.getValue())); MB = String.valueOf(32 - Integer.decode(integerOperand1.getValue())); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("rotlwi") || instruction.getMnemonic().equals("rotlwi.")) { // rotlwi rA,rS,n equivalent to rlwinm rA,rS,n,0,31 SH = integerOperand1.getValue(); MB = String.valueOf(0L); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("rotrwi") || instruction.getMnemonic().equals("rotrwi.")) { // rotrwi rA,rS,n equivalent to rlwinm rA,rS,32 - n,0,31 SH = String.valueOf(32 - Integer.decode(integerOperand1.getValue())); MB = String.valueOf(0L); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("slwi") || instruction.getMnemonic().equals("slwi.")) { // slwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,n,0,31 - n SH = integerOperand1.getValue(); MB = String.valueOf(0L); ME = String.valueOf(31 - Integer.decode(integerOperand1.getValue())); } else if (instruction.getMnemonic().equals("srwi") || instruction.getMnemonic().equals("srwi.")) { // srwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,32 - n,n,31 SH = String.valueOf(32 - Integer.decode(integerOperand1.getValue())); MB = integerOperand1.getValue(); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("clrlwi") || instruction.getMnemonic().equals("clrlwi.")) { // clrlwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,0,n,31 SH = String.valueOf(0L); MB = integerOperand1.getValue(); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("clrrwi") || instruction.getMnemonic().equals("clrrwi.")) { // clrrwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,0,0,31 - n SH = String.valueOf(0L); MB = String.valueOf(0L); ME = String.valueOf(31 - Integer.decode(integerOperand1.getValue())); } else if (instruction.getMnemonic().equals("clrlslwi") || instruction.getMnemonic().equals("clrlslwi.")) { // clrlslwi rA,rS,b,n (n <= b < 32) equivalent to rlwinm rA,rS,n,b - n,31 - n SH = integerOperand2.getValue(); MB = String.valueOf( Integer.decode(integerOperand1.getValue()) - Integer.decode(integerOperand2.getValue())); ME = String.valueOf(31 - Integer.decode(integerOperand2.getValue())); } else { SH = integerOperand1.getValue(); MB = integerOperand2.getValue(); } } else { SH = integerOperand1.getValue(); MB = integerOperand2.getValue(); ME = integerOperand3.getValue(); } final String normalMask = (instruction.getOperands().size() == 4) && !isSimplified ? integerOperand2.getValue() : Helpers.getRotateMask(MB, ME); final OperandSize dw = OperandSize.DWORD; /** * rlwinm Rotate Left Word Immediate then AND with Mask (x'5400 0000') rlwinm rA,rS,SH,MB,ME (Rc * = 0) rlwinm. rA,rS,SH,MB,ME (Rc = 1) n <- SH r <- ROTL(rS, n) m <- MASK(MB , ME) rA <- r & m * * <p>Simplified: extlwi rA,rS,n,b (n > 0) equivalent to rlwinm rA,rS,b,0,n - 1 extrwi rA,rS,n,b * (n > 0) equivalent to rlwinm rA,rS,b + n,32 - n,31 rotlwi rA,rS,n equivalent to rlwinm * rA,rS,n,0,31 rotrwi rA,rS,n equivalent to rlwinm rA,rS,32 - n,0,31 slwi rA,rS,n (n < 32) * equivalent to rlwinm rA,rS,n,0,31 - n srwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,32 - * n,n,31 clrlwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,0,n,31 clrrwi rA,rS,n (n < 32) * equivalent to rlwinm rA,rS,0,0,31 - n clrlslwi rA,rS,b,n (n <= b < 32) equivalent to rlwinm * rA,rS,n,b - n,31 - n */ // generate rotate through shift instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, SH, dw, rotateVar1)); instructions.add( ReilHelpers.createBsh( baseOffset++, dw, sourceRegister, dw, String.valueOf(-(32 - Integer.decode(SH))), dw, rotateVar2)); instructions.add( ReilHelpers.createOr(baseOffset++, dw, rotateVar1, dw, rotateVar2, dw, rotateVar3)); instructions.add( ReilHelpers.createAnd( baseOffset++, dw, rotateVar3, dw, String.valueOf(0xFFFFFFFFL), dw, rotateVar4)); // apply normal mask instructions.add( ReilHelpers.createAnd(baseOffset++, dw, rotateVar4, dw, normalMask, dw, targetRegister)); if (setCr) { // EQ CR0 instructions.add( ReilHelpers.createBisz( baseOffset++, OperandSize.DWORD, targetRegister, OperandSize.BYTE, Helpers.CR0_EQUAL)); // LT CR0 instructions.add( ReilHelpers.createBsh( baseOffset++, OperandSize.DWORD, targetRegister, OperandSize.WORD, "-31", OperandSize.BYTE, Helpers.CR0_LESS_THEN)); // GT CR0 instructions.add( ReilHelpers.createOr( baseOffset++, OperandSize.BYTE, Helpers.CR0_EQUAL, OperandSize.BYTE, Helpers.CR0_LESS_THEN, OperandSize.BYTE, crTemp)); instructions.add( ReilHelpers.createBisz( baseOffset++, OperandSize.BYTE, crTemp, OperandSize.BYTE, Helpers.CR0_GREATER_THEN)); // SO CR0 instructions.add( ReilHelpers.createStr( baseOffset, OperandSize.BYTE, Helpers.XER_SUMMARY_OVERFLOW, OperandSize.BYTE, Helpers.CRO_SUMMARY_OVERFLOW)); } }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { // TODO final String todo64 = ""; TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "lwr"); final OperandSize dw = OperandSize.DWORD; final OperandSize qw = OperandSize.QWORD; final String lastTwoAddressBits = environment.getNextVariableString(); final String shiftValue = environment.getNextVariableString(); final String memoryShiftAmount = environment.getNextVariableString(); final String registerMaskShiftAmount = environment.getNextVariableString(); final String shiftedMemoryContent = environment.getNextVariableString(); final String shiftedMemoryMask = environment.getNextVariableString(); final String maskedRegisterContent = environment.getNextVariableString(); final String temporaryResult = environment.getNextVariableString(); final String memoryContent = environment.getNextVariableString(); final String address = environment.getNextVariableString(); final IOperandTreeNode targetRegister = instruction.getOperands().get(0).getRootNode().getChildren().get(0); final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong(); long offset = baseOffset; final String extendedValue = SignExtendGenerator.extendAndAdd( offset, environment, instruction.getOperands().get(1), instructions); offset = baseOffset + instructions.size(); instructions.add( ReilHelpers.createAnd( offset++, dw, extendedValue, dw, String.valueOf(0xFFFFFFFCL), dw, address)); instructions.add(ReilHelpers.createLdm(offset, dw, address, dw, memoryContent)); instructions.add( ReilHelpers.createAnd( offset++, dw, extendedValue, dw, String.valueOf(3L), dw, lastTwoAddressBits)); instructions.add( ReilHelpers.createBsh( offset++, dw, lastTwoAddressBits, dw, String.valueOf(3L), dw, shiftValue)); final String endianess = "little"; if (endianess.equalsIgnoreCase("little")) { // little endian case // address bits 1:0 00 // memory content 0x11223344 shifted right by 0 -> 0x11223344 // register content 0xAABBCCDD masked with 0x00000000 -> 0x00000000 // both ored -> 0x11223344 // anded with register mask 0xFFFFFFFF -> 0x11223344 instructions.add( ReilHelpers.createSub( offset++, dw, String.valueOf(0L), dw, shiftValue, dw, memoryShiftAmount)); instructions.add( ReilHelpers.createSub( offset++, dw, String.valueOf(32L), dw, shiftValue, dw, registerMaskShiftAmount)); } else if (endianess.equalsIgnoreCase("big")) { // big endian case // address bits 1:0 00 // memory content 0x11223344 shifted right by 24 -> 0x00000011 // register contents 0xAABBCCDD masked with 0xFFFFFF00 -> 0xAABBCC00 // both ored -> 0xAABBCC11 // anded with register mask 0xFFFFFFF -> 0xAABBCC11 instructions.add( ReilHelpers.createAdd( offset++, dw, String.valueOf(-24L), dw, shiftValue, dw, memoryShiftAmount)); instructions.add( ReilHelpers.createAdd( offset++, dw, String.valueOf(8L), dw, shiftValue, dw, registerMaskShiftAmount)); } // bring the loaded memory into the correct position for register transfer instructions.add( ReilHelpers.createBsh( offset++, dw, memoryContent, dw, memoryShiftAmount, qw, shiftedMemoryContent)); // bring the register content into the correct form instructions.add( ReilHelpers.createBsh( offset++, dw, String.valueOf(0xFFFFFFFFL), dw, registerMaskShiftAmount, dw, shiftedMemoryMask)); instructions.add( ReilHelpers.createAnd( offset++, dw, targetRegister.getValue(), dw, shiftedMemoryMask, dw, maskedRegisterContent)); // combine the extracted information and adjust the size to machine register size instructions.add( ReilHelpers.createOr( offset++, dw, maskedRegisterContent, qw, shiftedMemoryContent, qw, temporaryResult)); instructions.add( ReilHelpers.createAnd( offset++, qw, temporaryResult, dw, String.valueOf(0xFFFFFFFFL), dw, targetRegister.getValue())); }
@Override protected void translateCore( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) { final IOperandTreeNode registerOperand1 = instruction.getOperands().get(0).getRootNode().getChildren().get(0); final IOperandTreeNode registerOperand2 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final IOperandTreeNode registerOperand3 = instruction.getOperands().get(2).getRootNode().getChildren().get(0); final IOperandTreeNode registerOperand4 = instruction.getOperands().get(3).getRootNode().getChildren().get(0); final String targetRegister = (registerOperand1.getValue()); final String sourceRegister1 = (registerOperand2.getValue()); final String sourceRegister2 = (registerOperand3.getValue()); final String sourceRegister3 = (registerOperand4.getValue()); final OperandSize bt = OperandSize.BYTE; final OperandSize dw = OperandSize.DWORD; final OperandSize qw = OperandSize.QWORD; final OperandSize wd = OperandSize.WORD; long baseOffset = ReilHelpers.nextReilAddress(instruction, instructions); final String operand2 = environment.getNextVariableString(); final String operand2from15to0 = environment.getNextVariableString(); final String operand2from31to16 = environment.getNextVariableString(); final String overflow1 = environment.getNextVariableString(); final String overflow2 = environment.getNextVariableString(); final String product1 = environment.getNextVariableString(); final String product2 = environment.getNextVariableString(); final String registerRm15to0 = environment.getNextVariableString(); final String registerRm31to16 = environment.getNextVariableString(); final String tmpAddResult1 = environment.getNextVariableString(); final String tmpResult1 = environment.getNextVariableString(); final String tmpRotate1 = environment.getNextVariableString(); final String tmpRotate2 = environment.getNextVariableString(); final String trueproduct1 = environment.getNextVariableString(); final String trueproduct2 = environment.getNextVariableString(); if (instruction.getMnemonic().contains("X")) { instructions.add( ReilHelpers.createBsh( baseOffset++, dw, sourceRegister2, bt, String.valueOf(-16), dw, tmpRotate1)); instructions.add( ReilHelpers.createBsh( baseOffset++, dw, sourceRegister2, bt, String.valueOf(16), dw, tmpRotate2)); instructions.add( ReilHelpers.createOr(baseOffset++, dw, tmpRotate1, dw, tmpRotate2, dw, operand2)); instructions.add( ReilHelpers.createAnd( baseOffset++, dw, operand2, dw, String.valueOf(0xFFFFFFFFL), dw, operand2)); } else { instructions.add(ReilHelpers.createStr(baseOffset++, dw, sourceRegister2, dw, operand2)); } // extract operand_2 high and low halves instructions.add( ReilHelpers.createAnd( baseOffset++, dw, operand2, dw, String.valueOf(0xFFFFL), dw, operand2from15to0)); instructions.add( ReilHelpers.createBsh( baseOffset++, dw, operand2, dw, String.valueOf(-16L), dw, operand2from31to16)); // extract Rm high and low halves instructions.add( ReilHelpers.createAnd( baseOffset++, dw, sourceRegister1, dw, String.valueOf(0xFFFFL), dw, registerRm15to0)); instructions.add( ReilHelpers.createBsh( baseOffset++, dw, sourceRegister1, dw, String.valueOf(-16L), dw, registerRm31to16)); Helpers.signedMul( baseOffset, environment, instruction, instructions, wd, registerRm15to0, wd, operand2from15to0, dw, trueproduct1); baseOffset = ReilHelpers.nextReilAddress(instruction, instructions); Helpers.signedMul( baseOffset, environment, instruction, instructions, wd, registerRm31to16, wd, operand2from31to16, dw, trueproduct2); baseOffset = ReilHelpers.nextReilAddress(instruction, instructions); instructions.add( ReilHelpers.createAdd(baseOffset++, dw, trueproduct1, dw, trueproduct2, qw, tmpAddResult1)); instructions.add( ReilHelpers.createAdd( baseOffset++, dw, sourceRegister3, qw, tmpAddResult1, qw, tmpResult1)); instructions.add( ReilHelpers.createAnd( baseOffset++, qw, tmpResult1, dw, String.valueOf(0xFFFFFFFFL), dw, targetRegister)); // calculate Overflow OF( product1 + priduct2 ) = sum | OF( sum + Rn ) Helpers.addOverflow( baseOffset, environment, instructions, dw, product1, dw, product2, qw, tmpAddResult1, overflow1, 16); baseOffset = ReilHelpers.nextReilAddress(instruction, instructions); Helpers.addOverflow( baseOffset, environment, instructions, dw, sourceRegister3, qw, tmpAddResult1, qw, tmpResult1, overflow2, 16); baseOffset = ReilHelpers.nextReilAddress(instruction, instructions); instructions.add(ReilHelpers.createOr(baseOffset++, bt, overflow1, bt, overflow2, bt, "Q")); }
/** * Translates an ADD instruction to REIL code. * * @param environment A valid translation environment. * @param instruction The ADD 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 ADD instruction */ @Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "add"); if (instruction.getOperands().size() != 2) { throw new InternalTranslationException( "Error: Argument instruction is not a add 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); 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(); final String msbMask = String.valueOf(TranslationHelpers.getMsbMask(size)); final String carryMask = String.valueOf(Helpers.getCarryMask(size)); final String truncateMask = String.valueOf(TranslationHelpers.getAllBitsMask(size)); final String shiftValue = String.valueOf(TranslationHelpers.getShiftMsbLsbMask(size)); final String shiftCarry = String.valueOf(-size.getBitSize()); final OperandSize resultSize = TranslationHelpers.getNextSize(size); final String msb1 = environment.getNextVariableString(); final String msb2 = environment.getNextVariableString(); final String addResult = environment.getNextVariableString(); final String msbResult = environment.getNextVariableString(); final String msbSameBefore = environment.getNextVariableString(); final String msbSameBeforeNeg = environment.getNextVariableString(); final String msbChanged = environment.getNextVariableString(); final String tempOf = environment.getNextVariableString(); final String tempCf = environment.getNextVariableString(); final String truncatedResult = environment.getNextVariableString(); // Isolate the MSBs of the two operands instructions.add( ReilHelpers.createAnd(offset, size, sourceRegister, size, msbMask, size, msb1)); instructions.add( ReilHelpers.createAnd(offset + 1, size, targetRegister, size, msbMask, size, msb2)); // Perform the addition instructions.add( ReilHelpers.createAdd( offset + 2, size, sourceRegister, size, targetRegister, resultSize, addResult)); // Isolate the MSB of the result and put it into the Sign Flag instructions.add( ReilHelpers.createAnd( offset + 3, resultSize, addResult, resultSize, msbMask, size, msbResult)); instructions.add( ReilHelpers.createBsh( offset + 4, size, msbResult, size, shiftValue, OperandSize.BYTE, Helpers.SIGN_FLAG)); // Find out if the MSB of the two operands were different and whether the MSB of the first // operand changed instructions.add( ReilHelpers.createXor(offset + 5, size, msb1, size, msb2, size, msbSameBefore)); instructions.add( ReilHelpers.createXor( offset + 6, size, msbSameBefore, size, msbMask, size, msbSameBeforeNeg)); instructions.add( ReilHelpers.createXor(offset + 7, size, msb1, size, msbResult, size, msbChanged)); instructions.add( ReilHelpers.createAnd(offset + 8, size, msbSameBeforeNeg, size, msbChanged, size, tempOf)); // Write the result into the Overflow Flag instructions.add( ReilHelpers.createBsh( offset + 9, size, tempOf, size, shiftValue, OperandSize.BYTE, Helpers.OVERFLOW_FLAG)); // Update the Carry Flag instructions.add( ReilHelpers.createAnd( offset + 10, resultSize, addResult, resultSize, carryMask, resultSize, tempCf)); instructions.add( ReilHelpers.createBsh( offset + 11, resultSize, tempCf, resultSize, shiftCarry, OperandSize.BYTE, Helpers.CARRY_FLAG)); // Truncate the result to fit into the target instructions.add( ReilHelpers.createAnd( offset + 12, resultSize, addResult, resultSize, truncateMask, size, truncatedResult)); // Update the Zero Flag instructions.add( ReilHelpers.createBisz( offset + 13, size, truncatedResult, OperandSize.BYTE, Helpers.ZERO_FLAG)); // Write the result of the ADD operation back into the target register Helpers.writeBack( environment, offset + 14, targetOperand, truncatedResult, size, targetResult.getAddress(), targetResult.getType(), instructions); }
@Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "div"); final String sourceRegister1 = instruction.getOperands().get(0).getRootNode().getChildren().get(0).getValue(); final String sourceRegister2 = instruction.getOperands().get(1).getRootNode().getChildren().get(0).getValue(); final OperandSize dw = OperandSize.DWORD; final long baseOffset = ReilHelpers.toReilAddress(instruction.getAddress()).toLong(); long offset = baseOffset; final Pair<String, String> sourceRegister1Abs = Helpers.generateAbs(environment, offset, sourceRegister1, dw, instructions); final String sourceRegister1Absolute = sourceRegister1Abs.second(); offset = baseOffset + instructions.size(); final Pair<String, String> sourceRegister2Abs = Helpers.generateAbs(environment, offset, sourceRegister2, dw, instructions); final String sourceRegister2Absolute = sourceRegister2Abs.second(); offset = baseOffset + instructions.size(); final String divResult = environment.getNextVariableString(); final String modResult = environment.getNextVariableString(); instructions.add( ReilHelpers.createDiv( offset++, dw, sourceRegister1Absolute, dw, sourceRegister2Absolute, dw, divResult)); instructions.add( ReilHelpers.createMod( offset++, dw, sourceRegister1Absolute, dw, sourceRegister2Absolute, dw, modResult)); final String xoredSigns = environment.getNextVariableString(); final String divToggleMask = environment.getNextVariableString(); final String xoredDivResult = environment.getNextVariableString(); // Find out if the two operands had different signs and adjust the result accordingly instructions.add( ReilHelpers.createXor( offset++, dw, sourceRegister1Abs.first(), dw, sourceRegister2Abs.first(), dw, xoredSigns)); instructions.add( ReilHelpers.createSub(offset++, dw, String.valueOf(0L), dw, xoredSigns, dw, divToggleMask)); instructions.add( ReilHelpers.createXor(offset++, dw, divToggleMask, dw, divResult, dw, xoredDivResult)); instructions.add(ReilHelpers.createAdd(offset++, dw, xoredDivResult, dw, xoredSigns, dw, "LO")); final String modToggleMask = environment.getNextVariableString(); final String xoredModResult = environment.getNextVariableString(); instructions.add( ReilHelpers.createSub( offset++, dw, String.valueOf(0L), dw, sourceRegister1Abs.first(), dw, modToggleMask)); instructions.add( ReilHelpers.createXor(offset++, dw, modToggleMask, dw, modResult, dw, xoredModResult)); instructions.add( ReilHelpers.createAdd( offset++, dw, xoredModResult, dw, sourceRegister1Abs.first(), dw, "HI")); }
@Override protected void translateCore( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { final IOperandTreeNode registerOperand1 = instruction.getOperands().get(0).getRootNode().getChildren().get(0); final IOperandTreeNode shifter = instruction.getOperands().get(1).getRootNode(); final String sourceRegister = (registerOperand1.getValue()); final OperandSize bt = OperandSize.BYTE; final OperandSize wd = OperandSize.WORD; final OperandSize dw = OperandSize.DWORD; final OperandSize qw = OperandSize.QWORD; long baseOffset = (instruction.getAddress().toLong() * 0x100) + instructions.size(); final String tmpVar1 = environment.getNextVariableString(); final String aluOut = environment.getNextVariableString(); // compute <shifter_operand> final Pair<String, String> shifterPair = AddressingModeOneGenerator.generate( baseOffset, environment, instruction, instructions, shifter); baseOffset = (instruction.getAddress().toLong() * 0x100) + instructions.size(); final String shifterOperand = shifterPair.first(); instructions.add( ReilHelpers.createAdd(baseOffset++, dw, sourceRegister, dw, shifterOperand, qw, tmpVar1)); instructions.add( ReilHelpers.createAnd( baseOffset++, qw, tmpVar1, dw, String.valueOf(0xFFFFFFFFL), dw, aluOut)); // match the case where we have to set flags this does not handle the S == 1 and Rd == R15 case // !!! final String tmpVar3 = environment.getNextVariableString(); final String tmpVar4 = environment.getNextVariableString(); final String msbVar1 = environment.getNextVariableString(); final String msbVar2 = environment.getNextVariableString(); // N Flag Rd[31] instructions.add( ReilHelpers.createBsh(baseOffset++, qw, tmpVar1, dw, String.valueOf(-31L), bt, tmpVar3)); instructions.add( ReilHelpers.createAnd(baseOffset++, bt, tmpVar3, bt, String.valueOf(1L), bt, "N")); // Z Flag if Rd == 0 then 1 else 0 instructions.add(ReilHelpers.createBisz(baseOffset++, dw, aluOut, bt, "Z")); // C Flag CarryFrom(Rn + shifter_operand) instructions.add( ReilHelpers.createBsh(baseOffset++, qw, tmpVar1, wd, String.valueOf(-32L), bt, tmpVar4)); instructions.add( ReilHelpers.createAnd(baseOffset++, bt, tmpVar4, bt, String.valueOf(1L), bt, "C")); // V Flag OverflowFrom(Rn + shifter_operand) instructions.add( ReilHelpers.createBsh( baseOffset++, dw, shifterOperand, wd, String.valueOf(-31L), bt, msbVar1)); instructions.add( ReilHelpers.createBsh( baseOffset++, dw, sourceRegister, wd, String.valueOf(-31L), bt, msbVar2)); // ( msbA XOR msbR ) AND ( msbB XOR msbR ) == OF instructions.add(ReilHelpers.createXor(baseOffset++, bt, msbVar1, bt, "N", bt, tmpVar4)); instructions.add(ReilHelpers.createXor(baseOffset++, bt, msbVar2, bt, "N", bt, tmpVar3)); instructions.add(ReilHelpers.createAnd(baseOffset++, bt, tmpVar4, bt, tmpVar3, bt, "V")); }
/** * Translates a OR instruction to REIL code. * * @param environment A valid translation environment. * @param instruction The OR 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 OR instruction */ @Override public void translate( final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, "or"); if (instruction.getOperands().size() != 2) { throw new InternalTranslationException( "Error: Argument instruction is not a or 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); 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(); final String orResult = environment.getNextVariableString(); // Do the OR operation instructions.add( ReilHelpers.createOr(offset, size, sourceRegister, size, targetRegister, size, orResult)); // Set the flags according to the result of the OR operation Helpers.generateBinaryOperationFlags(environment, offset + 1, orResult, size, instructions); offset = baseOffset + instructions.size(); // Write the result of the OR operation back into the target operand Helpers.writeBack( environment, offset, targetOperand, orResult, size, targetResult.getAddress(), targetResult.getType(), instructions); }