mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
feat: basic .text scan cache
This currently saves cached jsons in the working directory, we might wanna change that
This commit is contained in:
parent
f473c0e6d6
commit
eca2b7f5ee
2 changed files with 57 additions and 7 deletions
|
|
@ -106,7 +106,12 @@ namespace Dalamud
|
|||
Service<ServiceContainer>.Set();
|
||||
|
||||
// Initialize the process information.
|
||||
Service<SigScanner>.Set(new SigScanner(true));
|
||||
var info = Service<DalamudStartInfo>.Get();
|
||||
var cacheDir = new DirectoryInfo(Path.Combine(info.WorkingDirectory!, "cachedSigs"));
|
||||
if (!cacheDir.Exists)
|
||||
cacheDir.Create();
|
||||
|
||||
Service<SigScanner>.Set(new SigScanner(true, new FileInfo(Path.Combine(cacheDir.FullName, $"{info.GameVersion}.json"))));
|
||||
Service<HookManager>.Set();
|
||||
|
||||
// Signal the main game thread to continue
|
||||
|
|
@ -117,7 +122,7 @@ namespace Dalamud
|
|||
// Initialize FFXIVClientStructs function resolver
|
||||
using (Timings.Start("CS Resolver Init"))
|
||||
{
|
||||
FFXIVClientStructs.Resolver.Initialize();
|
||||
FFXIVClientStructs.Resolver.InitializeParallel();
|
||||
Log.Information("[T1] FFXIVClientStructs initialized!");
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +395,10 @@ namespace Dalamud
|
|||
Service<AntiDebug>.GetNullable()?.Dispose();
|
||||
Service<DalamudAtkTweaks>.GetNullable()?.Dispose();
|
||||
Service<HookManager>.GetNullable()?.Dispose();
|
||||
Service<SigScanner>.GetNullable()?.Dispose();
|
||||
|
||||
var sigScanner = Service<SigScanner>.Get();
|
||||
sigScanner.Save();
|
||||
sigScanner.Dispose();
|
||||
|
||||
SerilogEventSink.Instance.LogLine -= SerilogOnLogLine;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game
|
||||
|
|
@ -16,17 +18,22 @@ namespace Dalamud.Game
|
|||
/// </summary>
|
||||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
public sealed class SigScanner : IDisposable
|
||||
public class SigScanner : IDisposable
|
||||
{
|
||||
private readonly FileInfo? cacheFile;
|
||||
|
||||
private IntPtr moduleCopyPtr;
|
||||
private long moduleCopyOffset;
|
||||
|
||||
private Dictionary<string, IntPtr>? textCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SigScanner"/> class using the main module of the current process.
|
||||
/// </summary>
|
||||
/// <param name="doCopy">Whether or not to copy the module upon initialization for search operations to use, as to not get disturbed by possible hooks.</param>
|
||||
public SigScanner(bool doCopy = false)
|
||||
: this(Process.GetCurrentProcess().MainModule!, doCopy)
|
||||
/// <param name="cacheFile">File used to cached signatures.</param>
|
||||
public SigScanner(bool doCopy = false, FileInfo? cacheFile = null)
|
||||
: this(Process.GetCurrentProcess().MainModule!, doCopy, cacheFile)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -35,8 +42,10 @@ namespace Dalamud.Game
|
|||
/// </summary>
|
||||
/// <param name="module">The ProcessModule to be used for scanning.</param>
|
||||
/// <param name="doCopy">Whether or not to copy the module upon initialization for search operations to use, as to not get disturbed by possible hooks.</param>
|
||||
public SigScanner(ProcessModule module, bool doCopy = false)
|
||||
/// <param name="cacheFile">File used to cached signatures.</param>
|
||||
public SigScanner(ProcessModule module, bool doCopy = false, FileInfo? cacheFile = null)
|
||||
{
|
||||
this.cacheFile = cacheFile;
|
||||
this.Module = module;
|
||||
this.Is32BitProcess = !Environment.Is64BitProcess;
|
||||
this.IsCopy = doCopy;
|
||||
|
|
@ -49,6 +58,9 @@ namespace Dalamud.Game
|
|||
|
||||
Log.Verbose($"Module base: 0x{this.TextSectionBase.ToInt64():X}");
|
||||
Log.Verbose($"Module size: 0x{this.TextSectionSize:X}");
|
||||
|
||||
if (cacheFile != null)
|
||||
this.Load();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -294,6 +306,12 @@ namespace Dalamud.Game
|
|||
/// <returns>The real offset of the found signature.</returns>
|
||||
public IntPtr ScanText(string signature)
|
||||
{
|
||||
if (this.textCache != null && this.textCache.TryGetValue(signature, out var address))
|
||||
{
|
||||
Log.Information("Found signature {Signature} in cache: {Address}", signature, address);
|
||||
return address;
|
||||
}
|
||||
|
||||
var mBase = this.IsCopy ? this.moduleCopyPtr : this.TextSectionBase;
|
||||
|
||||
var scanRet = Scan(mBase, this.TextSectionSize, signature);
|
||||
|
|
@ -306,6 +324,8 @@ namespace Dalamud.Game
|
|||
if (insnByte == 0xE8 || insnByte == 0xE9)
|
||||
return ReadJmpCallSig(scanRet);
|
||||
|
||||
this.textCache?.Add(signature, scanRet);
|
||||
|
||||
return scanRet;
|
||||
}
|
||||
|
||||
|
|
@ -337,6 +357,17 @@ namespace Dalamud.Game
|
|||
Marshal.FreeHGlobal(this.moduleCopyPtr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the current state of the cache.
|
||||
/// </summary>
|
||||
internal void Save()
|
||||
{
|
||||
if (this.cacheFile == null)
|
||||
return;
|
||||
|
||||
File.WriteAllText(this.cacheFile.FullName, JsonConvert.SerializeObject(this.textCache));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for ScanText to get the correct address for IDA sigs that mark the first JMP or CALL location.
|
||||
/// </summary>
|
||||
|
|
@ -479,5 +510,16 @@ namespace Dalamud.Game
|
|||
|
||||
this.moduleCopyOffset = this.moduleCopyPtr.ToInt64() - this.Module.BaseAddress.ToInt64();
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
if (this.cacheFile is not { Exists: true })
|
||||
{
|
||||
this.textCache = new();
|
||||
return;
|
||||
}
|
||||
|
||||
this.textCache = JsonConvert.DeserializeObject<Dictionary<string, IntPtr>>(File.ReadAllText(this.cacheFile.FullName)) ?? new Dictionary<string, IntPtr>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue