Example #1
0
        private void WriteShift(ArmInstructionOperand op, MachineInstructionWriter writer)
        {
            switch (op.Shifter.Type)
            {
            case ArmShifterType.ASR: WriteImmShift("asr", op.Shifter.Value, writer); break;

            case ArmShifterType.LSL: WriteImmShift("lsl", op.Shifter.Value, writer); break;

            case ArmShifterType.LSR: WriteImmShift("lsr", op.Shifter.Value, writer); break;

            case ArmShifterType.ROR: WriteImmShift("ror", op.Shifter.Value, writer); break;

            case ArmShifterType.RRX: writer.Write(",rrx"); break;

            case ArmShifterType.ASR_REG: WriteRegShift("asr", op.Shifter.Value, writer); break;

            case ArmShifterType.LSL_REG: WriteRegShift("lsl", op.Shifter.Value, writer); break;

            case ArmShifterType.LSR_REG: WriteRegShift("lsr", op.Shifter.Value, writer); break;

            case ArmShifterType.ROR_REG: WriteRegShift("ror", op.Shifter.Value, writer); break;

            case ArmShifterType.RRX_REG: WriteRegShift("rrx", op.Shifter.Value, writer); break;

            case ArmShifterType.Invalid: break;
            }
        }
Example #2
0
        private Expression RewriteOp(ArmInstructionOperand op, DataType accessSize = null)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Register:
                return(GetReg(op.RegisterValue.Value));

            case ArmInstructionOperandType.Immediate:
                if (accessSize != null)
                {
                    return(Constant.Create(accessSize, op.ImmediateValue.Value));
                }
                else
                {
                    return(Constant.Int32(op.ImmediateValue.Value));
                }

            case ArmInstructionOperandType.Memory:
                var mem = op.MemoryValue;
                var ea  = EffectiveAddress(mem);
                return(emitter.Load(accessSize, ea));

            default:
                throw new NotImplementedException(op.Type.ToString());
            }
        }
Example #3
0
        private void MaybePostOperand(ArmInstructionOperand op)
        {
            if (instrs.Current.IsLastOperand(op))
            {
                return;
            }
            if (op.Type != ArmInstructionOperandType.Memory)
            {
                return;
            }
            var        lastOp  = instr.ArchitectureDetail.Operands[instr.ArchitectureDetail.Operands.Length - 1];
            Expression baseReg = Reg(op.MemoryValue.BaseRegister);
            var        offset  = Operand(lastOp);
            var        ea      = lastOp.IsSubtracted
                ? emitter.ISub(baseReg, offset)
                : emitter.IAdd(baseReg, offset);

            emitter.Assign(baseReg, ea);
#if NYI
            if (memOp == null || memOp.Offset == null)
            {
                return;
            }
            if (memOp.Preindexed)
            {
                return;
            }
            Expression baseReg = frame.EnsureRegister(memOp.Base);
            var        offset  = Operand(memOp.Offset);
            var        ea      = memOp.Subtract
                ? emitter.ISub(baseReg, offset)
                : emitter.IAdd(baseReg, offset);
            emitter.Assign(baseReg, ea);
#endif
        }
Example #4
0
        private Expression MaybeShiftOperand(Expression exp, ArmInstructionOperand op)
        {
            switch (op.Shifter.Type)
            {
            case ArmShifterType.ASR: return(emitter.Sar(exp, op.Shifter.Value));

            case ArmShifterType.LSL: return(emitter.Shl(exp, op.Shifter.Value));

            case ArmShifterType.LSR: return(emitter.Shr(exp, op.Shifter.Value));

            case ArmShifterType.ROR: return(host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, exp, Constant.Int32(op.Shifter.Value)));

            case ArmShifterType.RRX: return(host.PseudoProcedure("rrx", PrimitiveType.Word32, exp, Constant.Int32(op.Shifter.Value)));

            case ArmShifterType.ASR_REG: return(emitter.Sar(exp, Reg(op.Shifter.Value)));

            case ArmShifterType.LSL_REG: return(emitter.Shl(exp, Reg(op.Shifter.Value)));

            case ArmShifterType.LSR_REG: return(emitter.Shr(exp, Reg(op.Shifter.Value)));

            case ArmShifterType.ROR_REG: return(host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, exp, Reg(op.Shifter.Value)));

            case ArmShifterType.RRX_REG: return(host.PseudoProcedure("rrx", PrimitiveType.Word32, exp, Reg(op.Shifter.Value)));

            default: return(exp);
            }
        }
Example #5
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
                {
                    var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u;
                    ea = Address.Ptr32(dst);
                    if (op.MemoryValue.IndexRegister != ArmRegister.Invalid)
                    {
                        var ireg = Reg(op.MemoryValue.IndexRegister);
                        if (op.Shifter.Type == ArmShifterType.LSL)
                        {
                            ea = m.IAdd(ea, m.IMul(ireg, 1 << op.Shifter.Value));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                    return(m.Mem(SizeFromLoadStore(instr), ea));
                }
                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.Mem(SizeFromLoadStore(instr), ea));

            case ArmInstructionOperandType.FloatingPoint:
                return(Constant.Real64(op.FloatingPointValue.Value));
            }
            throw new NotImplementedException(op.Type.ToString());
        }
Example #6
0
        private void WriteMemoryOperand(ArmInstructionOperand op, MachineInstructionWriter writer)
        {
            writer.Write('[');
            writer.Write(A32Registers.RegisterByCapstoneID[op.MemoryValue.BaseRegister].Name);
            int displacement = op.MemoryValue.Displacement;

            if (displacement != 0)
            {
                if (true) // preincInternal.ArchitectureDetail)
                {
                    writer.Write(",");
                    if (displacement < 0)
                    {
                        displacement = -displacement;
                        writer.Write("-");
                    }
                    writer.Write("#");
                    WriteImmediateValue(displacement, writer);
                    writer.Write("]");
                    if (instruction.ArchitectureDetail.WriteBack)
                    {
                        writer.Write("!");
                    }
                }
                else
                {
                    writer.Write("],");
                    if (displacement < 0)
                    {
                        displacement = -displacement;
                        writer.Write("-");
                    }
                    WriteImmediateValue(displacement, writer);
                }
            }
            else
            {
                if (op.MemoryValue.IndexRegister != ArmRegister.Invalid)
                {
                    writer.Write(",");
                    // NOTE: capstone.NET seems to reverse the sense of this scale parameter.
                    if (op.IsSubtracted)
                    {
                        writer.Write("-");
                    }
                    writer.Write(A32Registers.RegisterByCapstoneID[op.MemoryValue.IndexRegister].Name);
                }
                if (op.Shifter.Type != ArmShifterType.Invalid)
                {
                    WriteShift(op, writer);
                }
                writer.Write(']');
                if (instruction.ArchitectureDetail.WriteBack && IsLastOperand(op))
                {
                    writer.Write("!");
                }
            }
        }
Example #7
0
        public void Write(ArmInstructionOperand op, MachineInstructionWriter writer)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Immediate:
                if (instruction.Id == Opcode.B ||
                    instruction.Id == Opcode.BL ||
                    instruction.Id == Opcode.BLX)
                {
                    writer.Write("$");
                    writer.WriteAddress(
                        string.Format("{0:X8}", op.ImmediateValue.Value),
                        Address.Ptr32((uint)op.ImmediateValue.Value));
                    break;
                }
                writer.Write("#");
                WriteImmediateValue(op.ImmediateValue.Value, writer);
                break;

            case ArmInstructionOperandType.CImmediate:
                writer.Write("c{0}", op.ImmediateValue);
                break;

            case ArmInstructionOperandType.PImmediate:
                writer.Write("p{0}", op.ImmediateValue);
                break;

            case ArmInstructionOperandType.Register:
                if (op.IsSubtracted)
                {
                    writer.Write('-');
                }
                writer.Write(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value].Name);
                WriteShift(op, writer);
                break;

            case ArmInstructionOperandType.SysRegister:
                writer.Write(A32Registers.SysRegisterByCapstoneID[op.SysRegisterValue.Value].Name);
                break;

            case ArmInstructionOperandType.Memory:
                WriteMemoryOperand(op, writer);
                break;

            case ArmInstructionOperandType.SetEnd:
                writer.Write(op.SetEndValue.ToString().ToLowerInvariant());
                break;

            default:
                throw new NotImplementedException(string.Format(
                                                      "Can't disasseble {0} {1}. Unknown operand type: {2}",
                                                      instruction.Mnemonic,
                                                      instruction.Operand,
                                                      op.Type));
            }
        }
Example #8
0
        /// <summary>
        ///     Create an ARM Instruction Operand.
        /// </summary>
        /// <param name="this">
        ///     A native ARM instruction operand.
        /// </param>
        /// <returns>
        ///     An ARM instruction operand.
        /// </returns>
        public static ArmInstructionOperand AsArmInstructionOperand(this NativeArmInstructionOperand @this)
        {
            var @object = new ArmInstructionOperand();

            @object.IsSubtracted = @this.IsSubtracted;
            @object.Shifter      = @this.Shifter.AsArmShifter();
            @object.Type         = (ArmInstructionOperandType)@this.Type;
            @object.VectorIndex  = @this.VectorIndex;

            // Set Values.
            //
            // ...
            switch (@object.Type)
            {
            case ArmInstructionOperandType.CImmediate:
                @object.ImmediateValue = @this.Value.Immediate;

                break;

            case ArmInstructionOperandType.FloatingPoint:
                @object.FloatingPointValue = @this.Value.FloatingPoint;
                break;

            case ArmInstructionOperandType.Immediate:
                @object.ImmediateValue = @this.Value.Immediate;

                break;

            case ArmInstructionOperandType.Memory:
                @object.MemoryValue = @this.Value.Memory.AsArmInstructionMemoryOperandValue();

                break;

            case ArmInstructionOperandType.PImmediate:
                @object.ImmediateValue = @this.Value.Immediate;

                break;

            case ArmInstructionOperandType.Register:
                @object.RegisterValue = (ArmRegister)@this.Value.Register;

                break;

            case ArmInstructionOperandType.SetEnd:
                @object.SetEndValue = (ArmSetEndInstructionOperandType)@this.Value.SetEnd;

                break;

            case ArmInstructionOperandType.SysRegister:
                @object.SysRegisterValue = (ArmSysRegister)@this.Value.Register;

                break;
            }

            return(@object);
        }
        /// <summary>
        ///     Create an ARM Instruction Operand.
        /// </summary>
        /// <param name="this">
        ///     A native ARM instruction operand.
        /// </param>
        /// <returns>
        ///     An ARM instruction operand.
        /// </returns>
        public static ArmInstructionOperand AsArmInstructionOperand(this NativeArmInstructionOperand @this)
        {
            var @object = new ArmInstructionOperand();
            @object.IsSubtracted = @this.IsSubtracted;
            @object.Shifter = @this.Shifter.AsArmShifter();
            @object.Type = (ArmInstructionOperandType) @this.Type;
            @object.VectorIndex = @this.VectorIndex;

            // Set Values.
            //
            // ...
            switch (@object.Type) {
                case ArmInstructionOperandType.CImmediate:
                    @object.ImmediateValue = @this.Value.Immediate;

                    break;
                case ArmInstructionOperandType.FloatingPoint:
                    @object.FloatingPointValue = @this.Value.FloatingPoint;
                    break;
                case ArmInstructionOperandType.Immediate:
                    @object.ImmediateValue = @this.Value.Immediate;

                    break;
                case ArmInstructionOperandType.Memory:
                    @object.MemoryValue = @this.Value.Memory.AsArmInstructionMemoryOperandValue();

                    break;
                case ArmInstructionOperandType.PImmediate:
                    @object.ImmediateValue = @this.Value.Immediate;

                    break;
                case ArmInstructionOperandType.Register:
                    @object.RegisterValue = (ArmRegister) @this.Value.Register;

                    break;
                case ArmInstructionOperandType.SetEnd:
                    @object.SetEndValue = (ArmSetEndInstructionOperandType) @this.Value.SetEnd;

                    break;
                case ArmInstructionOperandType.SysRegister:
                    @object.SysRegisterValue = (ArmSysRegister) @this.Value.Register;

                    break;
            }

            return @object;
        }
Example #10
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.Immediate:
                return(Constant.Word32(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(emitter.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
                        ? emitter.ISub(ea, offset)
                        : emitter.IAdd(ea, offset);
                }
                if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack)
                {
                    emitter.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(emitter.Load(SizeFromLoadStore(instr), ea));
            }
            throw new NotImplementedException(op.Type.ToString());
        }
Example #11
0
        /// <summary>
        /// Returns true if <paramref name="op"/> is the last operand of the instruction.
        /// </summary>
        /// <param name="op"></param>
        /// <returns></returns>
        public bool IsLastOperand(ArmInstructionOperand op)
        {
            var ops = instruction.ArchitectureDetail.Operands;

            return(op == ops[ops.Length - 1]);
        }
Example #12
0
        public void Write(ArmInstructionOperand op, MachineInstructionWriter writer, MachineInstructionWriterOptions options)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Immediate:
                if (instruction.Id == Opcode.B ||
                    instruction.Id == Opcode.BL ||
                    instruction.Id == Opcode.BLX)
                {
                    writer.Write("$");
                    writer.WriteAddress(
                        string.Format("{0:X8}", op.ImmediateValue.Value),
                        Address.Ptr32((uint)op.ImmediateValue.Value));
                    break;
                }
                writer.Write("#");
                WriteImmediateValue(op.ImmediateValue.Value, writer);
                break;

            case ArmInstructionOperandType.CImmediate:
                writer.Write("c{0}", op.ImmediateValue);
                break;

            case ArmInstructionOperandType.PImmediate:
                writer.Write("p{0}", op.ImmediateValue);
                break;

            case ArmInstructionOperandType.Register:
                if (op.IsSubtracted)
                {
                    writer.Write('-');
                }
                writer.Write(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value].Name);
                WriteShift(op, writer);
                break;

            case ArmInstructionOperandType.SysRegister:
                writer.Write(A32Registers.SysRegisterByCapstoneID[op.SysRegisterValue.Value].Name);
                break;

            case ArmInstructionOperandType.Memory:
                if (op.MemoryValue.BaseRegister == ArmRegister.PC)
                {
                    var uAddr = (uint)((int)this.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u;
                    var addr  = Address.Ptr32(uAddr);
                    if (op.MemoryValue.IndexRegister == ArmRegister.Invalid &&
                        (options & MachineInstructionWriterOptions.ResolvePcRelativeAddress) != 0)
                    {
                        writer.Write('[');
                        writer.WriteAddress(addr.ToString(), addr);
                        writer.Write(']');
                        var sr = new StringRenderer();
                        WriteMemoryOperand(op, sr);
                        writer.AddAnnotation(sr.ToString());
                    }
                    else
                    {
                        WriteMemoryOperand(op, writer);
                        writer.AddAnnotation(addr.ToString());
                    }
                    return;
                }
                WriteMemoryOperand(op, writer);
                break;

            case ArmInstructionOperandType.SetEnd:
                writer.Write(op.SetEndValue.ToString().ToLowerInvariant());
                break;

            case ArmInstructionOperandType.FloatingPoint:
                var f = op.FloatingPointValue.Value.ToString("g", CultureInfo.InvariantCulture);
                if (f.IndexOfAny(nosuffixRequired) < 0)
                {
                    f += ".0";
                }
                writer.Write("#{0}", f);
                break;

            default:
                throw new NotImplementedException(string.Format(
                                                      "Can't disassemble {0} {1}. Unknown operand type: {2}",
                                                      instruction.Mnemonic,
                                                      instruction.Operand,
                                                      op.Type));
            }
        }