Exemple #1
0
        protected ArrayAccess PushToHWStackAccess()
        {
            var stkptr = binder.EnsureRegister(arch.StackRegister);
            var slot   = m.ARef(PrimitiveType.Ptr32, PICRegisters.GlobalStack, stkptr);

            m.Assign(stkptr, m.IAdd(stkptr, Constant.Byte(1)));
            return(slot);
        }
Exemple #2
0
        private void RewriteLoad()
        {
            var ea = Op(1);

            if (instrCur.Operands.Length == 3)
            {
                ea = m.IAdd(ea, Op(2));
            }
            var dst = Op(0);

            m.Assign(dst, m.Mem(dst.DataType, ea));
        }
Exemple #3
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var reg = op as RegisterOperand;

            if (reg != null)
            {
                return(binder.EnsureRegister(reg.Register));
            }
            var addr = op as AddressOperand;

            if (addr != null)
            {
                return(addr.Address);
            }
            var imm = op as ImmediateOperand;

            if (imm != null)
            {
                return(imm.Value);
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                Expression ea;
                if (mem.Base != null)
                {
                    ea = binder.EnsureRegister(mem.Base);
                    if (mem.Index != null)
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(
                            ea,
                            m.Cast(PrimitiveType.Int16, idx));
                    }
                    else if (mem.Offset != null)
                    {
                        ea = m.IAdd(
                            ea,
                            m.Int16((sbyte)mem.Offset.ToByte()));
                    }
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(mem.Offset);
                }
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, ea));
                return(tmp);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Exemple #4
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand iop:
                return(iop.Value);

            case AddressOperand aop:
                return(aop.Address);

            case MemoryOperand mop:
                Expression ea;
                if (mop.Base != null)
                {
                    ea = binder.EnsureRegister(mop.Base);
                    if (mop.Offset != 0)
                    {
                        ea = m.IAddS(ea, mop.Offset);
                    }
                }
                else
                {
                    ea = m.Ptr32((uint)mop.Offset);
                }
                if (mop.Index != null)
                {
                    var idx = binder.EnsureRegister(mop.Index);
                    ea = m.IAdd(ea, idx);
                }
                return(m.Mem(op.Width, ea));

            case BitOperand bit:
                var bitSrc = RewriteSrc(bit.Operand);
                return(host.Intrinsic(
                           "__bit",
                           false,
                           PrimitiveType.Bool,
                           bitSrc,
                           Constant.Byte((byte)bit.BitPosition)));

            case FlagGroupOperand fop:
                return(binder.EnsureFlagGroup(fop.FlagGroup));

            default:
                throw new NotImplementedException($"Rl87Rewriter: operand type {op.GetType().Name} not implemented yet.");
            }
        }
Exemple #5
0
        private void RewriteAdc()
        {
            var dst = RewriteOp(dasm.Current.Op1);
            var src = RewriteOp(dasm.Current.Op2);

            emitter.Assign(dst, emitter.IAdd(emitter.IAdd(dst, src), FlagGroup(FlagM.CF)));
            AssignCond(FlagM.CF | FlagM.ZF | FlagM.SF | FlagM.PF, dst);
        }
Exemple #6
0
        private Expression Mem(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                var baseReg = binder.EnsureRegister(mem.Base);
                ea = baseReg;
                if (mem.Predecrement)
                {
                    m.Assign(baseReg, m.ISubS(baseReg, mem.Width.Size));
                }
                if (mem.Offset != 0)
                {
                    ea = m.IAdd(ea, mem.Offset);
                }
                if (mem.Postincrement)
                {
                    m.Assign(baseReg, m.IAddS(baseReg, mem.Width.Size));
                }
            }
            else
            {
                ea = Address.Ptr16((ushort)mem.Offset);
            }
            return(m.Mem(mem.Width, ea));
        }
Exemple #7
0
 private Expression EffectiveAddress(MachineOperand operand, RtlEmitter emitter)
 {
     var mop = (MemoryOperand) operand;
     var reg = binder.EnsureRegister(mop.BaseRegister);
     var offset = mop.Offset;
     return emitter.IAdd(reg, offset);
 }
Exemple #8
0
        private Expression Operand(ArmInstructionOperand op)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Register:
                var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]);
                return(MaybeShiftOperand(reg, op));

            case ArmInstructionOperandType.SysRegister:
                var sysreg = frame.EnsureRegister(A32Registers.SysRegisterByCapstoneID[op.SysRegisterValue.Value]);
                return(sysreg);

            case ArmInstructionOperandType.Immediate:
                return(Constant.Word32(op.ImmediateValue.Value));

            case ArmInstructionOperandType.CImmediate:
            case ArmInstructionOperandType.PImmediate:
                return(Constant.Byte((byte)op.ImmediateValue.Value));

            case ArmInstructionOperandType.Memory:
                Expression baseReg = Reg(op.MemoryValue.BaseRegister);
                Expression ea      = baseReg;
                if (op.MemoryValue.BaseRegister
                    == ArmRegister.PC)  // PC-relative address
                {
                    if (op.MemoryValue.Displacement != 0)
                    {
                        var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u;
                        return(m.Load(SizeFromLoadStore(instr), Address.Ptr32(dst)));
                    }
                }
                if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op))
                {
                    var offset = Constant.Int32(op.MemoryValue.Displacement);
                    ea = op.MemoryValue.IndexRegisterScale < 0
                        ? m.ISub(ea, offset)
                        : m.IAdd(ea, offset);
                }
                if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack)
                {
                    m.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(m.Load(SizeFromLoadStore(instr), ea));
            }
            throw new NotImplementedException(op.Type.ToString());
        }
Exemple #9
0
        private Expression Rewrite(MachineOperand op, bool highWord = false)
        {
            var rop = op as RegisterOperand;

            if (rop != null)
            {
                if (rop.Register.Number == 31)
                {
                    return(Constant.Word64(0));
                }
                else if (rop.Register.Number == 63)
                {
                    return(Constant.Real64(0.0));
                }
                else
                {
                    return(this.binder.EnsureRegister(rop.Register));
                }
            }
            var imm = op as ImmediateOperand;

            if (imm != null)
            {
                return(imm.Value);
            }
            var addr = op as AddressOperand;

            if (addr != null)
            {
                return(addr.Address);
            }
            var mop = op as MemoryOperand;

            if (mop != null)
            {
                int        offset = highWord ? (int)mop.Offset << 16 : mop.Offset;
                Expression ea;
                if (mop.Base.Number == ZeroRegister)
                {
                    var dt = PrimitiveType.Create(Domain.Integer, arch.PointerType.Size);
                    ea = Constant.Create(dt, offset); //$TODO should be platform size.
                }
                else
                {
                    ea = binder.EnsureRegister(mop.Base);
                    if (offset > 0)
                    {
                        ea = m.IAdd(ea, offset);
                    }
                    else if (offset < 0)
                    {
                        ea = m.ISub(ea, -offset);
                    }
                }
                return(m.Mem(mop.Width, ea));
            }
            throw new NotImplementedException(string.Format("{0} ({1})", op, op.GetType().Name));
        }
Exemple #10
0
        private void Inc()
        {
            var mem = RewriteOperand(instrCur.Operands[0]);
            var tmp = binder.CreateTemporary(PrimitiveType.Byte);
            var c   = FlagGroupStorage(FlagM.NF | FlagM.ZF);

            m.Assign(tmp, m.IAdd(mem, 1));
            m.Assign(RewriteOperand(instrCur.Operands[0]), tmp);
            m.Assign(c, m.Cond(tmp));
        }
Exemple #11
0
 private Expression EffectiveAddress_r0(MachineOperand op1, MachineOperand op2)
 {
     var e1 = RewriteOperand(op1, true);
     var e2 = RewriteOperand(op2);
     if (e1.IsZero)
         return e2;
     else
         return m.IAdd(e1, e2);
 }
Exemple #12
0
        private void RewritePush()
        {
            var src = OpSrc(instr.Operand1);
            var sp  = binder.EnsureRegister(Registers.SP);

            m.Assign(sp, m.IAdd(sp, 1));
            m.Assign(m.Mem8(sp), src);
        }
Exemple #13
0
        private Expression EffectiveAddress(ArmInstructionMemoryOperandValue mem)
        {
            var baseReg = GetReg(mem.BaseRegister);
            var ea      = baseReg;

            if (mem.Displacement > 0)
            {
                ea = emitter.IAdd(ea, Constant.Int32(mem.Displacement));
            }
            else if (mem.Displacement < 0)
            {
                ea = emitter.ISub(ea, Constant.Int32(-mem.Displacement));
            }
            else if (mem.IndexRegister != ArmRegister.Invalid)
            {
                ea = emitter.IAdd(ea, GetReg(mem.IndexRegister));
            }
            return(ea);
        }
Exemple #14
0
        private Expression RewriteOperand(MachineOperand op)
        {
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                return(binder.EnsureRegister(regOp.Register));
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(immOp.Value);
            }
            var indOp = op as IndirectOperand;

            if (indOp != null)
            {
                Expression ea;
                Identifier baseReg = binder.EnsureRegister(indOp.Base);
                if (indOp.Offset == 0)
                {
                    ea = baseReg;
                }
                else if (indOp.Offset > 0)
                {
                    ea = m.IAdd(baseReg, indOp.Offset);
                }
                else
                {
                    ea = m.ISub(baseReg, -indOp.Offset);
                }
                return(m.Mem(indOp.Width, ea));
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            throw new NotImplementedException(string.Format("Rewriting of operand type {0} not implemented yet.", op.GetType().Name));
        }
Exemple #15
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand reg:
                return(binder.EnsureRegister(reg.Register));

            case AddressOperand addr:
                return(addr.Address);

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base != null)
                {
                    ea = binder.EnsureRegister(mem.Base);
                    if (mem.Index != null)
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(
                            ea,
                            m.Convert(idx, idx.DataType, PrimitiveType.Int16));
                    }
                    else if (mem.Offset != null)
                    {
                        ea = m.IAdd(
                            ea,
                            m.Int16((sbyte)mem.Offset.ToByte()));
                    }
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(mem.Offset, false);
                }
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, ea));
                return(tmp);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Exemple #16
0
        private Expression RewriteOp(int iOp)
        {
            switch (instr.Operands[iOp])
            {
            case RegisterOperand r:
                if (r.Register == arch.Registers.GpRegs[0])
                {
                    return(Constant.Zero(r.Register.DataType));
                }
                else
                {
                    return(binder.EnsureRegister(r.Register));
                }

            case ImmediateOperand i:
                return(i.Value);

            case LeftImmediateOperand l:
                return(l.Value);

            case AddressOperand a:
                return(a.Address);

            case MemoryOperand mem:
                Identifier rb = binder.EnsureRegister(mem.Base);
                Expression ea = rb;
                if (mem.Index != null)
                {
                    if (mem.Index != arch.Registers.GpRegs[0])
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(ea, idx);
                    }
                }
                else if (mem.Offset != 0)
                {
                    ea = m.IAddS(ea, mem.Offset);
                }
                if (instr.BaseReg == AddrRegMod.mb)
                {
                    m.Assign(rb, ea);
                    ea = rb;
                }
                else if (instr.BaseReg == AddrRegMod.ma)
                {
                    var tmp = binder.CreateTemporary(rb.DataType);
                    m.Assign(tmp, ea);
                    m.Assign(rb, tmp);
                    ea = tmp;
                }
                return(m.Mem(mem.Width, ea));
            }
            throw new NotImplementedException($"Unimplemented PA-RISC operand type {instr.Operands[iOp].GetType()}.");
        }
Exemple #17
0
        private void RewritePush()
        {
            var src = OpSrc(instr.Operands[0], arch.DataMemory);
            var sp  = binder.EnsureRegister(Registers.SP);

            m.Assign(sp, m.IAdd(sp, 1));
            var dataMemory = binder.EnsureRegister(arch.DataMemory);

            m.Assign(m.SegMem8(dataMemory, sp), src);
        }
Exemple #18
0
        private Expression EffectiveAddress(MemoryOperand mem)
        {
            if (mem.Base == null || mem.Base.Number == 0)
            {
                // Must be abs address.
                return(Address.Create(arch.PointerType, (uint)mem.Offset));
            }
            Expression ea = binder.EnsureRegister(mem.Base);

            if (mem.Index != null && mem.Index.Number > 0)
            {
                var idx = binder.EnsureRegister(mem.Index);
                ea = m.IAdd(ea, idx);
            }
            if (mem.Offset != 0)
            {
                var off = Constant.Int(mem.Base.DataType, mem.Offset);
                ea = m.IAdd(ea, off);
            }
            return(ea);
        }
Exemple #19
0
        private Expression RewriteDecorator(DecoratorOperand dec)
        {
            var exp = OperandSrc(dec.Operand);

            if (dec.NewValue)
            {
                //$TODO;
                return(exp);
            }
            if (dec.Inverted)
            {
                exp = m.Not(exp);
                return(exp);
            }
            if (dec.Carry)
            {
                var app = (ApplicationOperand)dec.Operand;
                var p   = binder.EnsureRegister(((RegisterOperand)app.Operands[2]).Register);
                exp = m.IAdd(exp, p);
                //$TODO: what about carry-out? it's in p.
                return(exp);
            }
            if (dec.Width.BitSize < (int)dec.Operand.Width.BitSize)
            {
                exp = m.Slice(dec.Width, exp, dec.BitOffset);
                return(exp);
            }
            throw new NotImplementedException(dec.ToString());
        }
Exemple #20
0
        private void RewriteAdd(MipsInstruction instr, PrimitiveType size)
        {
            var        opLeft  = RewriteOperand(instr.op2);
            var        opRight = RewriteOperand(instr.op3);
            Expression opSrc;

            if (opLeft.IsZero)
            {
                opSrc = opRight;
            }
            else if (opRight.IsZero)
            {
                opSrc = opLeft;
            }
            else
            {
                opSrc = emitter.IAdd(opLeft, opRight);
            }
            var opDst = RewriteOperand(instr.op1);

            emitter.Assign(opDst, opSrc);
        }
Exemple #21
0
        private void RewriteAdc()
        {
            var dst = RewriteOp(dasm.Current.Operands[0]);
            var src = RewriteOp(dasm.Current.Operands[1]);

            m.Assign(dst, m.IAdd(m.IAdd(dst, src), FlagGroup(FlagM.CF)));
            AssignCond(FlagM.CF | FlagM.ZF | FlagM.SF | FlagM.PF, dst);
        }
Exemple #22
0
        private Expression Operand(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Address != null)
                {
                    if (mem.Register != null)
                    {
                        ea = m.IAdd(
                            mem.Address,
                            m.Cast(PrimitiveType.UInt16, binder.EnsureRegister(mem.Register)));
                    }
                    else
                    {
                        ea = mem.Address;
                    }
                }
                else
                {
                    ea = RegisterPair(mem.Register);
                }
                return(m.Mem(mem.Width, ea));

            case AddressOperand addr:
                return(addr.Address);

            default:
                throw new NotImplementedException(op.GetType().Name);
            }
        }
Exemple #23
0
 private Expression EffectiveAddress_r0(MachineOperand operand, RtlEmitter emitter)
 {
     var mop = (MemoryOperand) operand;
     if (mop.BaseRegister.Number == 0)
     {
         return Constant.Word32((int) mop.Offset.ToInt16());
     }
     else
     {
         var reg = binder.EnsureRegister(mop.BaseRegister);
         var offset = mop.Offset;
         return emitter.IAdd(reg, offset);
     }
 }
Exemple #24
0
        /// <summary>
        /// Rewrites the effective address of a memory load.
        /// </summary>
        /// <param name="mem"></param>
        /// <returns></returns>
        private Expression RewriteSrcEa(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                if (mem.Increment < 0)
                {
                    throw new NotImplementedException("predec");
                }
                ea = binder.EnsureRegister(mem.Base);
                if (mem.Offset != null)
                {
                    ea = m.IAdd(ea, mem.Offset);
                }
            }
            else
            {
                ea = arch.MakeAddressFromConstant(mem.Offset, false);
            }

            return(ea);
        }
Exemple #25
0
        public void AOS_LookupA6Call()
        {
            Given_Func("#1 512 0x200 Allocate( heap/a1, size/d0)\n");

            When_Create_Platform();
            m.Call(m.IAdd(binder.EnsureRegister(Registers.a6), -512), 4);
            var state = arch.CreateProcessorState();
            var svc   = platform.FindService(rtls.Last(), state);

            Assert.AreEqual("Allocate", svc.Name);
            Assert.AreEqual(2, svc.Signature.Parameters.Length);
            Assert.AreEqual("a1", svc.Signature.Parameters[0].Storage.ToString());
            Assert.AreEqual("d0", svc.Signature.Parameters[1].Storage.ToString());
        }
Exemple #26
0
        private Expression RewriteOp(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case MemoryOperand mop:
                Expression ea = binder.EnsureRegister(mop.Base);
                if (mop.PostIncrement)
                {
                    var tmp = binder.CreateTemporary(op.Width);
                    m.Assign(tmp, m.Mem(op.Width, ea));
                    m.Assign(ea, m.IAdd(ea, m.Int16((short)op.Width.Size)));
                    return(tmp);
                }
                else if (mop.Offset != 0)
                {
                    var tmp = binder.CreateTemporary(op.Width);
                    m.Assign(tmp, m.Mem(op.Width, m.IAdd(ea, m.Int16(mop.Offset))));
                    return(tmp);
                }
                else
                {
                    var tmp = binder.CreateTemporary(op.Width);
                    m.Assign(tmp, m.Mem(op.Width, ea));
                    return(tmp);
                }

            case ImmediateOperand iop:
                return(iop.Value);

            case AddressOperand aop:
                return(aop.Address);
            }
            throw new NotImplementedException(op.ToString());
        }
Exemple #27
0
        private void RewriteAddc()
        {
            var dst  = Reg(instrCur.Operands[0]);
            var src1 = Reg0(instrCur.Operands[1]);
            var src2 = Reg0(instrCur.Operands[2]);
            var c    = binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.sr, (uint)FlagM.CY));

            m.Assign(dst, m.IAdd(m.IAdd(src1, src2), c));
            CV(dst);
        }
Exemple #28
0
 private Expression SimplifySum(Expression srcLeft, Expression srcRight)
 {
     if (srcLeft == null && srcRight == null)
     {
         return(Constant.Zero(PrimitiveType.Ptr32));
     }
     else if (srcLeft == null)
     {
         return(srcRight);
     }
     else if (srcRight == null)
     {
         return(srcLeft);
     }
     else
     {
         return(m.IAdd(srcLeft, srcRight));
     }
 }
Exemple #29
0
 private MemoryAccess RewriteMemoryOperand(MemoryOperand memop)
 {
     if (memop.Base != null)
     {
         Expression baseReg;
         if (memop.Base == Registers.pc)
         {
             baseReg = instr.Address + instr.Length;
         }
         else
         {
             baseReg = binder.EnsureRegister(memop.Base);
         }
         Expression ea = baseReg;
         if (memop.Index != null)
         {
             Expression idx = binder.EnsureRegister(memop.Index);
             if (idx.DataType.BitSize < ea.DataType.BitSize)
             {
                 idx = m.Cast(PrimitiveType.UInt16, idx);
             }
             ea = m.IAdd(baseReg, idx);
         }
         else if (memop.PreIncrement)
         {
             m.Assign(ea, m.IAddS(ea, memop.Offset.Value));
         }
         else if (memop.PostIncrement)
         {
             var tmp = binder.CreateTemporary(baseReg.DataType);
             m.Assign(tmp, ea);
             m.Assign(baseReg, m.IAddS(baseReg, memop.Offset.Value));
             ea = tmp;
         }
         else
         {
             ea = m.IAdd(baseReg, (ushort)memop.Offset.Value);
         }
         if (memop.Indirect)
         {
             ea = m.Mem(PrimitiveType.Ptr16, ea);
         }
         return(m.Mem(memop.Width, ea));
     }
     else
     {
         Debug.Assert(memop.Offset != null);
         return(m.Mem(memop.Width, Address.Ptr16((ushort)memop.Offset.Value)));
     }
 }
Exemple #30
0
        public void MacOS_ResolveIndirectCall()
        {
            var macOS = new MacOSClassic(null, new M68kArchitecture("m68k"));
            var a5    = new Identifier(Registers.a5.Name, Registers.a5.DataType, Registers.a5);

            var a5world = new MemoryArea(Address.Ptr32(0x00100000), new byte[0x0300]);

            macOS.A5World  = new ImageSegment("A5World", a5world, AccessMode.ReadWrite);
            macOS.A5Offset = 0x0100u;
            const int  jumpTableOffset = 0x0032;
            const uint uAddrDirect     = 0x00123400u;
            var        w = new BeImageWriter(a5world, macOS.A5Offset + jumpTableOffset);

            w.WriteBeUInt16(0x4EF9);        // jmp... (not really necessary for the test but hey....);
            w.WriteBeUInt32(uAddrDirect);

            var m     = new RtlEmitter(null);
            var instr = new RtlCall(m.IAdd(a5, jumpTableOffset), 4, RtlClass.Call);
            var addr  = macOS.ResolveIndirectCall(instr);

            Assert.AreEqual(uAddrDirect, addr.ToUInt32());
        }