public RegisterEntry Add(string aName, uint aValue) { ArmRegister added = iEntries.Add(aName, aValue); RegisterEntry ret = added as RegisterEntry; return(ret); }
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); }
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); }
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); }
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; }
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); } }
private void TryToUpdateRegister(ArmRegister aObjectToUpdate, RegisterCollection aSource) { RegisterEntry entry = aSource[aObjectToUpdate.RegType]; if (entry != null) { aObjectToUpdate.Value = entry.Value; } }
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); }
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); } }
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); }
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)); } } }
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)); }
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); }
/// <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); }
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); }
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) { }
void IARCBackingStore.ARCBSRemove(ArmRegister aRegister) { // Nothing to do - our entries are derived from ArmRegister and // are owned by iEntries. }
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); }
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) { }