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;
        }
Beispiel #2
0
        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));
 }
Beispiel #4
0
 /// <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));
 }