Created
August 15, 2022 03:17
-
-
Save Micrologist/b0eaa094ff947941d44818a681ed0838 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using MemUtil; | |
using System.Diagnostics; | |
using System.Globalization; | |
Console.Write("Enter the name of the game process: "); | |
string? procName = Console.ReadLine()?.Replace(".exe", ""); | |
List<Process> procList = Process.GetProcesses().ToList().FindAll(x => x.ProcessName == procName); | |
if (procList.Count == 0) | |
{ | |
Console.WriteLine("Process not found!"); | |
Console.ReadKey(); | |
return; | |
} | |
Process game = procList[0]; | |
var modules = game.ModulesWow64Safe(); | |
var GetStaticPointerFromSig = (Func<string, int, IntPtr>)((signature, instructionOffset) => | |
{ | |
var scanner = new SignatureScanner(game, modules.First().BaseAddress, (int)modules.First().ModuleMemorySize); | |
var pattern = new SigScanTarget(signature); | |
var location = scanner.Scan(pattern); | |
if (location == IntPtr.Zero) return IntPtr.Zero; | |
int offset = game.ReadValue<int>((IntPtr)location + instructionOffset); | |
return (IntPtr)location + offset + instructionOffset + 0x4; | |
}); | |
var FNamePool = GetStaticPointerFromSig("74 09 48 8D 15 ?? ?? ?? ?? EB 16", 0x5); | |
var UWorld = GetStaticPointerFromSig("0F 2E ?? 74 ?? 48 8B 1D ?? ?? ?? ?? 48 85 DB 74", 0x8); | |
var GetNameFromFName = (Func<long, string>)(longKey => | |
{ | |
int key = (int)(longKey & uint.MaxValue); | |
int partial = (int)(longKey >> 32); | |
int chunkOffset = key >> 16; | |
int nameOffset = (ushort)key; | |
IntPtr namePoolChunk = game.ReadValue<IntPtr>((IntPtr)FNamePool + ((chunkOffset + 2) * 0x8)); | |
Int16 nameEntry = game.ReadValue<Int16>((IntPtr)namePoolChunk + (2 * nameOffset)); | |
int nameLength = nameEntry >> 6; | |
string output = game.ReadString((IntPtr)namePoolChunk + (2 * nameOffset) + 2, nameLength); | |
return (partial == 0) ? output : output + "_" + partial.ToString(); | |
}); | |
Console.Write("Enter \"Levels\" offset (in hex): "); | |
string? levelsOffsetString = Console.ReadLine()?.Replace("0x", ""); | |
if(!int.TryParse(levelsOffsetString, System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int levelsOffset)) | |
{ | |
Console.WriteLine("invalid input"); | |
Console.ReadKey(); | |
return; | |
} | |
Console.Write("Enter \"StreamingLevels\" offset (in hex): "); | |
string? streamingLevelsOffsetString = Console.ReadLine()?.Replace("0x", ""); | |
if (!int.TryParse(streamingLevelsOffsetString, System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int streamingLevelsOffset)) | |
{ | |
Console.WriteLine("invalid input"); | |
Console.ReadKey(); | |
return; | |
} | |
string persistentLevelName = GetNameFromFName(new DeepPointer(UWorld, 0x30, 0x20, 0x20, 0x18).Deref<long>(game)); | |
Console.WriteLine("\nPersistent Level: " + persistentLevelName); | |
IntPtr levelsPtr = new DeepPointer(UWorld, levelsOffset).Deref<IntPtr>(game); | |
int levelsCount = new DeepPointer(UWorld, levelsOffset + 0x8).Deref<int>(game); | |
Console.WriteLine("\nLevel Array at \"{0}\" containing {1} entries.", levelsPtr.ToString("X16"), levelsCount); | |
for (int i = 1; i < levelsCount; i++) | |
{ | |
string levelName = GetNameFromFName(new DeepPointer(UWorld, levelsOffset, 0x8 * i, 0x20, 0x20, 0x18).Deref<long>(game)); | |
Console.WriteLine(levelName); | |
} | |
IntPtr streamingLevelsPtr = new DeepPointer(UWorld, streamingLevelsOffset).Deref<IntPtr>(game); | |
int streamingLevelsCount = new DeepPointer(UWorld, streamingLevelsOffset + 0x8).Deref<int>(game); | |
Console.WriteLine("\nStreaming Level Array at \"{0}\" containing {1} entries.", streamingLevelsPtr.ToString("X16"), streamingLevelsCount); | |
for (int i = 0; i < streamingLevelsCount; i++) | |
{ | |
string levelName = GetNameFromFName(new DeepPointer(UWorld, streamingLevelsOffset, 0x8 * i, 0x38).Deref<long>(game)); | |
levelName = levelName[..levelName.LastIndexOf('.')]; | |
Console.WriteLine(levelName); | |
} | |
Console.ReadKey(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment