public RegisterService(DataTarget target) { _target = target; Type contextType; switch (target.Architecture) { case Architecture.Amd64: _contextSize = AMD64Context.Size; _contextFlags = AMD64Context.ContextControl | AMD64Context.ContextInteger | AMD64Context.ContextSegments; contextType = typeof(AMD64Context); break; case Architecture.X86: _contextSize = X86Context.Size; _contextFlags = X86Context.ContextControl | X86Context.ContextInteger | X86Context.ContextSegments; contextType = typeof(X86Context); break; case Architecture.Arm64: _contextSize = Arm64Context.Size; _contextFlags = Arm64Context.ContextControl | Arm64Context.ContextInteger; contextType = typeof(Arm64Context); break; case Architecture.Arm: _contextSize = ArmContext.Size; _contextFlags = ArmContext.ContextControl | ArmContext.ContextInteger; contextType = typeof(ArmContext); break; default: throw new PlatformNotSupportedException($"Unsupported architecture: {target.Architecture}"); } var registers = new List <RegisterInfo>(); int index = 0; FieldInfo[] fields = contextType.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { RegisterAttribute registerAttribute = field.GetCustomAttributes <RegisterAttribute>(inherit: false).SingleOrDefault(); if (registerAttribute == null) { continue; } RegisterType registerType = registerAttribute.RegisterType & RegisterType.TypeMask; switch (registerType) { case RegisterType.Control: case RegisterType.General: case RegisterType.Segments: break; default: continue; } if ((registerAttribute.RegisterType & RegisterType.ProgramCounter) != 0) { InstructionPointerIndex = index; } if ((registerAttribute.RegisterType & RegisterType.StackPointer) != 0) { StackPointerIndex = index; } if ((registerAttribute.RegisterType & RegisterType.FramePointer) != 0) { FramePointerIndex = index; } FieldOffsetAttribute offsetAttribute = field.GetCustomAttributes <FieldOffsetAttribute>(inherit: false).Single(); var registerInfo = new RegisterInfo(index, offsetAttribute.Value, Marshal.SizeOf(field.FieldType), registerAttribute.Name ?? field.Name.ToLower()); registers.Add(registerInfo); index++; } _lookupByName = registers.ToDictionary((info) => info.RegisterName); _lookupByIndex = registers.ToDictionary((info) => info.RegisterIndex); Registers = registers; }
public ThreadService(IDataReader dataReader) { _dataReader = dataReader; _threadReader = (IThreadReader)dataReader; Type contextType; switch (dataReader.Architecture) { case Architecture.Amd64: // Dumps generated with newer dbgeng have bigger context buffers and clrmd requires the context size to at least be that size. _contextSize = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0x700 : AMD64Context.Size; _contextFlags = AMD64Context.ContextControl | AMD64Context.ContextInteger | AMD64Context.ContextSegments; contextType = typeof(AMD64Context); break; case Architecture.X86: _contextSize = X86Context.Size; _contextFlags = X86Context.ContextControl | X86Context.ContextInteger | X86Context.ContextSegments; contextType = typeof(X86Context); break; case Architecture.Arm64: _contextSize = Arm64Context.Size; _contextFlags = Arm64Context.ContextControl | Arm64Context.ContextInteger; contextType = typeof(Arm64Context); break; case Architecture.Arm: _contextSize = ArmContext.Size; _contextFlags = ArmContext.ContextControl | ArmContext.ContextInteger; contextType = typeof(ArmContext); break; default: throw new PlatformNotSupportedException($"Unsupported architecture: {dataReader.Architecture}"); } var registers = new List <RegisterInfo>(); int index = 0; FieldInfo[] fields = contextType.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { RegisterAttribute registerAttribute = field.GetCustomAttributes <RegisterAttribute>(inherit: false).SingleOrDefault(); if (registerAttribute == null) { continue; } RegisterType registerType = registerAttribute.RegisterType & RegisterType.TypeMask; switch (registerType) { case RegisterType.Control: case RegisterType.General: case RegisterType.Segments: break; default: continue; } if ((registerAttribute.RegisterType & RegisterType.ProgramCounter) != 0) { _instructionPointerIndex = index; } if ((registerAttribute.RegisterType & RegisterType.StackPointer) != 0) { _stackPointerIndex = index; } if ((registerAttribute.RegisterType & RegisterType.FramePointer) != 0) { _framePointerIndex = index; } FieldOffsetAttribute offsetAttribute = field.GetCustomAttributes <FieldOffsetAttribute>(inherit: false).Single(); var registerInfo = new RegisterInfo(index, offsetAttribute.Value, Marshal.SizeOf(field.FieldType), registerAttribute.Name ?? field.Name.ToLower()); registers.Add(registerInfo); index++; } _lookupByName = registers.ToDictionary((info) => info.RegisterName); _lookupByIndex = registers.ToDictionary((info) => info.RegisterIndex); _registers = registers; }
/// <summary> /// Returns the register info (name, offset, size, etc). /// </summary> /// <param name="index">register index</param> /// <param name="info">RegisterInfo</param> /// <returns>true if index found</returns> public bool GetRegisterInfo(int index, out RegisterInfo info) { return(_lookupByIndex.TryGetValue(index, out info)); }
/// <summary> /// Returns the register info (name, offset, size, etc). /// </summary> /// <param name="index">register index</param> /// <param name="info">RegisterInfo</param> /// <returns>true if index found</returns> bool IThreadService.GetRegisterInfo(int index, out RegisterInfo info) { return(_lookupByIndex.TryGetValue(index, out info)); }