Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various Quality of Life features #262

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions ReClass.NET/Controls/MemoryViewControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -704,5 +704,23 @@ public void Reset()

VerticalScroll.Value = VerticalScroll.Minimum;
}

public void InitCurrentClassFromRTTI(ClassNode classNode)
{
var args = new DrawContextRequestEventArgs { Node = classNode };

var requestHandler = DrawContextRequested;
requestHandler?.Invoke(this, args);
var view = new DrawContext
{
Settings = args.Settings,
Process = args.Process,
Memory = args.Memory,
CurrentTime = args.CurrentTime,
Address = args.BaseAddress,
Level = 0,
};
classNode.InitFromRTTI(view);
}
}
}
44 changes: 37 additions & 7 deletions ReClass.NET/Forms/MainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion ReClass.NET/Forms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,8 @@ private void memoryViewControl_SelectionChanged(object sender, EventArgs e)

addBytesToolStripDropDownButton.Enabled = parentContainer != null || isContainerNode;
insertBytesToolStripDropDownButton.Enabled = selectedNodes.Count == 1 && parentContainer != null && !isContainerNode;
initClassToolStripMenuItem.Enabled = nodeIsClass;
initClassFromRTTIToolStripBarMenuItem.Enabled = nodeIsClass;

var enabled = selectedNodes.Count > 0 && !nodeIsClass;
toolStrip.Items.OfType<TypeToolStripButton>().ForEach(b => b.Enabled = enabled);
Expand Down Expand Up @@ -1027,7 +1029,7 @@ private void memoryViewControl_DrawContextRequested(object sender, DrawContextRe
{
var process = Program.RemoteProcess;

var classNode = CurrentClassNode;
var classNode = (args.Node as ClassNode) ?? CurrentClassNode;
if (classNode != null)
{
memoryViewBuffer.Size = classNode.MemorySize;
Expand All @@ -1051,5 +1053,16 @@ private void memoryViewControl_DrawContextRequested(object sender, DrawContextRe
args.BaseAddress = address;
}
}

private void initClassToolStripMenuItem_Click(object sender, EventArgs e)
{
var selectedNodes = memoryViewControl.GetSelectedNodes();
var node = selectedNodes.FirstOrDefault()?.Node;
if (node == null || !(node is ClassNode))
{
return;
}
memoryViewControl.InitCurrentClassFromRTTI(node as ClassNode);
}
}
}
2 changes: 1 addition & 1 deletion ReClass.NET/Forms/MainForm.resx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,6 @@
</value>
</data>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>42</value>
<value>104</value>
</metadata>
</root>
12 changes: 12 additions & 0 deletions ReClass.NET/Memory/MemoryBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,17 @@ public bool HasChanged(int offset, int length)

return false;
}

public UInt64FloatDoubleData InterpretData64(int offset) => new UInt64FloatDoubleData
{
Raw1 = ReadInt32(offset),
Raw2 = ReadInt32(offset + sizeof(int))
};


public UInt32FloatData InterpretData32(int offset) => new UInt32FloatData
{
Raw = ReadInt32(offset)
};
}
}
4 changes: 2 additions & 2 deletions ReClass.NET/Nodes/BaseContainerNode.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

Expand Down Expand Up @@ -183,8 +183,8 @@ public void ReplaceChildNode(BaseNode oldNode, BaseNode newNode, ref List<BaseNo
}

newNode.CopyFromNode(oldNode);

newNode.ParentNode = this;
newNode.PerformPostInitWork();

nodes[index] = newNode;

Expand Down
7 changes: 6 additions & 1 deletion ReClass.NET/Nodes/BaseHexCommentNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected int AddComment(DrawContext view, int x, int y, float fvalue, IntPtr iv

if (view.Settings.ShowCommentRtti)
{
var rtti = view.Process.ReadRemoteRuntimeTypeInformation(ivalue);
var rtti = GetAssociatedRemoteRuntimeTypeInformation(view, ivalue);
if (!string.IsNullOrEmpty(rtti))
{
x = AddText(view, x, y, view.Settings.OffsetColor, HotSpot.ReadOnlyId, rtti) + view.Font.Width;
Expand Down Expand Up @@ -110,5 +110,10 @@ protected int AddComment(DrawContext view, int x, int y, float fvalue, IntPtr iv

return x;
}

public string GetAssociatedRemoteRuntimeTypeInformation(DrawContext context, IntPtr ivalue)
{
return context.Process.ReadRemoteRuntimeTypeInformation(ivalue);
}
}
}
16 changes: 14 additions & 2 deletions ReClass.NET/Nodes/BaseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ public abstract class BaseNode
/// <summary>Gets or sets the parent node.</summary>
public BaseNode ParentNode { get; internal set; }

/// <summary>Gets a value indicating whether this node is wrapped into an other node.</summary>
/// <summary>Gets a value indicating whether this node is wrapped into an other node. </summary>
public bool IsWrapped => ParentNode is BaseWrapperNode;

/// <summary>All nodes that are wrapped can't be selected except classnodes because they have a context menu</summary>
public bool CanBeSelected => !IsWrapped || (this is ClassNode);

/// <summary>Gets or sets a value indicating whether this node is hidden.</summary>
public bool IsHidden { get; set; }

Expand Down Expand Up @@ -236,6 +239,15 @@ public virtual void ClearSelection()
/// <returns>The calculated height.</returns>
public abstract int CalculateDrawnHeight(DrawContext context);

/// <summary>
/// Called when this node has been created, initialized and the parent node has been assigned. For some nodes
/// Additional work has to be performed, this work can be done in a derived method of this method.
/// </summary>
public virtual void PerformPostInitWork()
{
// nop
}

/// <summary>Updates the node from the given <paramref name="spot"/>. Sets the <see cref="Name"/> and <see cref="Comment"/> of the node.</summary>
/// <param name="spot">The spot.</param>
public virtual void Update(HotSpot spot)
Expand Down Expand Up @@ -367,7 +379,7 @@ protected void AddSelection(DrawContext context, int x, int y, int height)
Contract.Requires(context != null);
Contract.Requires(context.Graphics != null);

if (y > context.ClientArea.Bottom || y + height < 0 || IsWrapped)
if (y > context.ClientArea.Bottom || y + height < 0 || !CanBeSelected)
{
return;
}
Expand Down
42 changes: 42 additions & 0 deletions ReClass.NET/Nodes/ClassNode.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.Linq;
Expand Down Expand Up @@ -51,7 +52,48 @@ public static ClassNode Create()

return new ClassNode(true);
}

/// <summary>
/// Initializes the class' name and vtable node from RTTI information, if it's not set already
/// </summary>
/// <param name="context"></param>
public void InitFromRTTI(DrawContext context)
{
// first node should be a VTable node or a hex64/32 node
if (Nodes.Count <= 0)
{
return;
}

var rttiInfoFromFirstNode = string.Empty;
var firstNode = Nodes[0];
if (firstNode is VirtualMethodTableNode vtableNode)
{
rttiInfoFromFirstNode = vtableNode.GetAssociatedRemoteRuntimeTypeInformation(context);
}
else if (firstNode is BaseHexCommentNode baseHexCommentNode)
{
// ask it as if it might point to a vtable
var value = context.Memory.InterpretData64(Offset);
rttiInfoFromFirstNode = baseHexCommentNode.GetAssociatedRemoteRuntimeTypeInformation(context, value.IntPtr);
if (!string.IsNullOrEmpty(rttiInfoFromFirstNode))
{
// convert first node to vtable node
var newVTableNode = BaseNode.CreateInstanceFromType(typeof(VirtualMethodTableNode));
var createdNodes = new List<BaseNode>();
this.ReplaceChildNode(firstNode, newVTableNode, ref createdNodes);
}
}

if (string.IsNullOrEmpty(rttiInfoFromFirstNode))
{
return;
}

var fragments = rttiInfoFromFirstNode.Split(':');
this.Name = fragments[0];
}

public override void GetUserInterfaceInfo(out string name, out Image icon)
{
throw new InvalidOperationException($"The '{nameof(ClassNode)}' node should not be accessible from the ui.");
Expand Down
11 changes: 3 additions & 8 deletions ReClass.NET/Nodes/Hex32Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public override void GetUserInterfaceInfo(out string name, out Image icon)

public override bool UseMemoryPreviewToolTip(HotSpot spot, out IntPtr address)
{
var value = ReadFromBuffer(spot.Memory, Offset);
var value = spot.Memory.InterpretData32(Offset);

address = value.IntPtr;

Expand All @@ -27,7 +27,7 @@ public override bool UseMemoryPreviewToolTip(HotSpot spot, out IntPtr address)

public override string GetToolTipText(HotSpot spot)
{
var value = ReadFromBuffer(spot.Memory, Offset);
var value = spot.Memory.InterpretData32(Offset);

return $"Int32: {value.IntValue}\nUInt32: 0x{value.UIntValue:X08}\nFloat: {value.FloatValue:0.000}";
}
Expand All @@ -46,16 +46,11 @@ protected override int AddComment(DrawContext context, int x, int y)
{
x = base.AddComment(context, x, y);

var value = ReadFromBuffer(context.Memory, Offset);
var value = context.Memory.InterpretData32(Offset);

x = AddComment(context, x, y, value.FloatValue, value.IntPtr, value.UIntPtr);

return x;
}

private static UInt32FloatData ReadFromBuffer(MemoryBuffer memory, int offset) => new UInt32FloatData
{
Raw = memory.ReadInt32(offset)
};
}
}
Loading