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 9 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
19 changes: 19 additions & 0 deletions ReClass.NET/Controls/MemoryViewControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -704,5 +704,24 @@ public void Reset()

VerticalScroll.Value = VerticalScroll.Minimum;
}


FransBouma marked this conversation as resolved.
Show resolved Hide resolved
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.

16 changes: 15 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,17 @@ 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>
7 changes: 7 additions & 0 deletions ReClass.NET/Memory/MemoryBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,12 @@ public bool HasChanged(int offset, int length)

return false;
}


public UInt64FloatDoubleData ReadFromBuffer(int offset) => new UInt64FloatDoubleData
FransBouma marked this conversation as resolved.
Show resolved Hide resolved
{
Raw1 = ReadInt32(offset),
Raw2 = ReadInt32(offset + sizeof(int))
};
}
}
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
8 changes: 7 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,11 @@ 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);
}
}
}
18 changes: 15 additions & 3 deletions ReClass.NET/Nodes/BaseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ 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>
public bool IsWrapped => ParentNode is BaseWrapperNode;
/// <summary>Gets a value indicating whether this node is wrapped into an other node. </summary>
public bool IsWrapped => (ParentNode is BaseWrapperNode);
FransBouma marked this conversation as resolved.
Show resolved Hide resolved

/// <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));
FransBouma marked this conversation as resolved.
Show resolved Hide resolved

/// <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
47 changes: 47 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 @@ -52,6 +53,52 @@ 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.ReadFromBuffer(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);
}
}
}
FransBouma marked this conversation as resolved.
Show resolved Hide resolved

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
12 changes: 3 additions & 9 deletions ReClass.NET/Nodes/Hex64Node.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.ReadFromBuffer(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.ReadFromBuffer(Offset);

return $"Int64: {value.LongValue}\nUInt64: 0x{value.ULongValue:X016}\nFloat: {value.FloatValue:0.000}\nDouble: {value.DoubleValue:0.000}";
}
Expand All @@ -46,17 +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.ReadFromBuffer(Offset);

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

return x;
}

private static UInt64FloatDoubleData ReadFromBuffer(MemoryBuffer memory, int offset) => new UInt64FloatDoubleData
{
Raw1 = memory.ReadInt32(offset),
Raw2 = memory.ReadInt32(offset + sizeof(int))
};
}
}
Loading