feat: add SafeMemory.PtrToStructure/<T>

This commit is contained in:
goat 2021-12-07 22:05:01 +01:00
parent 65d0acaf64
commit ca15a9c035
No known key found for this signature in database
GPG key ID: 7773BB5B43BA52E5
2 changed files with 27 additions and 10 deletions

View file

@ -190,6 +190,21 @@ namespace Dalamud
return WriteBytes(address, encoding.GetBytes(str + "\0")); return WriteBytes(address, encoding.GetBytes(str + "\0"));
} }
public static T? PtrToStructure<T>(IntPtr addr) where T : struct => (T?)PtrToStructure(addr, typeof(T));
public static object? PtrToStructure(IntPtr addr, Type type)
{
var size = Marshal.SizeOf(type);
if (!ReadBytes(addr, size, out var buffer))
return null;
var mem = new LocalMemory(size);
mem.Write(buffer);
return mem.Read(type);
}
/// <summary> /// <summary>
/// Get the size of the passed type. /// Get the size of the passed type.
/// </summary> /// </summary>
@ -249,6 +264,8 @@ namespace Dalamud
public T Read<T>(int offset = 0) => (T)Marshal.PtrToStructure(this.hGlobal + offset, typeof(T)); public T Read<T>(int offset = 0) => (T)Marshal.PtrToStructure(this.hGlobal + offset, typeof(T));
public object? Read(Type type, int offset = 0) => Marshal.PtrToStructure(this.hGlobal + offset, type);
public void Write(byte[] data, int index = 0) => Marshal.Copy(data, index, this.hGlobal, this.size); public void Write(byte[] data, int index = 0) => Marshal.Copy(data, index, this.hGlobal, this.size);
public void Write<T>(T data, int offset = 0) => Marshal.StructureToPtr(data, this.hGlobal + offset, false); public void Write<T>(T data, int offset = 0) => Marshal.StructureToPtr(data, this.hGlobal + offset, false);

View file

@ -160,8 +160,8 @@ namespace Dalamud.Utility
return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray()); return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
} }
private static ulong moduleStartAddr; private static ulong ModuleStartAddr;
private static ulong moduleEndAddr; private static ulong ModuleEndAddr;
private static unsafe void PrintOutValue(ulong addr, IEnumerable<string> path, Type type, object value) private static unsafe void PrintOutValue(ulong addr, IEnumerable<string> path, Type type, object value)
{ {
@ -173,18 +173,18 @@ namespace Dalamud.Utility
{ {
var unboxedAddr = (ulong)unboxed; var unboxedAddr = (ulong)unboxed;
ImGuiHelpers.ClickToCopyText($"{(ulong)unboxed:X}"); ImGuiHelpers.ClickToCopyText($"{(ulong)unboxed:X}");
if (moduleStartAddr > 0 && unboxedAddr >= moduleStartAddr && unboxedAddr <= moduleEndAddr) if (ModuleStartAddr > 0 && unboxedAddr >= ModuleStartAddr && unboxedAddr <= ModuleEndAddr)
{ {
ImGui.SameLine(); ImGui.SameLine();
ImGui.PushStyleColor(ImGuiCol.Text, 0xffcbc0ff); ImGui.PushStyleColor(ImGuiCol.Text, 0xffcbc0ff);
ImGuiHelpers.ClickToCopyText($"ffxiv_dx11.exe+{unboxedAddr - moduleStartAddr:X}"); ImGuiHelpers.ClickToCopyText($"ffxiv_dx11.exe+{unboxedAddr - ModuleStartAddr:X}");
ImGui.PopStyleColor(); ImGui.PopStyleColor();
} }
try try
{ {
var eType = type.GetElementType(); var eType = type.GetElementType();
var ptrObj = Marshal.PtrToStructure(new IntPtr(unboxed), eType); var ptrObj = SafeMemory.PtrToStructure(new IntPtr(unboxed), eType);
ImGui.SameLine(); ImGui.SameLine();
PrintOutObject(ptrObj, (ulong)unboxed, new List<string>(path)); PrintOutObject(ptrObj, (ulong)unboxed, new List<string>(path));
} }
@ -215,24 +215,24 @@ namespace Dalamud.Utility
{ {
path ??= new List<string>(); path ??= new List<string>();
if (moduleEndAddr == 0 && moduleStartAddr == 0) if (ModuleEndAddr == 0 && ModuleStartAddr == 0)
{ {
try try
{ {
var processModule = Process.GetCurrentProcess().MainModule; var processModule = Process.GetCurrentProcess().MainModule;
if (processModule != null) if (processModule != null)
{ {
moduleStartAddr = (ulong)processModule.BaseAddress.ToInt64(); ModuleStartAddr = (ulong)processModule.BaseAddress.ToInt64();
moduleEndAddr = moduleStartAddr + (ulong)processModule.ModuleMemorySize; ModuleEndAddr = ModuleStartAddr + (ulong)processModule.ModuleMemorySize;
} }
else else
{ {
moduleEndAddr = 1; ModuleEndAddr = 1;
} }
} }
catch catch
{ {
moduleEndAddr = 1; ModuleEndAddr = 1;
} }
} }