public static void GenerateClass(MemoryObject obj)
        {
            var cts = new CancellationTokenSource();
            var ct  = cts.Token;

            var dialog = new MemoryObjectClassGeneratorDialog();

            dialog.HeaderText         = "Generating class...";
            dialog.StatusText         = "";
            dialog.ProgressPercentage = 0;
            dialog.Closed            += (s, e) =>
                                        cts.Cancel();

            var task = new Task <StringBuilder>(() =>
            {
                var type         = obj.GetType();
                var size         = type.SizeOf();
                string hexFormat = "X" + Math.Max(2, size.ToString("X").Length);
                var sb           = new StringBuilder();
                sb.AppendLine(string.Format("public class {0} : MemoryObject", type.Name));
                sb.AppendLine("{");

                int offset = 0;
                while (offset < size && !ct.IsCancellationRequested)
                {
                    Execute.OnUIThreadAsync(() =>
                    {
                        dialog.ProgressPercentage = 100d * offset / size;
                        dialog.StatusText         = string.Format("Scanning {0} / {1}", offset, size);
                    });

                    var ctx = new TypeMatchContext(obj, offset);
                    if (false ||
                        ctx.TryAsList() ||
                        ctx.TryAsAllocator() ||
                        ctx.TryAsBasicAllocator() ||
                        ctx.TryAsMap() ||
                        ctx.TryAsVector() ||
                        ctx.TryAsZeroInt32() ||                         // Anything that might be valid if first 4 bytes are zero must be above this check!
                        ctx.TryAsUIReference() ||
                        ctx.TryAsSno() ||
                        ctx.TryAsRefString() ||
                        ctx.TryAsText() ||
                        ctx.TryAsFloat() ||
                        ctx.TryAsPointer() ||
                        false)
                    {
                        if (ctx.Name == null)
                        {
                            ctx.Name = ctx.FieldType;
                        }
                    }
                    else
                    {
                        ctx.Prefix    = "_";
                        ctx.FieldType = "int";
                        ctx.Name      = "";
                        ctx.FieldSize = sizeof(int);
                        ctx.Comment   = ctx.Read <int>(0x00).ToString();
                    }

                    string line = string.Format("\t/* 0x{5:X8} */ public {0} {1}x{2}{3} {{ get {{ return Read<{0}>(0x{2}); }} }}{4}",
                                                ctx.FieldType,
                                                ctx.Prefix,
                                                ctx.Offset.ToString(hexFormat),
                                                ctx.Name == string.Empty ? string.Empty : ("_" + ctx.Name + ctx.Postfix),
                                                string.IsNullOrEmpty(ctx.Comment) ? string.Empty : " // " + ctx.Comment,
                                                ctx.MemoryObject.Address + ctx.Offset);
                    sb.AppendLine(line);

                    offset += ctx.FieldSize;
                }
                sb.AppendLine("}");
                return(sb);
            }, ct);

            task.ContinueWith(t =>
            {
                var sb = t.Result;
                Execute.OnUIThread(() =>
                {
                    dialog.Close();
                    var menu = new ContextMenu();
                    var item = new MenuItem {
                        Header = "Copy to clipboard"
                    };
                    item.Click += (s, e) => Clipboard.SetText(sb.ToString());
                    menu.Items.Add(item);
                    new Window()
                    {
                        Content = new ScrollViewer
                        {
                            Content = new TextBox
                            {
                                IsReadOnly  = true,
                                Text        = sb.ToString(),
                                FontFamily  = new FontFamily("Consolas"),
                                ContextMenu = menu
                            }
                        }
                    }.ShowDialog();
                });
            });
            task.Start();
            dialog.ShowDialog();
        }
Example #2
0
        private void PreProcess(ref IMethodCallMessage msg)
        {
            if (msg.MethodName.StartsWith("get_"))
            {
                PropertyInfo property  = _target.GetType().GetProperty(msg.MethodName.Substring(4));
                var          attribute = property.GetCustomAttribute <AddressAttribute>();

                if (property.CanWrite && attribute != null)
                {
                    ProcessMemory mem = _target.Memory[attribute.Address];

                    if (property.PropertyType == typeof(int))
                    {
                        property.SetValue(_target, mem.AsInteger());
                    }
                    if (property.PropertyType == typeof(byte))
                    {
                        property.SetValue(_target, mem.AsByte());
                    }
                    if (property.PropertyType == typeof(byte[]))
                    {
                        property.SetValue(_target, mem.AsBytes(attribute.Length));
                    }
                    if (property.PropertyType == typeof(float))
                    {
                        property.SetValue(_target, mem.AsFloat());
                    }
                    if (property.PropertyType == typeof(short))
                    {
                        property.SetValue(_target, mem.AsShort());
                    }
                    if (property.PropertyType == typeof(string))
                    {
                        property.SetValue(_target, mem.AsString(attribute.Length));
                    }
                    if (property.PropertyType.IsSubclassOf(typeof(MemoryObject)))
                    {
                        property.SetValue(_target, Activator.CreateInstance(property.PropertyType, mem.AsPointer()));
                    }
                }
            }

            if (msg.MethodName.StartsWith("set_"))
            {
                PropertyInfo property  = _target.GetType().GetProperty(msg.MethodName.Substring(4));
                var          attribute = property.GetCustomAttribute <AddressAttribute>();

                if (property.CanWrite && attribute != null)
                {
                    ProcessMemory mem = _target.Memory[attribute.Address];

                    if (property.PropertyType == typeof(int))
                    {
                        mem.Set((int)msg.GetArg(0));
                    }
                    if (property.PropertyType == typeof(byte))
                    {
                        mem.Set((byte)msg.GetArg(0));
                    }
                    if (property.PropertyType == typeof(byte[]))
                    {
                        mem.Set((byte[])msg.GetArg(0));
                    }
                    if (property.PropertyType == typeof(float))
                    {
                        mem.Set((float)msg.GetArg(0));
                    }
                    if (property.PropertyType == typeof(short))
                    {
                        mem.Set((short)msg.GetArg(0));
                    }
                    if (property.PropertyType == typeof(string))
                    {
                        mem.Set((string)msg.GetArg(0));
                    }
                    if (property.PropertyType.IsSubclassOf(typeof(MemoryObject)))
                    {
                        object value = msg.GetArg(0);
                        if (value != null)
                        {
                            var other = value as MemoryObject;
                            mem.Set(other.Memory.Address);
                        }
                    }
                }
            }
        }
 public TypeMatchContext(MemoryObject obj, int offset)
 {
     MemoryObject = obj;
     Size         = obj.GetType().SizeOf();
     Offset       = offset;
 }