Example #1
0
        public Expression Transform(IntelInstruction instr, MachineOperand op, PrimitiveType opWidth, X86State state)
        {
            var reg = op as RegisterOperand;

            if (reg != null)
            {
                return(AluRegister(reg));
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                return(CreateMemoryAccess(instr, mem, opWidth, state));
            }
            var imm = op as ImmediateOperand;

            if (imm != null)
            {
                return(CreateConstant(imm, opWidth));
            }
            var fpu = op as FpuOperand;

            if (fpu != null)
            {
                return(FpuRegister(fpu.StNumber, state));
            }
            var addr = op as AddressOperand;

            if (addr != null)
            {
                return(addr.Address);
            }
            throw new NotImplementedException(string.Format("Operand {0}", op));
        }
Example #2
0
        private Expression CreateTestCondition(ConditionCode cc, Opcode opcode)
        {
            var grf = orw.FlagGroup(IntelInstruction.UseCc(opcode));
            var tc  = new TestCondition(cc, grf);

            return(tc);
        }
Example #3
0
        public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand mem, DataType dt, X86State state)
        {
            var exp = ImportedProcedureName(instr.Address, mem.Width, mem);

            if (exp != null)
            {
                return(new ProcedureConstant(arch.PointerType, exp));
            }

            Expression expr = EffectiveAddressExpression(instr, mem, state);

            if (IsSegmentedAccessRequired ||
                (mem.DefaultSegment != Registers.ds && mem.DefaultSegment != Registers.ss))
            {
                Expression seg = ReplaceCodeSegment(mem.DefaultSegment, state);
                if (seg == null)
                {
                    seg = AluRegister(mem.DefaultSegment);
                }
                return(new SegmentedAccess(MemoryIdentifier.GlobalMemory, seg, expr, dt));
            }
            else
            {
                return(new MemoryAccess(MemoryIdentifier.GlobalMemory, expr, dt));
            }
        }
Example #4
0
        /*
         * the C0 bit becomes the CF (carry) flag, 
 the C2 bit becomes the PF(parity) flag, and 
 the C3 bit becomes the ZF (zero) flag. 
         */
        //  >              0
        //  <              1
        //  =             40
        //  inordered     45

        public FstswChainMatcher(IntelInstruction[] instrs, OperandRewriter orw)
        {
            this.instrs = instrs;
            this.orw = orw;
            this.zappedInstructions = new Dictionary<int, Opcode>();
            this.rewritten = new List<Instruction>();
        }
Example #5
0
        /// <summary>
        /// A jump to 0xFFFF:0x0000 in real mode is a reboot.
        /// </summary>
        /// <param name="instrCur"></param>
        /// <returns></returns>
        private bool IsRealModeReboot(IntelInstruction instrCur)
        {
            var  addrOp           = instrCur.op1 as X86AddressOperand;
            bool isRealModeReboot = addrOp != null && addrOp.Address.ToLinear() == 0xFFFF0;

            return(isRealModeReboot);
        }
Example #6
0
        /// <summary>
        /// Breaks up very common case of x86:
        /// <code>
        ///		op [memaddr], reg
        /// </code>
        /// into the equivalent:
        /// <code>
        ///		tmp := [memaddr] op reg;
        ///		store([memaddr], tmp);
        /// </code>
        /// </summary>
        /// <param name="opDst"></param>
        /// <param name="src"></param>
        /// <param name="forceBreak">if true, forcibly splits the assignments in two if the destination is a memory store.</param>
        /// <returns>Returns the destination of the copy.</returns>
        public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags)
        {
            Expression dst   = SrcOp(opDst);
            Identifier idDst = dst as Identifier;

            if (idDst != null || (flags & CopyFlags.ForceBreak) == 0)
            {
                emitter.Assign(dst, src);
            }
            else
            {
                Identifier tmp = frame.CreateTemporary(opDst.Width);
                emitter.Assign(tmp, src);
                var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state);
                emitter.Assign(ea, tmp);
                dst = tmp;
            }
            if ((flags & CopyFlags.EmitCc) != 0)
            {
                EmitCcInstr(dst, IntelInstruction.DefCc(instrCur.code));
            }
            if ((flags & CopyFlags.SetCfIf0) != 0)
            {
                emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Eq0(dst));
            }
        }
Example #7
0
        /// <summary>
        /// Implementation of IComparer.Compare. In reality,
        /// </summary>
        /// <param name="oInstrA"></param>
        /// <param name="oInstrB"></param>
        /// <returns></returns>
        public int Compare(object oInstrA, object oInstrB)
        {
            IntelInstruction instrA = (IntelInstruction)oInstrA;
            IntelInstruction instrB = (IntelInstruction)oInstrB;

            if (instrA.code != instrB.code)
            {
                return((int)instrB.code - (int)instrA.code);
            }
            if (instrA.Operands != instrB.Operands)
            {
                return(instrB.Operands - instrA.Operands);
            }
            ;

            int retval = 0;

            if (instrA.Operands > 0)
            {
                retval = CompareOperands(instrA.op1, instrB.op1);
                if (retval == 0 && instrA.Operands > 1)
                {
                    retval = CompareOperands(instrA.op2, instrB.op2);
                    if (retval == 0 && instrA.Operands > 2)
                    {
                        retval = CompareOperands(instrA.op3, instrB.op3);
                    }
                }
            }
            return(retval);
        }
Example #8
0
        private void RewriteCmp()
        {
            Expression op1 = SrcOp(instrCur.op1);
            Expression op2 = SrcOp(instrCur.op2, instrCur.op1.Width);

            emitter.Assign(
                orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
                new ConditionOf(emitter.ISub(op1, op2)));
        }
Example #9
0
        private void RewriteMultiply(BinaryOperator op, Domain resultDomain)
        {
            Expression product;

            switch (instrCur.Operands)
            {
            case 1:
                Identifier multiplicator;

                switch (instrCur.op1.Width.Size)
                {
                case 1:
                    multiplicator = orw.AluRegister(Registers.al);
                    product       = orw.AluRegister(Registers.ax);
                    break;

                case 2:
                    multiplicator = orw.AluRegister(Registers.ax);
                    product       = frame.EnsureSequence(
                        orw.AluRegister(Registers.dx), multiplicator, PrimitiveType.Word32);
                    break;

                case 4:
                    multiplicator = orw.AluRegister(Registers.eax);
                    product       = frame.EnsureSequence(
                        orw.AluRegister(Registers.edx), multiplicator, PrimitiveType.Word64);
                    break;

                default:
                    throw new ApplicationException(string.Format("Unexpected operand size: {0}", instrCur.op1.Width));
                }
                ;
                emitter.Assign(
                    product,
                    new BinaryExpression(
                        op,
                        PrimitiveType.Create(resultDomain, product.DataType.Size),
                        SrcOp(instrCur.op1),
                        multiplicator));
                EmitCcInstr(product, IntelInstruction.DefCc(instrCur.code));
                return;

            case 2:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op1), SrcOp(instrCur.op2),
                          CopyFlags.ForceBreak | CopyFlags.EmitCc);
                return;

            case 3:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op2), SrcOp(instrCur.op3),
                          CopyFlags.ForceBreak | CopyFlags.EmitCc);
                return;

            default:
                throw new ArgumentException("Invalid number of operands");
            }
        }
Example #10
0
        private void RewriteXadd()
        {
            var dst = SrcOp(instrCur.op1);
            var src = SrcOp(instrCur.op2);

            emitter.Assign(
                dst,
                PseudoProc("__xadd", instrCur.op1.Width, dst, src));
            EmitCcInstr(dst, IntelInstruction.DefCc(instrCur.code));
        }
Example #11
0
        private void RewriteTest()
        {
            var src = new BinaryExpression(Operator.And,
                                           instrCur.op1.Width,
                                           SrcOp(instrCur.op1),
                                           SrcOp(instrCur.op2));

            EmitCcInstr(src, (IntelInstruction.DefCc(instrCur.code) & ~FlagM.CF));
            emitter.Assign(orw.FlagGroup(FlagM.CF), Constant.False());
        }
 public void DcffLiveAtEnd()
 {
     IntelInstruction [] instrs =
         new IntelInstruction[] {
                                    new IntelInstruction(Opcode.cmp, PrimitiveType.Word32, PrimitiveType.Word32, new RegisterOperand(Registers.eax), new RegisterOperand(Registers.eax)),
                                    new IntelInstruction(Opcode.jnz, PrimitiveType.Word32, PrimitiveType.Word32, new ImmediateOperand(Constant.Word32(0x10001010)))
                                };
     FlagM [] deadOut = dcff.DeadOutFlags(instrs);
     Assert.AreEqual(0, (int) deadOut[0]);
 }
Example #13
0
		public void Setup()
		{
            prog = new Program();
            prog.Image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
            var procAddress = Address.Ptr32(0x10000000);
            instr = new IntelInstruction(Opcode.nop, PrimitiveType.Word32, PrimitiveType.Word32)
            {
                Address = procAddress,
            };
            proc = Procedure.Create(procAddress, arch.CreateFrame());
			state = (X86State) arch.CreateProcessorState();
			orw = new OperandRewriter32(arch, proc.Frame, new FakeRewriterHost(prog));
		}
 public void DcffConsecutiveAdds()
 {
     IntelInstruction [] instrs =
         new IntelInstruction[] {
                                    new IntelInstruction(Opcode.add, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(Registers.bx), new ImmediateOperand(Constant.Word16(0x10))),
                                    new IntelInstruction(Opcode.mov, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(Registers.si), new RegisterOperand(Registers.bx)),
                                    new IntelInstruction(Opcode.add, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(Registers.cx), new ImmediateOperand(Constant.Word16(1)))
                                };
     FlagM [] deadOut = dcff.DeadOutFlags(instrs);
     Assert.AreEqual(FlagM.SF|FlagM.CF|FlagM.ZF|FlagM.OF, deadOut[0], "Item 0");
     Assert.AreEqual(FlagM.SF|FlagM.CF|FlagM.ZF|FlagM.OF, deadOut[1], "Item 1");
     Assert.AreEqual(0, (int) deadOut[2], "Item 2");
 }
Example #15
0
        private void RewriteDivide(BinaryOperator op, Domain domain)
        {
            if (instrCur.Operands != 1)
            {
                throw new ArgumentOutOfRangeException("Intel DIV/IDIV instructions only take one operand");
            }
            Identifier regDividend;
            Identifier regQuotient;
            Identifier regRemainder;

            switch (instrCur.dataWidth.Size)
            {
            case 1:
                regQuotient  = orw.AluRegister(Registers.al);
                regDividend  = orw.AluRegister(Registers.ax);
                regRemainder = orw.AluRegister(Registers.ah);
                break;

            case 2:
                regQuotient  = orw.AluRegister(Registers.ax);
                regRemainder = orw.AluRegister(Registers.dx);
                regDividend  = frame.EnsureSequence(regRemainder, regQuotient, PrimitiveType.Word32);
                break;

            case 4:
                regQuotient  = orw.AluRegister(Registers.eax);
                regRemainder = orw.AluRegister(Registers.edx);
                regDividend  = frame.EnsureSequence(regRemainder, regQuotient, PrimitiveType.Word64);
                break;

            default:
                throw new ArgumentOutOfRangeException(string.Format("{0}-byte divisions not supported.", instrCur.dataWidth.Size));
            }
            ;
            PrimitiveType p = ((PrimitiveType)regRemainder.DataType).MaskDomain(domain);

            emitter.Assign(
                regRemainder, new BinaryExpression(Operator.IMod, p,
                                                   regDividend,
                                                   SrcOp(instrCur.op1)));
            emitter.Assign(
                regQuotient, new BinaryExpression(op, p, regDividend,
                                                  SrcOp(instrCur.op1)));
            EmitCcInstr(regQuotient, IntelInstruction.DefCc(instrCur.code));
        }
		public void Setup()
		{
			arch = new IntelArchitecture(ProcessorMode.Real);
            var image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
			var prog = new Program(
                image,
                image.CreateImageMap(),
                arch,
                null);
			var procAddress = Address.Ptr32(0x10000000);
            instr = new IntelInstruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16)
            {
                Address = procAddress,
            };

            proc = Procedure.Create(procAddress, arch.CreateFrame());
			orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog));
            state = (X86State)arch.CreateProcessorState();
        }
Example #17
0
 public Expression Transform(IntelInstruction instr, MachineOperand op, PrimitiveType opWidth, X86State state)
 {
     var reg = op as RegisterOperand;
     if (reg != null)
         return AluRegister(reg);
     var mem = op as MemoryOperand;
     if (mem != null)
         return CreateMemoryAccess(instr, mem, opWidth, state);
     var imm = op as ImmediateOperand;
     if (imm != null)
         return CreateConstant(imm, opWidth);
     var fpu = op as FpuOperand;
     if (fpu != null)
         return FpuRegister(fpu.StNumber, state);
     var addr = op as AddressOperand;
     if (addr != null)
         return addr.Address;
     throw new NotImplementedException(string.Format("Operand {0}", op));
 }
Example #18
0
        private int GetHashCodeInner(object obj)
        {
            IntelInstruction instr = (IntelInstruction)obj;
            int hash = instr.code.GetHashCode();

            hash = hash * 47 + instr.Operands.GetHashCode();

            if (instr.Operands > 0)
            {
                hash = hash * 23 + GetHashCode(instr.op1);
                if (instr.Operands > 1)
                {
                    hash = hash * 17 + GetHashCode(instr.op2);
                    if (instr.Operands > 2)
                    {
                        hash = hash * 13 + GetHashCode(instr.op3);
                    }
                }
            }
            return(hash);
        }
Example #19
0
        private void RewriteLogical(BinaryOperator op)
        {
            if (instrCur.code == Opcode.and)
            {
                var r = instrCur.op1 as RegisterOperand;
                if (r != null && r.Register == arch.StackRegister &&
                    instrCur.op2 is ImmediateOperand)
                {
                    emitter.SideEffect(PseudoProc("__align", VoidType.Instance, SrcOp(instrCur.op1)));
                    return;
                }
            }

            EmitBinOp(
                op,
                instrCur.op1,
                instrCur.op1.Width,
                SrcOp(instrCur.op1),
                SrcOp(instrCur.op2),
                CopyFlags.ForceBreak);
            EmitCcInstr(SrcOp(instrCur.op1), (IntelInstruction.DefCc(instrCur.code) & ~FlagM.CF));
            emitter.Assign(orw.FlagGroup(FlagM.CF), Constant.False());
        }
Example #20
0
        private void RewriteStringInstruction()
        {
            bool incSi       = false;
            bool incDi       = false;
            var  incOperator = GetIncrementOperator();

            Identifier      regDX;
            PseudoProcedure ppp;

            switch (instrCur.code)
            {
            default:
                throw new NotSupportedException(string.Format("'{0}' is not an x86 string instruction.", instrCur.code));

            case Opcode.cmps:
            case Opcode.cmpsb:
                emitter.Assign(
                    orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi())));
                incSi = true;
                incDi = true;
                break;

            case Opcode.lods:
            case Opcode.lodsb:
                emitter.Assign(RegAl, MemSi());
                incSi = true;
                break;

            case Opcode.movs:
            case Opcode.movsb:
                Identifier tmp = frame.CreateTemporary(instrCur.dataWidth);
                emitter.Assign(tmp, MemSi());
                emitter.Assign(MemDi(), tmp);
                incSi = true;
                incDi = true;
                break;

            case Opcode.ins:
            case Opcode.insb:
                regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                ppp   = host.EnsurePseudoProcedure("__in", instrCur.dataWidth, 1);
                emitter.Assign(MemDi(), emitter.Fn(ppp, regDX));
                incDi = true;
                break;

            case Opcode.outs:
            case Opcode.outsb:
                regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                ppp   = host.EnsurePseudoProcedure("__out" + RegAl.DataType.Prefix, VoidType.Instance, 2);
                emitter.SideEffect(emitter.Fn(ppp, regDX, RegAl));
                incSi = true;
                break;

            case Opcode.scas:
            case Opcode.scasb:
                emitter.Assign(
                    orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub,
                                             instrCur.dataWidth,
                                             RegAl,
                                             MemDi())));
                incDi = true;
                break;

            case Opcode.stos:
            case Opcode.stosb:
                emitter.Assign(MemDi(), RegAl);
                incDi = true;
                break;

            case Opcode.ret:
                // "AMD recommends to avoid the penalty by adding rep prefix instead of nop
                // because it saves decode bandwidth."
                RewriteRet();
                return;
            }

            if (incSi)
            {
                emitter.Assign(RegSi,
                               new BinaryExpression(incOperator,
                                                    instrCur.addrWidth,
                                                    RegSi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }

            if (incDi)
            {
                emitter.Assign(RegDi,
                               new BinaryExpression(incOperator,
                                                    instrCur.addrWidth,
                                                    RegDi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }
        }
Example #21
0
        public void Execute(IntelInstruction instr)
        {
            switch (instr.code)
            {
            default:
                throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr));

            case Opcode.adc: Adc(instr.op1, instr.op2); return;

            case Opcode.add: Add(instr.op1, instr.op2); return;

            case Opcode.and: And(instr.op1, instr.op2); return;

            case Opcode.call: Call(instr.op1); return;

            case Opcode.cmp: Cmp(instr.op1, instr.op2); return;

            case Opcode.dec: Dec(instr.op1); return;

            case Opcode.hlt: running = false; return;

            case Opcode.inc: Inc(instr.op1); return;

            case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jc: if ((Flags & Cmask) != 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jmp: Jump(instr.op1); return;

            case Opcode.jnc: if ((Flags & Cmask) == 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jnz: if ((Flags & Zmask) == 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jz: if ((Flags & Zmask) != 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break;

            case Opcode.loop: Loop(instr.op1); break;

            case Opcode.mov: Write(instr.op1, Read(instr.op2)); break;

            case Opcode.or: Or(instr.op1, instr.op2); return;

            case Opcode.pop: Write(instr.op1, Pop()); return;

            case Opcode.popa: Popa(); return;

            case Opcode.push: Push(Read(instr.op1)); return;

            case Opcode.pusha: Pusha(); return;

            case Opcode.repne: Repne(); return;

            case Opcode.rol: Rol(instr.op1, instr.op2); return;

            case Opcode.scasb: Scasb(); return;

            case Opcode.shl: Shl(instr.op1, instr.op2); return;

            case Opcode.shr: Shr(instr.op1, instr.op2); return;

            case Opcode.sub: Sub(instr.op1, instr.op2); return;

            case Opcode.xor: Xor(instr.op1, instr.op2); return;

            case Opcode.xchg: Xchg(instr.op1, instr.op2); return;
            }
        }
Example #22
0
 /// <summary>
 /// A jump to 0xFFFF:0x0000 in real mode is a reboot.
 /// </summary>
 /// <param name="instrCur"></param>
 /// <returns></returns>
 private bool IsRealModeReboot(IntelInstruction instrCur)
 {
     var addrOp = instrCur.op1 as X86AddressOperand;
     bool isRealModeReboot = addrOp != null && addrOp.Address.ToLinear() == 0xFFFF0;
     return isRealModeReboot;
 }
Example #23
0
		private IntelInstruction CreatePush(IntelRegister reg)
		{
            IntelInstruction inst = new IntelInstruction(
                Opcode.push,
                reg.DataType,
                reg.DataType,
                new RegisterOperand(reg));
			return inst;
		}
Example #24
0
		private IntelInstruction CreateMov(IntelRegister regDst, IntelRegister regSrc)
		{
            IntelInstruction inst = new IntelInstruction(
                Opcode.mov,
                PrimitiveType.Word16,
                PrimitiveType.Word16,
                new RegisterOperand(regDst),
                new RegisterOperand(regSrc));
			return inst;
		}
Example #25
0
        /// <summary>
        /// Iterator that yields one RtlIntructionCluster for each x86 instruction.
        /// </summary>
        /// <returns></returns>
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instrCur = dasm.Current;
                ric      = new RtlInstructionCluster(instrCur.Address, instrCur.Length);
                emitter  = new RtlEmitter(ric.Instructions);
                orw      = arch.ProcessorMode.CreateOperandRewriter(arch, frame, host);
                switch (instrCur.code)
                {
                default:
                    throw new AddressCorrelatedException(
                              instrCur.Address,
                              "Rewriting x86 opcode '{0}' is not supported yet.",
                              instrCur.code);

                case Opcode.aaa: RewriteAaa(); break;

                case Opcode.aam: RewriteAam(); break;

                case Opcode.adc: RewriteAdcSbb(BinaryOperator.IAdd); break;

                case Opcode.add: RewriteAddSub(BinaryOperator.IAdd); break;

                case Opcode.and: RewriteLogical(BinaryOperator.And); break;

                case Opcode.arpl: RewriteArpl(); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.bswap: RewriteBswap(); break;

                case Opcode.bt: RewriteBt(); break;

                case Opcode.btr: RewriteBtr(); break;

                case Opcode.bts: RewriteBts(); break;

                case Opcode.call: RewriteCall(instrCur.op1, instrCur.op1.Width); break;

                case Opcode.cbw: RewriteCbw(); break;

                case Opcode.clc: RewriteSetFlag(FlagM.CF, Constant.False()); break;

                case Opcode.cld: RewriteSetFlag(FlagM.DF, Constant.False()); break;

                case Opcode.cli: RewriteCli(); break;

                case Opcode.cmc: emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Not(orw.FlagGroup(FlagM.CF))); break;

                case Opcode.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.op1, instrCur.op2); break;

                case Opcode.cmpxchg: RewriteCmpxchg(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmps: RewriteStringInstruction(); break;

                case Opcode.cmpsb: RewriteStringInstruction(); break;

                case Opcode.cpuid: RewriteCpuid(); break;

                case Opcode.cvttsd2si: RewriteCvttsd2si(); break;

                case Opcode.cwd: RewriteCwd(); break;

                case Opcode.daa: EmitDaaDas("__daa"); break;

                case Opcode.das: EmitDaaDas("__das"); break;

                case Opcode.dec: RewriteIncDec(-1); break;

                case Opcode.div: RewriteDivide(Operator.UDiv, Domain.UnsignedInt); break;

                case Opcode.enter: RewriteEnter(); break;

                case Opcode.fadd: EmitCommonFpuInstruction(Operator.FAdd, false, false); break;

                case Opcode.faddp: EmitCommonFpuInstruction(Operator.FAdd, false, true); break;

                case Opcode.fchs: EmitFchs(); break;

                case Opcode.fclex: RewriteFclex(); break;

                case Opcode.fcom: RewriteFcom(0); break;

                case Opcode.fcomp: RewriteFcom(1); break;

                case Opcode.fcompp: RewriteFcom(2); break;

                case Opcode.fcos: RewriteFUnary("cos"); break;

                case Opcode.fdiv: EmitCommonFpuInstruction(Operator.FDiv, false, false); break;

                case Opcode.fdivp: EmitCommonFpuInstruction(Operator.FDiv, false, true); break;

                case Opcode.fiadd: EmitCommonFpuInstruction(Operator.FAdd, false, false, PrimitiveType.Real64); break;

                case Opcode.fimul: EmitCommonFpuInstruction(Operator.FMul, false, false, PrimitiveType.Real64); break;

                case Opcode.fisub: EmitCommonFpuInstruction(Operator.FSub, false, false, PrimitiveType.Real64); break;

                case Opcode.fisubr: EmitCommonFpuInstruction(Operator.FSub, true, false, PrimitiveType.Real64); break;

                case Opcode.fidiv: EmitCommonFpuInstruction(Operator.FDiv, false, false, PrimitiveType.Real64); break;

                case Opcode.fdivr: EmitCommonFpuInstruction(Operator.FDiv, true, false); break;

                case Opcode.fdivrp: EmitCommonFpuInstruction(Operator.FDiv, true, true); break;

                case Opcode.fild: RewriteFild(); break;

                case Opcode.fistp: RewriteFistp(); break;

                case Opcode.fld: RewriteFld(); break;

                case Opcode.fld1: RewriteFldConst(1.0); break;

                case Opcode.fldcw: RewriteFldcw(); break;

                case Opcode.fldln2: RewriteFldConst(Constant.Ln2()); break;

                case Opcode.fldpi: RewriteFldConst(Constant.Pi()); break;

                case Opcode.fldz: RewriteFldConst(0.0); break;

                case Opcode.fmul: EmitCommonFpuInstruction(Operator.FMul, false, false); break;

                case Opcode.fmulp: EmitCommonFpuInstruction(Operator.FMul, false, true); break;

                case Opcode.fpatan: RewriteFpatan(); break;

                case Opcode.frndint: RewriteFUnary("__rndint"); break;

                case Opcode.fsin: RewriteFUnary("sin"); break;

                case Opcode.fsincos: RewriteFsincos(); break;

                case Opcode.fsqrt: RewriteFUnary("sqrt"); break;

                case Opcode.fst: RewriteFst(false); break;

                case Opcode.fstcw: RewriterFstcw(); break;

                case Opcode.fstp: RewriteFst(true); break;

                case Opcode.fstsw: RewriteFstsw(); break;

                case Opcode.fsub: EmitCommonFpuInstruction(Operator.ISub, false, false); break;

                case Opcode.fsubp: EmitCommonFpuInstruction(Operator.ISub, false, true); break;

                case Opcode.fsubr: EmitCommonFpuInstruction(Operator.ISub, true, false); break;

                case Opcode.fsubrp: EmitCommonFpuInstruction(Operator.ISub, true, true); break;

                case Opcode.ftst: RewriteFtst(); break;

                case Opcode.fucompp: RewriteFcom(2); break;

                case Opcode.fxam: RewriteFxam(); break;

                case Opcode.fxch: RewriteExchange(); break;

                case Opcode.fyl2x: RewriteFyl2x(); break;

                case Opcode.hlt: RewriteHlt(); break;

                case Opcode.idiv: RewriteDivide(Operator.SDiv, Domain.SignedInt); break;

                case Opcode.@in: RewriteIn(); break;

                case Opcode.imul: RewriteMultiply(Operator.SMul, Domain.SignedInt); break;

                case Opcode.inc: RewriteIncDec(1); break;

                case Opcode.insb: RewriteStringInstruction(); break;

                case Opcode.ins: RewriteStringInstruction(); break;

                case Opcode.@int: RewriteInt(); break;

                case Opcode.iret: RewriteIret(); break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.op1); break;

                case Opcode.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.op1); break;

                case Opcode.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.op1); break;

                case Opcode.jcxz: RewriteJcxz(); break;

                case Opcode.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.op1); break;

                case Opcode.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.op1); break;

                case Opcode.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.op1); break;

                case Opcode.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.op1); break;

                case Opcode.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.op1); break;

                case Opcode.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.op1); break;

                case Opcode.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.op1); break;

                case Opcode.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.op1); break;

                case Opcode.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.op1); break;

                case Opcode.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.op1); break;

                case Opcode.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.op1); break;

                case Opcode.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.op1); break;

                case Opcode.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.op1); break;

                case Opcode.lahf: RewriteLahf(); break;

                case Opcode.lds: RewriteLxs(Registers.ds); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.leave: RewriteLeave(); break;

                case Opcode.les: RewriteLxs(Registers.es); break;

                case Opcode.lfs: RewriteLxs(Registers.fs); break;

                case Opcode.lgs: RewriteLxs(Registers.gs); break;

                case Opcode.@lock: RewriteLock(); break;

                case Opcode.lods: RewriteStringInstruction(); break;

                case Opcode.lodsb: RewriteStringInstruction(); break;

                case Opcode.loop: RewriteLoop(0, ConditionCode.EQ); break;

                case Opcode.loope: RewriteLoop(FlagM.ZF, ConditionCode.EQ); break;

                case Opcode.loopne: RewriteLoop(FlagM.ZF, ConditionCode.NE); break;

                case Opcode.lss: RewriteLxs(Registers.ss); break;

                case Opcode.mov: RewriteMov(); break;

                case Opcode.movd: RewriteMovzx(); break;

                case Opcode.movdqa: RewriteMov(); break;

                case Opcode.movq: RewriteMov(); break;

                case Opcode.movs: RewriteStringInstruction(); break;

                case Opcode.movsb: RewriteStringInstruction(); break;

                case Opcode.movsx: RewriteMovsx(); break;

                case Opcode.movzx: RewriteMovzx(); break;

                case Opcode.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break;

                case Opcode.neg: RewriteNeg(); break;

                case Opcode.nop: continue;

                case Opcode.not: RewriteNot(); break;

                case Opcode.or: RewriteLogical(BinaryOperator.Or); break;

                case Opcode.@out: RewriteOut(); break;

                case Opcode.@outs: RewriteStringInstruction(); break;

                case Opcode.@outsb: RewriteStringInstruction(); break;

                case Opcode.palignr: RewritePalignr(); break;

                case Opcode.pop: RewritePop(); break;

                case Opcode.popa: RewritePopa(); break;

                case Opcode.popf: RewritePopf(); break;

                case Opcode.pshufd: RewritePshufd(); break;

                case Opcode.punpcklbw: RewritePunpcklbw(); break;

                case Opcode.punpcklwd: RewritePunpcklwd(); break;

                case Opcode.push: RewritePush(); break;

                case Opcode.pusha: RewritePusha(); break;

                case Opcode.pushf: RewritePushf(); break;

                case Opcode.pxor: RewritePxor(); break;

                case Opcode.rcl: RewriteRotation(PseudoProcedure.RolC, true, true); break;

                case Opcode.rcr: RewriteRotation(PseudoProcedure.RorC, true, false); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol, false, true); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror, false, false); break;

                case Opcode.rdtsc: RewriteRdtsc(); break;

                case Opcode.rep: RewriteRep(); break;

                case Opcode.repne: RewriteRep(); break;

                case Opcode.ret: RewriteRet(); break;

                case Opcode.retf: RewriteRet(); break;

                case Opcode.sahf: emitter.Assign(orw.FlagGroup(IntelInstruction.DefCc(instrCur.code)), orw.AluRegister(Registers.ah)); break;

                case Opcode.sar: RewriteBinOp(Operator.Sar); break;

                case Opcode.sbb: RewriteAdcSbb(BinaryOperator.ISub); break;

                case Opcode.scas: RewriteStringInstruction(); break;

                case Opcode.scasb: RewriteStringInstruction(); break;

                case Opcode.seta: RewriteSet(ConditionCode.UGT); break;

                case Opcode.setc: RewriteSet(ConditionCode.ULT); break;

                case Opcode.setbe: RewriteSet(ConditionCode.ULE); break;

                case Opcode.setg: RewriteSet(ConditionCode.GT); break;

                case Opcode.setge: RewriteSet(ConditionCode.GE); break;

                case Opcode.setl: RewriteSet(ConditionCode.LT); break;

                case Opcode.setle: RewriteSet(ConditionCode.LE); break;

                case Opcode.setnc: RewriteSet(ConditionCode.UGE); break;

                case Opcode.setns: RewriteSet(ConditionCode.NS); break;

                case Opcode.setnz: RewriteSet(ConditionCode.NE); break;

                case Opcode.seto: RewriteSet(ConditionCode.OV); break;

                case Opcode.sets: RewriteSet(ConditionCode.SG); break;

                case Opcode.setz: RewriteSet(ConditionCode.EQ); break;

                case Opcode.shl: RewriteBinOp(BinaryOperator.Shl); break;

                case Opcode.shld: RewriteShxd("__shld"); break;

                case Opcode.shr: RewriteBinOp(BinaryOperator.Shr); break;

                case Opcode.shrd: RewriteShxd("__shrd"); break;

                case Opcode.stc: RewriteSetFlag(FlagM.CF, Constant.True()); break;

                case Opcode.std: RewriteSetFlag(FlagM.DF, Constant.True()); break;

                case Opcode.sti: break; //$TODO:

                case Opcode.stos: RewriteStringInstruction(); break;

                case Opcode.stosb: RewriteStringInstruction(); break;

                case Opcode.sub: RewriteAddSub(BinaryOperator.ISub); break;

                case Opcode.test: RewriteTest(); break;

                case Opcode.wait: break;        // used to slow down FPU.

                case Opcode.xadd: RewriteXadd(); break;

                case Opcode.xchg: RewriteExchange(); break;

                case Opcode.xgetbv: RewriteXgetbv(); break;

                case Opcode.xlat: RewriteXlat(); break;

                case Opcode.xor: RewriteLogical(BinaryOperator.Xor); break;
                }
                yield return(ric);
            }
        }
Example #26
0
        public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand mem, DataType dt, X86State state)
        {
            var exp = ImportedProcedure(instr.Address, mem.Width, mem);
            if (exp != null)
                return new ProcedureConstant(arch.PointerType, exp);

            Expression expr = EffectiveAddressExpression(instr, mem, state);
            if (IsSegmentedAccessRequired ||
                (mem.DefaultSegment != Registers.ds && mem.DefaultSegment != Registers.ss))
            {
                Expression seg = ReplaceCodeSegment(mem.DefaultSegment, state);
                if (seg == null)
                    seg = AluRegister(mem.DefaultSegment);
                return new SegmentedAccess(MemoryIdentifier.GlobalMemory, seg, expr, dt);
            }
            else
            {
                return new MemoryAccess(MemoryIdentifier.GlobalMemory, expr, dt);
            }
        }
Example #27
0
 public void Execute(IntelInstruction instr)
 {
     switch (instr.code)
     {
     default:
         throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr));
     case Opcode.adc: Adc(instr.op1, instr.op2); return;
     case Opcode.add: Add(instr.op1, instr.op2); return;
     case Opcode.and: And(instr.op1, instr.op2); return;
     case Opcode.call: Call(instr.op1); return;
     case Opcode.cmp: Cmp(instr.op1, instr.op2); return;
     case Opcode.dec: Dec(instr.op1); return;
     case Opcode.hlt: running = false; return;
     case Opcode.inc: Inc(instr.op1); return;
     case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jc: if ((Flags & Cmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jmp: Jump(instr.op1); return;
     case Opcode.jnc: if ((Flags & Cmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jnz: if ((Flags & Zmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jz: if ((Flags & Zmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break;
     case Opcode.loop: Loop(instr.op1); break;
     case Opcode.mov: Write(instr.op1, Read(instr.op2)); break;
     case Opcode.or: Or(instr.op1, instr.op2); return;
     case Opcode.pop: Write(instr.op1, Pop()); return;
     case Opcode.popa: Popa(); return;
     case Opcode.push: Push(Read(instr.op1)); return;
     case Opcode.pusha: Pusha(); return;
     case Opcode.repne: Repne(); return;
     case Opcode.rol: Rol(instr.op1, instr.op2); return;
     case Opcode.scasb: Scasb(); return;
     case Opcode.shl: Shl(instr.op1, instr.op2); return;
     case Opcode.shr: Shr(instr.op1, instr.op2); return;
     case Opcode.sub: Sub(instr.op1, instr.op2); return;
     case Opcode.xor: Xor(instr.op1, instr.op2); return;
     case Opcode.xchg: Xchg(instr.op1, instr.op2); return;
     }
 }
Example #28
0
        /// <summary>
        /// Memory accesses are translated into expressions.
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public Expression EffectiveAddressExpression(IntelInstruction instr, MemoryOperand mem, X86State state)
        {
            Expression eIndex = null;
            Expression eBase = null;
            Expression expr = null;
            PrimitiveType type = PrimitiveType.CreateWord(mem.Width.Size);
            bool ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long l = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l = -l;
                        op = Operator.ISub;
                    }

                    DataType dt = (eBase != null) ? eBase.DataType : eIndex.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = new BinaryExpression(
                        Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale));
                }
                expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex);
            }
            return expr;
        }
Example #29
0
 public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand memoryOperand, X86State state)
 {
     return CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state);
 }
Example #30
0
        /// <summary>
        /// Memory accesses are translated into expressions.
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public Expression EffectiveAddressExpression(IntelInstruction instr, MemoryOperand mem, X86State state)
        {
            Expression    eIndex      = null;
            Expression    eBase       = null;
            Expression    expr        = null;
            PrimitiveType type        = PrimitiveType.CreateWord(mem.Width.Size);
            bool          ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long           l  = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l  = -l;
                        op = Operator.ISub;
                    }

                    DataType dt      = (eBase != null) ? eBase.DataType : eIndex.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = new BinaryExpression(
                        Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale));
                }
                expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex);
            }
            return(expr);
        }
Example #31
0
 public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand memoryOperand, X86State state)
 {
     return(CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state));
 }