public T Create() { var obj = MemoryObjectFactory.UnsafeCreate(typeof(T), Dump._memory, Address); obj.SetSnapshot(Dump._buffer, BufferOffset, TypeHelper <T> .SizeOf); return((T)(object)obj); }
public static T Cast <T>(this UXControl control) where T : UXControl { if (!GetVTables(typeof(T)).Contains(control.x000_VTable)) { throw new InvalidCastException(); } return(MemoryObjectFactory.Create <T>(control.Memory.Reader, control.Address)); }
private static UXControl GetControlFromPointer(Ptr ptr) { if (ptr == null) { return(null); } var vtable = ptr.Cast <int>().Dereference(); var type = GetControlTypeFromVTable(vtable); return((UXControl)MemoryObjectFactory.UnsafeCreate(type, ptr.Memory.Reader, ptr.ValueAddress)); }
public static IEnumerable Enumerate(Type type, bool allowSubClasses = false) { if (!typeof(UXControl).IsAssignableFrom(type)) { throw new ArgumentException("Invalid type."); } var vtable = (int)type.GetField("VTable").GetRawConstantValue(); var map = GetUIMap(); if (map == null) { yield break; // Enumerable.Empty<UIControl>(); } foreach (var entry in map) { if (entry.x10_PtrComponent.ValueAddress != 0) { var ctrl_vtable = entry.x10_PtrComponent.Cast <UXControl>().Dereference().x000_VTable; var ctrl_type = GetControlTypeFromVTable(ctrl_vtable); if (ctrl_type == null) { continue; } if (ctrl_type == type || (allowSubClasses && ctrl_type.IsSubclassOf(type))) { var control = entry.x10_PtrComponent.Cast <UXControl>().Dereference(); if (control.x020_Self.x000_Hash == entry.x08_Hash) { yield return(MemoryObjectFactory.UnsafeCreate(type, entry.Memory, entry.x10_PtrComponent.ValueAddress)); } else { ; } } } } }
protected override object CreateContent() { if (ContextMenuItems == null) { ContextMenuItems = new MenuItem[1]; ContextMenuItems[0] = new MenuItem { Header = "Generate Class" }; ContextMenuItems[0].Click += (s, e) => { var memoryObjectContext = Context as MemoryObject; if (memoryObjectContext != null) { MemoryObjectClassGenerator.GenerateClass(memoryObjectContext); } }; } var root = new ScrollViewer(); var panel = new StackPanel(); root.Content = panel; //panel.Children.Add(new TextBox { IsReadOnly = true, Text = "Type: " + Context.GetType().FullName }); panel.Children.Add(new Label { Header = "Type", Content = Context.GetType().FullName }); if (Context is MemoryObject) { //panel.Children.Add(Dynamic(new TextBox() { IsReadOnly = true }, a => { a.Text = "Address: 0x" + ((MemoryObject)Context).Address.ToString("X8"); })); panel.Children.Add(Dynamic(new Label { Header = "Address" }, a => a.Content = (Context as MemoryObject).Address.ToString())); } else { panel.Children.Add(new Label { Content = Context.ToString() }); } var props = Context.GetType().GetProperties(); foreach (var prop in props) { var propName = prop.Name.TrimStart('_'); string prefix; if (!propName.StartsWith("x")) { if (!_skipOffsetCheck) { continue; } prefix = propName; } else { var index = propName.IndexOf('_'); var offset = "[0x" + (index == -1 ? propName.Substring(1) : propName.Substring(1, index - 1)) + "]"; var name = index == -1 ? "???" : propName.Substring(index + 1); prefix = offset + " " + name; } Func <object, int, string> transform = null; if (prop.PropertyType == typeof(int) || prop.PropertyType == typeof(uint)) { transform = (value, address) => { var i32 = Convert.ToInt32(value); var i32text = (i32 > 0x00800000 || i32 < -0x00800000) ? "0x" + i32.ToString("X8") : i32.ToString(); if (i32 > 0x00800000 || i32 < -0x00800000) { i32text += " (float: " + BitConverter.ToSingle(BitConverter.GetBytes(i32), 0) + ")"; i32text += " (ascii: " + Encoding.ASCII.GetString(BitConverter.GetBytes(i32)) + ")"; } //if (App.SnoDiskEntries.ContainsKey(i32)) // i32text += " (" + App.SnoDiskEntries[i32].Type.ToString() + ": " + App.SnoDiskEntries[i32].Name + ")"; if (i32 == 0x600DF00D) { i32text += " (GOODFOOD)"; if (address != 0) { var mem = (Context as MemoryObject).Memory; var back8 = mem.Reader.Read <int>(address - 8); if ((back8 & 0x20200) == 0x20200) { i32text += " (" + MemoryObjectFactory.Create <Allocator>(mem.Reader, address - Allocator.SizeOf + 4).ToString() + ")"; } else { var back12 = mem.Reader.Read <int>(address - 12); if ((back12 & 0x20200) == 0x20200) { i32text += " (" + MemoryObjectFactory.Create <BasicAllocator>(mem.Reader, address - BasicAllocator.SizeOf + 4).ToString() + ")"; } } } } if (i32 == unchecked ((int)0xFEEDFACE)) { i32text += " (FEEDFACE)"; } return(i32text); }; } else if (prop.PropertyType == typeof(long)) { transform = (value, address) => { var i64 = Convert.ToInt64(value); return((i64 > 0x00800000 || i64 < -0x00800000) ? "0x" + i64.ToString("X8") : i64.ToString()); }; } else if (prop.PropertyType == typeof(ulong)) { transform = (value, address) => { var ui64 = Convert.ToUInt64(value); return((ui64 > 0x00800000) ? "0x" + ui64.ToString("X8") : ui64.ToString()); }; } int baseAddress = Context is MemoryObject ? (int)(Context as MemoryObject).Address : 0; //panel.Children.Add(Dynamic(new TextBox() { IsReadOnly = true }, a => panel.Children.Add(Dynamic(new Label(), a => { var value = prop.GetValue(Context); var propOffset = GetOffsetFromPropertyName(prop.Name); var address = propOffset == -1 ? 0 : baseAddress + propOffset; if (transform != null) { value = transform(value, address); } a.Header = prefix; a.Content = (value ?? "null").ToString(); a.ToolTip = "Address: 0x" + address.ToString("X8"); })); } if (_includeFields) { foreach (var field in Context.GetType().GetFields()) { panel.Children.Add(Dynamic(new Label(), a => { var value = field.GetValue(Context); a.Header = field.Name; a.Content = (value ?? "null").ToString(); })); } } return(root); }
public void Update() { Container.TakeSnapshot(); if (PreviousData.Length != CurrentData.Length) { Array.Resize(ref PreviousData, CurrentData.Length); } Buffer.BlockCopy(CurrentData, 0, PreviousData, 0, CurrentData.Length); Container.GetAllocatedBytes(ref CurrentData); if (PreviousMapping.Length != CurrentMapping.Length) { Array.Resize(ref PreviousMapping, CurrentMapping.Length); } Buffer.BlockCopy(CurrentMapping, 0, PreviousMapping, 0, CurrentMapping.Length * sizeof(int)); var count = CurrentData.Length / Container.ItemSize; var mr = new BufferMemoryReader(CurrentData); if (CurrentMapping.Length != count) { Array.Resize(ref CurrentMapping, count); } for (int i = 0; i < count; i++) { CurrentMapping[i] = mr.Read <int>(i * Container.ItemSize); } NewItems.Clear(); OldItems.Clear(); // Compare against previous where there is a value. for (int i = 0; i < Math.Min(PreviousMapping.Length, CurrentMapping.Length); i++) { if (CurrentMapping[i] != PreviousMapping[i]) { if (PreviousMapping[i] != -1) { OnItemRemoved(i); OldItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(PreviousData), i * Container.ItemSize)); } if (CurrentMapping[i] != -1) { OnItemAdded(i); NewItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(CurrentData), i * Container.ItemSize)); } } } // Check expanded area. for (int i = PreviousMapping.Length; i < CurrentMapping.Length; i++) { if (CurrentMapping[i] != -1) { OnItemAdded(i); NewItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(CurrentData), i * Container.ItemSize)); } } // Check reduced area. for (int i = CurrentMapping.Length; i < PreviousMapping.Length; i++) { if (PreviousMapping[i] != -1) { OnItemRemoved(i); OldItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(PreviousData), i * Container.ItemSize)); } } }
public void Update(MemoryContext ctx) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } try { if (!IsLocalActorValid(ctx)) { return; } if (!IsObjectManagerOnNewFrame(ctx)) { return; } var itemsToAdd = new List <IMapMarker>(); var itemsToRemove = new List <IMapMarker>(); _acdsObserver = _acdsObserver ?? new ContainerObserver <ACD>(ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData); _acdsObserver.Update(); // Must have a local ACD to base coords on. if (_playerAcd == null) { var playerAcdId = ctx.DataSegment.ObjectManager.PlayerDataManager[ ctx.DataSegment.ObjectManager.Player.LocalPlayerIndex].ACDID; var index = Array.IndexOf(_acdsObserver.CurrentMapping, playerAcdId); if (index != -1) { _playerAcd = MemoryObjectFactory.UnsafeCreate <ACD>(new BufferMemoryReader(_acdsObserver.CurrentData), index * _acdsObserver.Container.ItemSize); } } foreach (var acd in _acdsObserver.OldItems) { var marker = default(IMapMarker); if (_minimapItemsDic.TryGetValue(acd.Address, out marker)) { Trace.WriteLine("Removing " + acd.Name); itemsToRemove.Add(marker); _minimapItemsDic.Remove(acd.Address); } } foreach (var acd in _acdsObserver.NewItems) { var actorSnoId = acd.ActorSNO; if (_ignoredSnoIds.Contains(actorSnoId)) { continue; } if (!_minimapItemsDic.ContainsKey(acd.Address)) { bool ignore; var minimapItem = MapMarkerFactory.Create(acd, out ignore); if (ignore) { _ignoredSnoIds.Add(actorSnoId); } else if (minimapItem != null) { _minimapItemsDic.Add(acd.Address, minimapItem); itemsToAdd.Add(minimapItem); } } } UpdateUI(itemsToAdd, itemsToRemove); } catch (Exception exception) { OnUpdateException(exception); } }
private void Run() { var actors = new ContainerObserver <Actor> { Container = _ctx.DataSegment.ObjectManager.Actors }; actors.ItemRemoved += (index, actor) => { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"{actors.Container.Name} item removed at [{index}]: {MemoryObjectFactory.UnsafeCreate<Actor>(new BufferMemoryReader(actors.PreviousData), index * SymbolTable.Current.Actor.SizeOf).Name}"); Console.ResetColor(); }; actors.ItemAdded += (index, actor) => { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{actors.Container.Name} item added at [{index}]: {MemoryObjectFactory.UnsafeCreate<Actor>(new BufferMemoryReader(actors.CurrentData), index * SymbolTable.Current.Actor.SizeOf).Name}"); Console.ResetColor(); }; while (_stopSignal.WaitOne(10) == false) { try { actors.Update(); } catch { } // TODO: Re-bind on exception, container could be at a new address } }