Skip to content
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
9 changes: 5 additions & 4 deletions ResLogger2.Plugin/PapHandling/PapHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using InteropGenerator.Runtime;

// This namespace is taken almost directly from Penumbra
namespace ResLogger2.Plugin.PapHandling;
Expand All @@ -13,9 +14,9 @@ public sealed class PapHandler : IDisposable
public const string LoadMigratoryMotionPack = "E9 ?? ?? ?? 00 8B 84 24 ?? ?? 00 00 48 8D";

private readonly PapRewriter _rewriter;
private readonly Action<IntPtr, HookType> _processHook;
private readonly Action<CStringPointer, HookType> _processHook;

public unsafe PapHandler(Action<IntPtr, HookType> processHook)
public unsafe PapHandler(Action<CStringPointer, HookType> processHook)
{
_processHook = processHook;
_rewriter = new PapRewriter(PapResourceHandler);
Expand All @@ -36,9 +37,9 @@ public unsafe PapHandler(Action<IntPtr, HookType> processHook)

public void Dispose() => _rewriter.Dispose();

private unsafe int PapResourceHandler(void* self, byte* path, int length)
private unsafe int PapResourceHandler(void* self, CStringPointer path, int length)
{
_processHook.Invoke((IntPtr)path, HookType.Unknown);
_processHook.Invoke(path, HookType.Unknown);
return length;
}
}
3 changes: 2 additions & 1 deletion ResLogger2.Plugin/PapHandling/PapRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
using System.Text.Unicode;
using Dalamud.Hooking;
using Iced.Intel;
using InteropGenerator.Runtime;
using static Iced.Intel.AssemblerRegisters;

namespace ResLogger2.Plugin.PapHandling;

public sealed class PapRewriter(PapRewriter.PapResourceHandlerPrototype papResourceHandler) : IDisposable
{
public unsafe delegate int PapResourceHandlerPrototype(void* self, byte* path, int length);
public unsafe delegate int PapResourceHandlerPrototype(void* self, CStringPointer path, int length);

private readonly PeSigScanner _scanner = new();
private readonly Dictionary<nint, AsmHook> _hooks = [];
Expand Down
51 changes: 28 additions & 23 deletions ResLogger2.Plugin/ResLogger2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
using ResLogger2.Plugin.IPC;
using ResLogger2.Plugin.PapHandling;
using ResLogger2.Plugin.Windows;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using InteropGenerator.Runtime;

namespace ResLogger2.Plugin;

public class ResLogger2 : IDalamudPlugin
public unsafe class ResLogger2 : IDalamudPlugin
{
public string Name => "ResLogger2.Plugin";

Expand All @@ -26,11 +29,9 @@ public class ResLogger2 : IDalamudPlugin

private const string CommandName = "/reslog";
private const int HookHitsTillCommit = 10000;

private delegate IntPtr GetResourceSyncPrototype(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pPath, IntPtr a6);
private delegate IntPtr GetResourceAsyncPrototype(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pPath, IntPtr a6, byte a7);
private readonly Hook<GetResourceSyncPrototype> _getResourceSyncHook;
private readonly Hook<GetResourceAsyncPrototype> _getResourceAsyncHook;

private readonly Hook<ResourceManager.Delegates.GetResourceSync> _getResourceSyncHook;
private readonly Hook<ResourceManager.Delegates.GetResourceAsync> _getResourceAsyncHook;

private readonly PapHandler _papHandler;
private readonly PenumbraIpcHandler _penumbraIpcHandler;
Expand Down Expand Up @@ -79,13 +80,17 @@ public ResLogger2(IDalamudPluginInterface pi)
ResLogWindows.AddWindow(StatsWindow);

DalamudApi.PluginInterface.UiBuilder.Draw += ResLogWindows.Draw;

var getResourceAsync = DalamudApi.SigScanner.ScanText("E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 83 C4 68");
var getResourceSync = DalamudApi.SigScanner.ScanText("E8 ?? ?? ?? ?? 48 8B 8E ?? ?? ?? ?? 49 89 04 0E");
_getResourceAsyncHook = DalamudApi.Hooks.HookFromAddress<GetResourceAsyncPrototype>(getResourceAsync, GetResourceAsyncDetour);
_getResourceSyncHook = DalamudApi.Hooks.HookFromAddress<GetResourceSyncPrototype>(getResourceSync, GetResourceSyncDetour);
_getResourceAsyncHook.Enable();

_getResourceSyncHook = DalamudApi.Hooks.HookFromAddress<ResourceManager.Delegates.GetResourceSync>(
(nint)ResourceManager.MemberFunctionPointers.GetResourceSync,
GetResourceSyncDetour);

_getResourceAsyncHook = DalamudApi.Hooks.HookFromAddress<ResourceManager.Delegates.GetResourceAsync>(
(nint)ResourceManager.MemberFunctionPointers.GetResourceAsync,
GetResourceAsyncDetour);

_getResourceSyncHook.Enable();
_getResourceAsyncHook.Enable();

var list = DalamudApi.PluginInterface.InstalledPlugins.Where(plugin => plugin.IsLoaded).ToList();

Expand All @@ -101,27 +106,27 @@ public ResLogger2(IDalamudPluginInterface pi)
}
}

private IntPtr GetResourceSyncDetour(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pPath, IntPtr a6)
private ResourceHandle* GetResourceSyncDetour(ResourceManager* thisPtr, ResourceCategory* category, uint* type, uint* hash, CStringPointer path, void* unknown, void* unkDebugPtr, uint unkDebugInt)
{
var ret = _getResourceSyncHook.Original(a1, a2, a3, a4, pPath, a6);
ProcessHook(pPath, HookType.Sync);
return ret;
var ret = _getResourceSyncHook.Original(thisPtr, category, type, hash, path, unknown, unkDebugPtr, unkDebugInt);
ProcessHook(path, HookType.Sync);
return ret;
}

private IntPtr GetResourceAsyncDetour(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pPath, IntPtr a6, byte a7)
private ResourceHandle* GetResourceAsyncDetour(ResourceManager* thisPtr, ResourceCategory* category, uint* type, uint* hash, CStringPointer path, void* unknown, bool isUnknown, void* unkDebugPtr, uint unkDebugInt)
{
var ret = _getResourceAsyncHook.Original(a1, a2, a3, a4, pPath, a6, a7);
ProcessHook(pPath, HookType.Async);
return ret;
var ret = _getResourceAsyncHook.Original(thisPtr, category, type, hash, path, unknown, isUnknown, unkDebugPtr, unkDebugInt);
ProcessHook(path, HookType.Async);
return ret;
}

public void ProcessHook(IntPtr pPath, HookType type)
public void ProcessHook(CStringPointer pPath, HookType type)
{
_hookHits++;
try
{
if (pPath == IntPtr.Zero) return;
var path = Marshal.PtrToStringAnsi(pPath);
if (!pPath.HasValue) return;
var path = pPath.ToString();
if (string.IsNullOrEmpty(path)) return;
if (!IsAscii(path)) return;

Expand Down