I build a Hack for Game Memory Manipulation

September 18, 2022 (2y ago)

Building a Game Memory Manipulation Tool with ImGui and DirectX 11 ๐ŸŽฎ๐Ÿ› ๏ธ

Introduction ๐Ÿง 

In the world of game modding, creating tools to manipulate game data can significantly enhance the gaming experience. Recently, I decided to improve my game hacking tool by integrating ImGui and DirectX 11. This article provides a detailed look at the process and includes a practical application for Dyson Sphere Program.

Setting Up: The Basics ๐Ÿ› ๏ธ

We start with a basic setup, including necessary headers and initial function definitions, allowing us to efficiently capture and manipulate game memory.

Headers and Initial Definitions

#include "includes.h"
#include <TlHelp32.h>
#include <vector>
#include <tchar.h>
 
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
Present oPresent;
HWND window = NULL;
WNDPROC oWndProc;
ID3D11Device* pDevice = NULL;
ID3D11DeviceContext* pContext = NULL;
ID3D11RenderTargetView* mainRenderTargetView;
 
#define hProc PROCESS_ALL_ACCESS

Retrieving Process and Module Information ๐Ÿ”

To manipulate game data, we need to retrieve the process ID and module base address. These functions help us locate the game's memory addresses for reading and writing values.

Get Process ID

DWORD GetProcId(const char* procName) {
    DWORD procId = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap != INVALID_HANDLE_VALUE) {
        PROCESSENTRY32 procEntry;
        procEntry.dwSize = sizeof(procEntry);
        if (Process32First(hSnap, &procEntry)) {
            do {
                if (!_stricmp(procEntry.szExeFile, procName)) {
                    procId = procEntry.th32ProcessID;
                    break;
                }
            } while (Process32Next(hSnap, &procEntry));
        }
    }
    CloseHandle(hSnap);
    return procId;
}

Get Module Base Address

uintptr_t GetModuleBaseAddress(TCHAR* lpszModuleName, DWORD pID) {
    uintptr_t dwModuleBaseAddress = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID);
    MODULEENTRY32 ModuleEntry32 = { 0 };
    ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
 
    if (Module32First(hSnapshot, &ModuleEntry32)) {
        do {
            if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) {
                dwModuleBaseAddress = (uintptr_t)ModuleEntry32.modBaseAddr;
                break;
            }
        } while (Module32Next(hSnapshot, &ModuleEntry32));
    }
    CloseHandle(hSnapshot);
    return dwModuleBaseAddress;
}

Dynamic Address Calculation ๐Ÿงฉ

To read or write memory values, we often need to navigate through a chain of pointers. This function calculates the final address dynamically based on base address and offsets.

Find Dynamic Address

uintptr_t FindDynamicAddress(HANDLE hProcess, uintptr_t baseAddress, std::vector<uintptr_t> offsets) {
    uintptr_t addr = baseAddress;
    for (size_t i = 0; i < offsets.size(); i++) {
        ReadProcessMemory(hProcess, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}

Creating the ImGui Interface ๐ŸŽจ

ImGui integration provides a user-friendly interface for interacting with the game data. The setup includes initializing ImGui and creating the main rendering loop.

Initialize ImGui

void InitImGui() {
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
    ImGui_ImplWin32_Init(window);
    ImGui_ImplDX11_Init(pDevice, pContext);
}

Main Rendering Loop

HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) {
    static bool init = false;
    static bool show = true;
 
    if (!init) {
        if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&pDevice))) {
            pDevice->GetImmediateContext(&pContext);
            DXGI_SWAP_CHAIN_DESC sd;
            pSwapChain->GetDesc(&sd);
            window = sd.OutputWindow;
            ID3D11Texture2D* pBackBuffer;
            pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
            pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView);
            pBackBuffer->Release();
            oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
            InitImGui();
            init = true;
        } else {
            return oPresent(pSwapChain, SyncInterval, Flags);
        }
    }
 
    if (ImGui::IsKeyDown(VK_INSERT)) {
        show = !show;
    }
 
    if (show) {
        ImGui_ImplDX11_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();
 
        ImGui::Begin("Game Hack Tool");
 
        for (auto& memEdit : memoryEdits) {
            ImGui::Text("%s", memEdit.label.c_str());
 
            if (ImGui::SliderInt(("##" + memEdit.label).c_str(), &memEdit.value, 0, 100)) {
                DWORD pID = GetProcId(targetProcess);
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
                uintptr_t moduleBaseAddr = GetModuleBaseAddress(_T(targetModule), pID);
                uintptr_t dynamicAddr = FindDynamicAddress(hProcess, moduleBaseAddr + memEdit.baseAddress, memEdit.offsets);
                WriteProcessMemory(hProcess, (LPVOID)dynamicAddr, &memEdit.value, sizeof(memEdit.value), 0);
                CloseHandle(hProcess);
            }
        }
 
        if (ImGui::Button("Close")) {
            kiero::shutdown();
        }
 
        ImGui::End();
        ImGui::Render();
    } else {
        ImGui::NewFrame();
        ImGui::SetNextWindowSize(ImVec2(1.0f, 1.0f), ImGuiCond_Once);
        ImGui::Begin("dummy", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
        ImGui::End();
        ImGui::Render();
        ImGui::EndFrame();
    }
 
    pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
    ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
    return oPresent(pSwapChain, SyncInterval, Flags);
}

Bringing It All Together ๐Ÿงฉ

Finally, we integrate everything into the main thread and DLL entry point, ensuring our tool initializes and hooks correctly.

Main Thread

DWORD WINAPI MainThread(LPVOID lpReserved) {
    bool init_hook = false;
    do {
        if (kiero::init(kiero::RenderType::D3D11) == kiero::Status::Success) {
            kiero::bind(8, (void**)&oPresent, hkPresent);
            init_hook = true;
        }
    } while (!init_hook);
    return TRUE;
}

DLL Main Entry Point

BOOL WINAPI DllMain(HMODULE hMod, DWORD dwReason, LPVOID lpReserved) {
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hMod);
            CreateThread(nullptr, 0, MainThread, hMod, 0, nullptr);
            break;
        case DLL_PROCESS_DETACH:
            kiero::shutdown();
            break;
    }
    return TRUE;
}

Conclusion ๐ŸŽˆ

By integrating ImGui and DirectX 11, we created a more interactive and user-friendly game hacking tool. This approach can be adapted to various needs and applications, providing a robust solution for game modding enthusiasts.

So hereโ€™s to creating powerful and user-friendly tools that enhance our gaming experiences!

Bonus! ๐ŸŽ Dyson Sphere Program Hack ๐ŸŒŒ

Key Features:

You can download the Dyson Sphere Program hack DLL here: DysonSphereHack.dll

Note: Please use this tool responsibly and in accordance with the game's terms of service. It's intended for educational purposes and personal use only.

This hack work with the version v0.9.26.13026 of Dyson Sphere Program.

Conclusion ๐ŸŽˆ

By integrating ImGui and DirectX 11, we've created a more interactive and user-friendly game hacking tool. This approach can be adapted to various games and applications, providing a robust solution for game modding enthusiasts. The Dyson Sphere Program hack demonstrates the practical application of these techniques in enhancing gameplay experiences.

Remember, the power to modify games comes with responsibility. Always respect the developers' work and the gaming community's guidelines when using such tools.

Happy hacking, and may your Dyson Spheres grow ever larger! ๐Ÿš€๐ŸŒŸ