Game Development 14 min read

Technical Principles and Implementation of Game Memory Modifiers for "Black Myth: Wukong"

This article explains the technical mechanisms behind game memory modifiers—including memory scanning, DLL injection, debugging tools, file editing, anti‑cheat evasion, and pointer scanning—using the "Black Myth: Wukong" trainer as a concrete example, and provides complete C++ code samples.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Technical Principles and Implementation of Game Memory Modifiers for "Black Myth: Wukong"

Introduction

For players who find complex game mechanics challenging, the "Black Myth: Wukong" trainer offers a way to enjoy the game regardless of skill level. This guide explores the underlying technologies that enable real‑time memory manipulation, dynamic data adjustment, and immersive gameplay enhancements.

Trainer Overview

The trainer attaches to the fixed game process name, allowing users to modify in‑game values such as health, money, and resources each time the game is launched.

How the Trainer Works

The core techniques involve real‑time memory editing and dynamic data manipulation.

Memory Editing

Memory Scan : The trainer scans the process memory to locate addresses that store specific game data (e.g., health, money).

Address Localization : Repeated scans and value comparisons pinpoint the exact address of the target variable.

Data Modification : Once the address is found, the trainer writes new values directly to memory, such as setting health to an extremely high number for infinite life.

DLL Injection

DLL Injection : A custom DLL is injected into the game process to intercept and modify function calls.

Function Hooking : Critical game functions are hooked so custom code can run before or after the original function, e.g., setting damage to zero for invincibility.

Real‑Time Adjustment : The injected DLL continuously monitors and adjusts game data to keep modifications active.

Debugging Tools

Debug Interfaces : Advanced trainers use interfaces provided by tools like Cheat Engine to interact directly with the process.

Breakpoint Debugging : Breakpoints pause execution at specific code locations, allowing data analysis and modification.

Assembly Instruction Editing : Trainers can modify assembly instructions, for example turning a "decrease health" instruction into an "increase health" instruction.

File Modification

Configuration Files : Some games store key data in INI or XML files, which can be edited to change settings.

Save Files : Direct manipulation of save files can alter progress, money, or unlock all levels.

Anti‑Cheat Measures

Anti‑Detection : Trainers employ code obfuscation, dynamic encryption, and other techniques to avoid detection by anti‑cheat systems.

Stealth Operations : Simulating normal user behavior reduces the risk of being flagged.

While these techniques provide powerful capabilities, users should respect legal and ethical considerations, avoiding unfair advantage in multiplayer environments.

Code Examples

Below is a simple memory‑scan implementation in C++:

#include
#include
#include
// Scan target memory
std::vector
ScanMemory(HANDLE hProcess, int targetValue) {
    std::vector
addresses;
    MEMORY_BASIC_INFORMATION mbi;
    LPVOID address = 0;
    while (VirtualQueryEx(hProcess, address, &mbi, sizeof(mbi))) {
        if (mbi.State == MEM_COMMIT && (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_WRITECOPY)) {
            SIZE_T bytesRead;
            std::vector
buffer(mbi.RegionSize);
            if (ReadProcessMemory(hProcess, address, buffer.data(), mbi.RegionSize, &bytesRead)) {
                for (SIZE_T i = 0; i < bytesRead - sizeof(targetValue); ++i) {
                    if (memcmp(buffer.data() + i, &targetValue, sizeof(targetValue)) == 0) {
                        addresses.push_back((LPVOID)((SIZE_T)address + i));
                    }
                }
            }
        }
        address = (LPVOID)((SIZE_T)address + mbi.RegionSize);
    }
    return addresses;
}

int main() {
    DWORD processID = 1234; // replace with actual PID
    int targetValue = 100; // value to search for
    HANDLE hProcess = OpenTargetProcess(processID);
    if (hProcess) {
        auto addresses = ScanMemory(hProcess, targetValue);
        for (auto addr : addresses) {
            std::cout << "Found value at address: " << addr << std::endl;
            ModifyMemory(hProcess, addr, 999); // modify memory
        }
        CloseHandle(hProcess);
    }
    return 0;
}

Additional examples demonstrate opening a process, writing memory, and hooking functions via inline patches.

#include
#include
// Open target process
HANDLE OpenTargetProcess(DWORD processID) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    if (hProcess == NULL) {
        std::cerr << "Failed to open process. Error: " << GetLastError() << std::endl;
    }
    return hProcess;
}

// Modify memory at a specific address
void ModifyMemory(HANDLE hProcess, LPVOID address, int newValue) {
    SIZE_T bytesWritten;
    if (WriteProcessMemory(hProcess, address, &newValue, sizeof(newValue), &bytesWritten)) {
        std::cout << "Memory modified successfully." << std::endl;
    } else {
        std::cerr << "Failed to modify memory. Error: " << GetLastError() << std::endl;
    }
}

int main() {
    DWORD processID = 1234; // replace with actual PID
    LPVOID targetAddress = (LPVOID)0x00ABCDEF; // replace with target address
    int newValue = 999; // value to write
    HANDLE hProcess = OpenTargetProcess(processID);
    if (hProcess) {
        ModifyMemory(hProcess, targetAddress, newValue);
        CloseHandle(hProcess);
    }
    return 0;
}

A simple inline hook example for MessageBoxA demonstrates function hijacking on Windows:

#include
// Original function type definition
typedef int (WINAPI *MessageBoxAFunc)(HWND, LPCSTR, LPCSTR, UINT);
MessageBoxAFunc OriginalMessageBoxA = NULL;

int WINAPI HookedMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) {
    lpText = "This is a hooked message!";
    return OriginalMessageBoxA(hWnd, lpText, lpCaption, uType);
}

void SetHook() {
    HMODULE hUser32 = GetModuleHandle("user32.dll");
    OriginalMessageBoxA = (MessageBoxAFunc)GetProcAddress(hUser32, "MessageBoxA");
    DWORD oldProtect;
    VirtualProtect(OriginalMessageBoxA, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
    *(BYTE*)OriginalMessageBoxA = 0xE9; // JMP instruction
    *(DWORD*)((BYTE*)OriginalMessageBoxA + 1) = (DWORD)HookedMessageBoxA - (DWORD)OriginalMessageBoxA - 5;
    VirtualProtect(OriginalMessageBoxA, 5, oldProtect, &oldProtect);
}

int main() {
    SetHook();
    MessageBoxA(NULL, "Original message", "Test", MB_OK);
    return 0;
}

Pointer Scanning

Manual memory editing is labor‑intensive; tools like Cheat Engine automate the process. Pointer scanning discovers stable base addresses (static pointers) that remain valid across game restarts, solving the problem of dynamic address changes.

Why Use Pointer Scanning?

Dynamic memory allocation causes variable addresses to shift each run. Pointer scanning builds a chain of pointers leading to a static base address, enabling reliable modifications even after restarts.

Basic Steps with Cheat Engine

Perform an initial scan to locate the current value's address (e.g., 0x00ABCDEF).

Right‑click the address and select "Pointer scan for this address".

Configure maximum pointer level and offsets, then start the scan.

Validate the pointer path by restarting the game and confirming the path still points to the correct value.

Save the stable pointer path for future use, eliminating the need for repeated scans.

Important Considerations

Pointer Level : Higher levels increase scan time but handle more complex multi‑level pointers.

Verification : Re‑validate pointers after each game restart to ensure stability.

Performance Impact : Scanning large processes can affect system performance; run scans in a suitable environment.

By following these steps, users can reliably locate and modify game variables, achieving consistent cheat functionality.

C++memory editinganti-cheat evasioncheat engineDLL injectiongame hackingpointer scanning
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.