public static object GetSimpleValue(ulong objAddress, ClrType clrType, bool isInterior=false) { if (objAddress == 0) throw new NullReferenceException("ClrObject at is pointing to null address."); ClrHeap heap = clrType.Heap; if (clrType.IsEnum) { var val = clrType.GetValue(objAddress); return clrType.GetEnumName(val); } if (clrType.IsPrimitive || clrType.IsString) return clrType.GetValue(objAddress); ulong address = isInterior ? objAddress : objAddress + (ulong)heap.PointerSize; switch (clrType.Name) { case GuidTypeName: { byte[] buffer = ReadBuffer(heap, address, 16); return new Guid(buffer); } case TimeSpanTypeName: { byte[] buffer = ReadBuffer(heap, address, 8); long ticks = BitConverter.ToInt64(buffer, 0); return new TimeSpan(ticks); } case DateTimeTypeName: { byte[] buffer = ReadBuffer(heap, address, 8); ulong dateData = BitConverter.ToUInt64(buffer, 0); return GetDateTime(dateData); } case IPAddressTypeName: { return GetIPAddress(new ClrObject(objAddress, clrType, isInterior)); } } throw new InvalidOperationException(string.Format("SimpleValue not available for type '{0}'", clrType.Name)); }
public static object GetValue(ClrType type, ulong address) { if (type.IsPrimitive && type.HasSimpleValue) return type.GetValue(address); if (type.IsObjectReference) { if (type.IsString) return ReadString(type, address); return new MemoryAddress(address); } // TODO: Handle structs return "<Struct>"; }
private List<ClrObjectModel> GetValues(ulong obj, ClrType type, string baseName, int offset, bool inner, List<ClrObjectModel> values) { if (type.Name == "System.String") { object value; try { value = type.GetValue(obj); } catch (Exception ex) { value = ex.Message; } values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, TypeName = type.Name, Value = value }); values.AddRange(type.Fields.Select(field => new ClrObjectModel { Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = field.GetValue(obj, inner).ToString() })); } else if (type.IsArray) { int len = type.GetArrayLength(obj); if (type.ComponentType == null) { try { for (int i = 0; i < len; i++) values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i) }); } catch{ } } else if (type.ComponentType.HasSimpleValue) { for (int i = 0; i < len; i++) values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i) }); } else { for (int i = 0; i < len; i++) { ulong arrAddress = type.GetArrayElementAddress(obj, i); foreach (var field in type.ComponentType.Fields) { string value; if (field.HasSimpleValue) value = field.GetValue(arrAddress, inner).ToString(); // an embedded struct else value = field.GetAddress(arrAddress, inner).ToString(); values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = value }); if (field.ElementType == ClrElementType.Struct) values.AddRange(GetValues(arrAddress, field.Type, baseName + field.Name, offset + field.Offset, true, new List<ClrObjectModel>())); } } } } else { foreach (var field in type.Fields) { ulong addr = field.GetAddress(obj, inner); object value; if (field.HasSimpleValue) try { value = field.GetValue(obj, inner); } catch (Exception) { value = "{Unknown}"; } else value = addr; string sValue = value?.ToString() ?? "{Null}"; values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = sValue }); if (field.ElementType == ClrElementType.Struct) values.AddRange(GetValues(addr, field.Type, baseName + field.Name, offset + field.Offset, true, new List<ClrObjectModel>())); } } return values; }