diff --git a/Memory/Memory.hpp b/Memory/Memory.hpp index cb9d8fe..db20ef4 100644 --- a/Memory/Memory.hpp +++ b/Memory/Memory.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include @@ -10,6 +11,70 @@ Memory::CreateTrampoline(ADDRESS, allocMemory, TRAMPOLINE_LENGTH); \ Memory::WriteInstructions(allocMemory, INSTRUCTIONS, sizeof INSTRUCTIONS, ADDRESS + TRAMPOLINE_LENGTH); \ } while (false) +namespace UT { // Typedef used by Unreal Engine + typedef int8_t int8; + typedef int16_t int16; + typedef int32_t int32; + typedef int64_t int64; + + typedef uint8_t uint8; + typedef uint16_t uint16; + typedef uint32_t uint32; + typedef uint64_t uint64; +} + +struct AOBScanEntry { + uint8_t** address; + std::function getSignature; + const char* featureName; + std::string moduleName = ""; // "" = main exe + DWORD protection = PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | + PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY; + intptr_t offset = 0; +}; + +namespace AOBScan { + // Helper template to create entry with ObfuscatedString + template + static AOBScanEntry Make(uint8_t** addr, ObfStr& obf, const char* name, std::string module = "", DWORD prot = PAGE_EXECUTE_READ) { + return AOBScanEntry{ addr, [&, obf]() { return obf.decrypt(); }, name, module, prot, 0 }; + } +} + +enum class OffsetCalcType +{ + None, + GetOffsetFromOpcode, + UE_CalculateOffset +}; + +struct OffsetScanEntry +{ + uint8_t** outAddress; // Address where the pointer will be stored + std::function getSignature; // decrypted AOB + std::string name; // Name for the log (GWorlds ...) + OffsetCalcType calcType; // Method to calculate offset + UT::int32* outOffset = nullptr; // Offset pointer to update + size_t opcodeOffset = 0; // Relative offset for GetOffsetFromOpcode method + DWORD protection = PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | + PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY; +}; + +namespace OffsetScan { + // Helper template to create an entry + template + static OffsetScanEntry Make(uint8_t** addr, ObfStr& obf, const char* featureName, + OffsetCalcType type, UT::int32* outOffsetPtr, + size_t opOffset = 0, DWORD prot = PAGE_EXECUTE_READ) { + return OffsetScanEntry{ + addr, + [&obf]() { return obf.decrypt(); }, // signature lambda + featureName, type, + outOffsetPtr, + opOffset, prot + }; + } +} class Memory { @@ -65,6 +130,25 @@ class Memory */ static uint8_t* AOBScan(const std::string& module_name, const std::string& signature, DWORD protect_flags, std::shared_ptr log = nullptr); + /** + * Achieve an AOB scan in memory by batch. + * + * @param const std::vector& entries : AOB signatures of AOBScanEntry type. + * @param logger : If any log is to be used + */ + static void AOBScanBatch(const std::vector& entries, std::shared_ptr logger); + + /** + * Achieve an unreal offsets scan by batch. + * + * @param const std::vector& entries : AOB signatures of OffsetScanEntry type. + * @param baseModule : The starting address of module scanned. + * @param logger : If any log is to be used + * @param moduleName : The module targeted (.exe, .dll ...) + */ + static void OffsetScanBatch(const std::vector& entries, uint8_t* baseModule, + std::shared_ptr logger, const std::string& moduleName = ""); + static std::string ByteToHexEscaped(const BYTE byte); /**