Skip to content

Instantly share code, notes, and snippets.

@CamxxCore
Last active June 26, 2017 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CamxxCore/3c81920f4ab30e5659310bd580268aae to your computer and use it in GitHub Desktop.
Save CamxxCore/3c81920f4ab30e5659310bd580268aae to your computer and use it in GitHub Desktop.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
namespace Memory
{
public static unsafe class MemoryAccess
{
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
public delegate IntPtr FwGetAssetIndexFn(IntPtr assetStore, out int index, StringBuilder name);
public delegate IntPtr GetPooledPtfxAddressFn(int handle);
private static readonly IntPtr PtfxAssetStorePtr;
private static readonly FwGetAssetIndexFn FwGetAssetIndex;
static MemoryAccess()
{
#region SetupPTFXAssetStore
var pattern = new Pattern("\x0F\xBF\x04\x9F\xB9", "xxxxx");
var result = pattern.Get(0x19);
if (result != IntPtr.Zero)
{
var rip = result.ToInt64() + 7;
var value = Marshal.ReadInt32(IntPtr.Add(result, 3));
PtfxAssetStorePtr = new IntPtr(rip + value);
}
#endregion
#region SetupfwGetAssetIndex
pattern = new Pattern("\x41\x8B\xDE\x4C\x63\x00", "xxxxx?");
result = pattern.Get();
if (result != IntPtr.Zero)
{
var rip = result.ToInt64();
var value = Marshal.ReadInt32(result - 4);
FwGetAssetIndex = Marshal.GetDelegateForFunctionPointer<FwGetAssetIndexFn>(new IntPtr(rip + value));
}
#endregion
}
private static PgDictionary* GetPtfxRuleDictionary(string ptxAssetName)
{
var assetStore = Marshal.PtrToStructure<PtfxAssetStore>(PtfxAssetStorePtr);
int index;
FwGetAssetIndex(PtfxAssetStorePtr, out index, new StringBuilder(ptxAssetName));
var ptxFxListPtr = Marshal.ReadIntPtr(assetStore.Items + assetStore.ItemSize * index);
return (PgDictionary*)Marshal.ReadIntPtr(ptxFxListPtr + 0x48);
}
public static void DumpPtxEffectRule(PgDictionary* ptxRulesDict)
{
using (var writer = XmlWriter.Create("dump.xml",
new XmlWriterSettings {Indent = true}))
{
writer.WriteStartDocument();
writer.WriteStartElement("ptxEffectRules");
for (var i = 0; i < ptxRulesDict->ItemsCount; i++)
{
var itAddress = Marshal.ReadIntPtr(ptxRulesDict->Items + i * 8);
if (itAddress == IntPtr.Zero) continue;
var szName = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(itAddress + 0x20));
if (string.IsNullOrEmpty(szName)) continue;
var emitters = Marshal.ReadIntPtr(itAddress + 0x38);
var emitterCount = Marshal.ReadInt16(itAddress + 0x40);
writer.WriteStartElement("ptxEffectRule");
writer.WriteAttributeString("name", szName);
writer.WriteStartElement("ptxEventEmitters");
for (int e = 0; e < emitterCount; e++)
{
writer.WriteStartElement("item");
var itEmitter = Marshal.ReadIntPtr(emitters + 0x8 * e);
string emitterName = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(itEmitter + 0x30));
//string secondaryName = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(itEmitter + 0x38));
writer.WriteAttributeString("name", emitterName);
writer.WriteEndElement();
}
writer.WriteEndElement();
var parameters = Marshal.ReadIntPtr(itAddress + 0x48);
if (parameters != IntPtr.Zero)
{
writer.WriteStartElement("ptxEvolutionArgs");
var parametersList = Marshal.ReadIntPtr(parameters);
var numParams = Marshal.ReadInt16(parameters + 0x8);
for (int p = 0; p < numParams; p++)
{
var itParam = parametersList + p * 0x18;
writer.WriteStartElement("item");
writer.WriteAttributeString("name", Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(itParam)));
writer.WriteEndElement();
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
public static void DumpPtfx()
{
var ptxRulesDict = GetPtfxRuleDictionary("core");
if (ptxRulesDict != null)
{
DumpPtxEffectRule(ptxRulesDict);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment