Exemple #1
0
        public RegisterEntry Add(string aName, uint aValue)
        {
            ArmRegister   added = iEntries.Add(aName, aValue);
            RegisterEntry ret   = added as RegisterEntry;

            return(ret);
        }
Exemple #2
0
        private RegisterCollection AddBank(RegisterCollection.TType aType, RegisterCollection aLinkedWith, params TArmRegisterType[] aExtraRegs)
        {
            RegisterCollection bank = new RegisterCollection(CrashDebugger, aType, null, aLinkedWith);

            iBanks.Add(aType, bank);

            // Create bank specific registers
            string bankName = RegisterCollection.BankName(aType);

            if (bankName != string.Empty)
            {
                bankName = "_" + bankName;
            }

            bank.Add("R13" + bankName, 0);
            bank.Add("R14" + bankName, 0);
            bank.Add("SPSR" + bankName, 0);

            // Create custom registers
            foreach (TArmRegisterType custom in aExtraRegs)
            {
                string name = ArmRegister.GetTypeName(custom) + bankName;
                bank.Add(name, 0);
            }

            return(bank);
        }
Exemple #3
0
        public uint Process(ArmRegister aSp, DataBuffer aStackData)
        {
            uint ret = 0;

            //
            switch (Type)
            {
            case TType.EUndefined:
                throw new NotSupportedException();

            case TType.EOffsetFromSp:
                ret = UpdateUsingOffsetFromSp(aSp, aStackData);
                break;

            case TType.EOffsetFromStackTop:
                ret = UpdateUsingOffsetFromStackTop(aSp, aStackData);
                break;

            case TType.ESpPlusOffset:
                ret = UpdateUsingSpPlusOffset(aSp, aStackData);
                break;
            }
            //
            return(ret);
        }
Exemple #4
0
        private void AddRegister(ParserParagraph aPara, ParserField aField, ParserFieldName aFieldName, uint aValue)
        {
            RegisterCollection.TType type = (RegisterCollection.TType)aPara.Tag;
            string regName = aFieldName.Name;

            // USR registers are a bit tricky since they are largely shared. Only R13 and R14 are
            // really USR specific.
            if (type == RegisterCollection.TType.ETypeUser)
            {
                ArmRegister reg = new ArmRegister(regName, aValue);
                //
                switch (reg.RegType)
                {
                default:
                    type = RegisterCollection.TType.ETypeCommonBank;
                    break;

                case TArmRegisterType.EArmReg_SP:
                case TArmRegisterType.EArmReg_LR:
                    break;
                }
            }

            RegisterCollection regCollection = iInfo[type];

            regCollection.Add(regName, aValue);
        }
Exemple #5
0
        private uint UpdateUsingSpPlusOffset(ArmRegister aSp, DataBuffer aStackData)
        {
            uint sp     = aSp;
            uint offset = OffsetAsDWord;
            uint val    = offset + sp;

            return(val);
        }
 /// <summary>
 ///     Create an ARM Memory Operand Value.
 /// </summary>
 /// <param name="disassembler">
 ///     A disassembler.
 /// </param>
 /// <param name="nativeMemoryOperandValue">
 ///     A native ARM memory operand value.
 /// </param>
 internal ArmMemoryOperandValue(CapstoneDisassembler disassembler, ref NativeArmMemoryOperandValue nativeMemoryOperandValue)
 {
     this.Base         = ArmRegister.TryCreate(disassembler, nativeMemoryOperandValue.Base);
     this.Displacement = nativeMemoryOperandValue.Displacement;
     this.Index        = ArmRegister.TryCreate(disassembler, nativeMemoryOperandValue.Index);
     this.LeftShit     = nativeMemoryOperandValue.LeftShift;
     this.Scale        = nativeMemoryOperandValue.Scale;
 }
Exemple #7
0
 public void AddMany(params TArmRegisterType[] aTypes)
 {
     foreach (TArmRegisterType reg in aTypes)
     {
         string name = ArmRegister.GetTypeName(reg);
         Add(name, 0);
     }
 }
        void IARCBackingStore.ARCBSRemove(ArmRegister aRegister)
        {
            CIRegister reg = aRegister.Tag as CIRegister;

            if (reg != null)
            {
                base.RemoveChild(reg);
            }
        }
Exemple #9
0
        private void TryToUpdateRegister(ArmRegister aObjectToUpdate, RegisterCollection aSource)
        {
            RegisterEntry entry = aSource[aObjectToUpdate.RegType];

            if (entry != null)
            {
                aObjectToUpdate.Value = entry.Value;
            }
        }
Exemple #10
0
        private uint UpdateUsingOffsetFromStackTop(ArmRegister aSp, DataBuffer aStackData)
        {
            uint           stackTop  = aStackData.Last.Address + 1;
            uint           offset    = OffsetAsDWord;
            uint           fetchAddr = stackTop - offset;
            DataBufferUint val       = aStackData[fetchAddr];

            return(val);
        }
Exemple #11
0
        private uint UpdateUsingOffsetFromSp(ArmRegister aSp, DataBuffer aStackData)
        {
            uint           sp        = aSp;
            uint           offset    = OffsetAsDWord;
            uint           fetchAddr = offset + sp;
            DataBufferUint val       = aStackData[fetchAddr];

            return(val);
        }
 public CIRegister this[string aName]
 {
     get
     {
         System.Diagnostics.Debug.Assert(iCollection.Count == base.Count);
         ArmRegister reg = iCollection[aName];
         CIRegister  ret = (CIRegister)reg.Tag;
         return(ret);
     }
 }
 public CIRegister this[TArmRegisterType aType]
 {
     get
     {
         System.Diagnostics.Debug.Assert(iCollection.Count == base.Count);
         ArmRegister reg = iCollection[aType];
         System.Diagnostics.Debug.Assert(reg.Tag != null && reg.Tag is CIRegister);
         CIRegister ret = (CIRegister)reg.Tag;
         return(ret);
     }
 }
Exemple #14
0
        public ArmPrologueHelper(AccurateEngine aEngine)
        {
            iEngine = aEngine;

            // Make a new PC register, since we're going to manipulate it...
            iPC = new ArmRegister(aEngine.CPU.PC);

            // Create offsets
            iOffsetValues.AddDefaults();
            iOffsetValues.SetAll(uint.MaxValue);
        }
Exemple #15
0
 internal Vector128 <float> GetVector(ArmRegister register)
 {
     byte[] value_bytes = new byte[16];
     Interface.Checked(Interface.uc_reg_read(uc, (int)register, value_bytes));
     unsafe
     {
         fixed(byte *p = &value_bytes[0])
         {
             return(Sse.LoadVector128((float *)p));
         }
     }
 }
Exemple #16
0
 internal void SetVector(ArmRegister register, Vector128 <float> value)
 {
     byte[] value_bytes = new byte[16];
     unsafe
     {
         fixed(byte *p = &value_bytes[0])
         {
             Sse.Store((float *)p, value);
         }
     }
     Interface.Checked(Interface.uc_reg_write(uc, (int)register, value_bytes));
 }
Exemple #17
0
        private RegisterCollection GetUserContextRegisters()
        {
            bool isCurrent         = IsCurrent;
            RegisterCollection ret = new RegisterCollection(Registers, RegisterCollection.TType.ETypeUser, iParentThread.OwningProcess);

            // User-land CPSR is stored in SPSR_SVC
            RegisterEntry spsr = Registers[TArmRegisterType.EArmReg_SPSR];

            ret[TArmRegisterType.EArmReg_CPSR].Value = spsr.Value;

            // Get the context table that we'll need to work out the reg positions
            UserContextTable.UserContextTable table = CrashDebugger.UserContextTableManager[UserContextType];

            // Get SP and stack data for supervisor thread
            uint            sp     = SavedSP;
            ThreadStackData spData = iParentThread.StackInfoSupervisor.Data;

            if (spData.Info.Data.Size > 0)
            {
                // This is the user side address that will be branched back to once we exit SVC mode...
                uint retAddr = UserReturnAddress;
                ret[TArmRegisterType.EArmReg_PC].Value = retAddr;

                // Now try to get the register values off of the supervisor stack
                DataBuffer superStackData = spData.Data;
                foreach (ArmRegister reg in ret)
                {
                    if (UserContextTable.UserContextTable.IsSupported(reg.RegType))
                    {
                        UserContextTableEntry uctEntry = table[reg.RegType];
                        if (uctEntry.IsAvailable(isCurrent))
                        {
                            ArmRegister savedSp  = new ArmRegister(TArmRegisterType.EArmReg_SP, sp);
                            uint        newValue = uctEntry.Process(savedSp, superStackData);
                            reg.Value = newValue;
                        }
                    }
                }
            }

            // Getting context of current thread? Some values can be fetched directly
            // from the registers if they are not available from the stack.
            if (isCurrent && table[TArmRegisterType.EArmReg_SP].Type == UserContextTableEntry.TType.EOffsetFromSp)
            {
                RegisterCollection userRegs = CrashDebugger.InfoCpu[RegisterCollection.TType.ETypeUser];
                //
                ret[TArmRegisterType.EArmReg_SP].Value = userRegs[TArmRegisterType.EArmReg_SP];
                ret[TArmRegisterType.EArmReg_LR].Value = userRegs[TArmRegisterType.EArmReg_LR];
            }

            return(ret);
        }
        public CIRegister Add(TArmRegisterType aType, uint aValue)
        {
            // Will cause a call back to create the entries in iRegisters...
            ArmRegister entry = iCollection.Add(aType, aValue);

            //
            System.Diagnostics.Debug.Assert(entry.Tag != null && entry.Tag is CIRegister);
            System.Diagnostics.Debug.Assert(iCollection.Count == base.Count);
            //
            CIRegister ret = (CIRegister)entry.Tag;

            return(ret);
        }
        ArmRegister IARCBackingStore.ARCBSCreate(TArmRegisterType aType, string aName, uint aValue)
        {
            // Go via factory to deal with special registers...
            CIRegister reg = Factory.CIRegisterFactory.New(aType, aValue, aName, this);

            base.AddChild(reg);

            // Set up two-way association
            ArmRegister ret = reg.Register;

            ret.Tag = reg;
            return(ret);
        }
Exemple #20
0
        /// <summary>
        ///     Create an ARM Register.
        /// </summary>
        /// <param name="disassembler">
        ///     A disassembler.
        /// </param>
        /// <param name="id">
        ///     The register's unique identifier.
        /// </param>
        /// <returns>
        ///     An ARM register.
        /// </returns>
        /// <exception cref="System.ObjectDisposedException">
        ///     Thrown if the disassembler is disposed.
        /// </exception>
        internal static ArmRegister TryCreate(CapstoneDisassembler disassembler, ArmRegisterId id)
        {
            ArmRegister @object = null;

            if (id != ArmRegisterId.Invalid)
            {
                // ...
                //
                // Throws an exception if the operation fails.
                var name = NativeCapstone.GetRegisterName(disassembler.Handle, (int)id);

                @object = new ArmRegister(id, name);
            }

            return(@object);
        }
        private void PrintInitialInfo()
        {
            ArmRegister sp = CPU[TArmRegisterType.EArmReg_SP];
            //
            ArmRegister lr       = CPU[TArmRegisterType.EArmReg_LR];
            string      lrSymbol = SymbolViewText[lr];
            //
            ArmRegister pc       = CPU[TArmRegisterType.EArmReg_PC];
            string      pcSymbol = SymbolViewText[pc];
            //
            ArmRegister cpsr = CPU[TArmRegisterType.EArmReg_CPSR];

            //
            Trace(System.Environment.NewLine);
            Trace(string.Format("[{5:d2}] SP: 0x{0:x8}, LR: 0x{1:x8} [{2}], PC: 0x{3:x8} [{4}], isThumb: {6}", sp.Value, lr.Value, lrSymbol, pc.Value, pcSymbol, iIterationNumber, CPU.CurrentProcessorMode == TArmInstructionSet.ETHUMB));
        }
        public CIRegister(CIRegisterList aList, TArmRegisterType aType, string aName, uint aValue)
            : base(aList.Container)
        {
            iList = aList;

            // Create register and observe when it changes value
            iRegister     = new ArmRegister(aType, aName, aValue);
            iRegister.Tag = this;

            // Prepare non-resolved symbol. I.e. this saves the address
            // but doesn't actually do any symbolic look up at this stage.
            ICISymbolManager symbolManager = this.SymbolManager;
            CISymbol         symbol        = symbolManager.SymbolDictionary.Register(iRegister.Value);

            base.AddChild(symbol);
        }
Exemple #23
0
        private bool AddLRAndPC()
        {
            bool addedLRandPC = false;
            //
            ArmRegisterCollection regs = base.Engine.Registers;

            // If we're inside the stack address range, then poke in the PC and LR values
            if (regs.Count > 0)
            {
                // Working bottom up, so LR should go on the stack first
                if (regs.Contains(TArmRegisterType.EArmReg_LR))
                {
                    ArmRegister regLR = regs[TArmRegisterType.EArmReg_LR];

                    StackOutputEntry entryLR = new StackOutputEntry(0, regLR.Value, base.DebugEngineView);
                    entryLR.IsRegisterBasedEntry       = true;
                    entryLR.IsOutsideCurrentStackRange = true;
                    entryLR.AssociatedRegister         = regLR.RegType;
                    EmitElement(entryLR);
                }

                // Then the PC...
                if (regs.Contains(TArmRegisterType.EArmReg_PC))
                {
                    ArmRegister regPC = regs[TArmRegisterType.EArmReg_PC];

                    StackOutputEntry entryPC = new StackOutputEntry(0, regPC.Value, base.DebugEngineView);
                    entryPC.IsRegisterBasedEntry       = true;
                    entryPC.IsOutsideCurrentStackRange = true;
                    entryPC.AssociatedRegister         = regPC.RegType;
                    EmitElement(entryPC);
                }

                // Even if they weren't added, we at least attempted to addd them
                addedLRandPC = true;
            }

            return(addedLRandPC);
        }
Exemple #24
0
 private Expression GetReg(ArmRegister armRegister)
 {
     return(frame.EnsureRegister(A32Registers.RegisterByCapstoneID[armRegister]));
 }
 internal RegisterEntryCPSR(RegisterCollection aParent, uint aValue)
     : base(aParent, ArmRegister.GetTypeName(TArmRegisterType.EArmReg_CPSR), aValue)
 {
 }
Exemple #26
0
 void IARCBackingStore.ARCBSRemove(ArmRegister aRegister)
 {
     // Nothing to do - our entries are derived from ArmRegister and
     // are owned by iEntries.
 }
Exemple #27
0
 private Identifier Reg(ArmRegister reg)
 {
     return(frame.EnsureRegister(A32Registers.RegisterByCapstoneID[reg]));
 }
        public bool Process()
        {
            // We need SP, LR, PC, CPSR
            CheckRequiredRegistersAvailable();

            // Debug info
            PrintInitialInfo();

            // Make initial stack frames for seed registers
            MakeInitialSeedStackFramesFromRegisterValues();

            // Get sp
            ArmRegister sp             = CPU[TArmRegisterType.EArmReg_SP];
            uint        initialSPValue = sp.Value;

            // Create Prologue object that will establish the instructions for the
            // function and also identify operations that might affect SP and LR.
            ArmPrologueHelper Prologue = new ArmPrologueHelper(this);

            Prologue.Build();

            // Create a new stack frame for this function call
            ArmStackFrame stackFrame = new ArmStackFrame(Prologue);

            // We save the stack address which contained the popped link register
            // during the previous cycle. If possible, use that value. If it
            // hasn't been set, then assume we obtained the link register from the
            // previous 4 bytes of stack (according to the current value of SP).
            long stackAddressAssociatedWithCurrentFrame = iLastLinkRegisterStackAddress;

            if (stackAddressAssociatedWithCurrentFrame == KLinkRegisterWasNotPushedOnStack)
            {
                // We're always four bytes behind the current SP
                stackAddressAssociatedWithCurrentFrame = sp - 4;
            }
            stackFrame.Address = (uint)stackAddressAssociatedWithCurrentFrame;
            stackFrame.Data    = iStackInterface.StackValueAtAddress(stackFrame.Address);

            Trace("Creating Stack Frame [" + stackFrame.Address.ToString("x8") + "] = 0x" + stackFrame.Data.ToString("x8") + " = " + SymbolString(stackFrame.Data));

            // Can now adjust stack pointer based upon the number of stack-adjusting
            // instructions during the Prologue phase.
            uint stackAdjustment = (uint)(Prologue.NumberOfWordsPushedOnStack * 4);

            sp.Value += stackAdjustment;
            Trace("stack adjusted by: 0x" + stackAdjustment.ToString("x8"));

            // We're hoping that the link register was pushed on the stack somewhere
            // during the function preamble. If that was the case, then as we processed
            // each instruction, we'll have updated the register offsets so that we know
            // the offset to the link register from the perspective of the starting stack
            // address for the function.
            uint lrOffsetInWords = Prologue.OffsetValues[TArmRegisterType.EArmReg_LR];

            Trace(string.Format("LR offset on stack is: 0x{0:x8}", lrOffsetInWords * 4));
            GetNewLRValue(lrOffsetInWords, Prologue);

            // Update the PC to point to the new function address (which we obtain
            // from LR)
            uint oldPCValue = CPU.PC;

            ChangePCToLRAddress();
            uint newPCValue = CPU.PC;

            Trace(string.Format("oldPCValue: 0x{0:x8}, newPCValue: 0x{1:x8}, fn: {2}", oldPCValue, newPCValue, SymbolViewText[newPCValue]));

            // Decide if we are in thumb or ARM mode after switching functions
            UpdateInstructionSet(newPCValue);

            // Return true if we moved to a new function
            bool gotNewFunction = (oldPCValue != CPU.PC);

            Trace("gotNewFunction: " + gotNewFunction);

            // Save stack frame
            SaveStackFrames(stackFrame);

            // Increment iteration
            ++iIterationNumber;

            // Do we have more to do?
            bool moreToDo = gotNewFunction && (CPU.PC > 0);

            // Done
            Trace("moreToDo: " + moreToDo);
            return(moreToDo);
        }
Exemple #29
0
 public uint this[ArmRegister register] {
     get => (uint)this[(int)register];
 public CIRegister(CIRegisterList aList, TArmRegisterType aType, uint aValue)
     : this(aList, aType, ArmRegister.GetTypeName(aType), aValue)
 {
 }