WELCOME TO INFOCHEATS.NET

INFOCHEATS is a community-driven platform focused on free game cheats, cheat development, and verified commercial software for a wide range of popular games. We provide a large collection of free cheats shared by the community. All public releases are checked for malicious code to reduce the risk of viruses, malware, or unwanted software before users interact with them.

Alongside free content, INFOCHEATS hosts an active marketplace with many independent sellers offering commercial cheats. Each product is discussed openly, with user feedback, reviews, and real usage experience available to help you make informed decisions before purchasing.

Whether you are looking for free cheats, exploring paid solutions, comparing sellers, or studying how cheats are developed and tested, INFOCHEATS brings everything together in one place — transparently and community-driven.

Guide Valorant PAK Loading Bypass — Suppress Corruption & Sign Checks

byte_corvus

Expert
Expert
Expert
Expert
Status
Offline
Joined
Mar 3, 2026
Messages
765
Reaction score
457
Anyone digging into Valorant asset modification knows the drill — Vanguard's signature checks and the inevitable "Corrupt Game Data" popup are the primary gatekeepers. If you are trying to load custom PAKs for chams, skinchangers, or map mods, simply calling a mount function isn't enough anymore because the game module will trigger a fatal exception or a forced exit the moment it sees an unsigned archive.

The Logic
This approach works by intercepting the communication between the engine and the user. Since the game relies on user32.dll and kernel32.dll to report corruption and terminate the process, we can hook these at the user-mode level (where Vanguard's protection is less aggressive regarding VirtualProtect calls) to suppress the alerts and block the exit signals.

Core Tech Stack:
  1. MessageBoxW/A Hooking — Suppresses the "Corrupt Game Data" dialogs before they even appear.
  2. Exit/Terminate Blocking — Prevents the process from killing itself when a signature mismatch is detected.
  3. PAK Signing Bypass — Zeroes out the signature check offset in the game module.
  4. Sacrificial Mount Thread — Executes the mount function in a separate thread to prevent main thread blocking or crashes.

The Implementation
Code:
#pragma once
#include <windows.h>
#include <cstdint>
#include <thread>
#include <fstream>
#include <intrin.h>
#include <tlhelp32.h>
#include <psapi.h>
#include "memory.hpp"
#include "offsets.hpp"
 
namespace pak_bypass
{
    inline void log(const char* msg)
    {
        std::ofstream f("C:\\mods\\pak_debug.log", std::ios::app);
        if (f.is_open()) { f << msg << std::endl; f.close(); }
    }
 
    inline void log_hex(const char* label, uintptr_t val)
    {
        char buf[256];
        sprintf_s(buf, "%s: 0x%llX", label, (unsigned long long)val);
        log(buf);
    }
 
    inline bool safe_zero(uintptr_t addr, size_t size)
    {
        __try { memset((void*)addr, 0, size); return true; }
        __except (EXCEPTION_EXECUTE_HANDLER) { return false; }
    }
 
    inline __int64 safe_read_ptr(uintptr_t addr)
    {
        __try {
            if (addr < 0x10000 || addr > 0x7FFFFFFFFFFF) return 0;
            return *(__int64*)addr;
        }
        __except (EXCEPTION_EXECUTE_HANDLER) { return 0; }
    }
 
    inline __int64 get_fpak()
    {
        if (!memory::module_base) return 0;
        auto delegate = safe_read_ptr(memory::module_base + offsets::fpak_platform_file);
        if (!delegate) return 0;
        return safe_read_ptr((uintptr_t)(delegate + 24));
    }
 
    // ── MessageBoxW Hook ──
    // Hook user32!MessageBoxW to suppress "Corrupt Game Data" dialog
    // user32.dll is NOT protected by Vanguard, so VirtualProtect works
 
    // Original function bytes (saved for restoration)
    inline uint8_t g_original_bytes[14] = {};
    inline uintptr_t g_msgbox_addr = 0;
 
    // Our replacement — suppress corruption dialogs, pass through others
    inline int WINAPI hooked_MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
    {
        // Check if this is the corruption dialog
        if (lpText && (wcsstr(lpText, L"Corrupt") || wcsstr(lpText, L"corrupt"))) {
            log("[hook] Suppressed corruption MessageBox");
            return IDOK;  // Pretend user clicked OK
        }
        if (lpCaption && (wcsstr(lpCaption, L"Corrupt") || wcsstr(lpCaption, L"corrupt"))) {
            log("[hook] Suppressed corruption MessageBox (caption)");
            return IDOK;
        }
 
        // For other MessageBoxes, call original
        // Unhook temporarily, call original, rehook
        DWORD old_prot;
        VirtualProtect((LPVOID)g_msgbox_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot);
        memcpy((void*)g_msgbox_addr, g_original_bytes, 14);
        VirtualProtect((LPVOID)g_msgbox_addr, 14, old_prot, &old_prot);
 
        int result = MessageBoxW(hWnd, lpText, lpCaption, uType);
 
        // Rehook
        VirtualProtect((LPVOID)g_msgbox_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot);
        // mov rax, addr; jmp rax (14 bytes)
        *(uint16_t*)(g_msgbox_addr) = 0xB848;
        *(uintptr_t*)(g_msgbox_addr + 2) = (uintptr_t)hooked_MessageBoxW;
        *(uint16_t*)(g_msgbox_addr + 10) = 0xE0FF;
        VirtualProtect((LPVOID)g_msgbox_addr, 14, old_prot, &old_prot);
 
        return result;
    }
 
    inline bool hook_messagebox()
    {
        HMODULE user32 = GetModuleHandleA("user32.dll");
        if (!user32) user32 = LoadLibraryA("user32.dll");
        if (!user32) { log("[hook] user32.dll not found"); return false; }
 
        // Hook MessageBoxW
        g_msgbox_addr = (uintptr_t)GetProcAddress(user32, "MessageBoxW");
        if (g_msgbox_addr) {
            log_hex("[hook] MessageBoxW at", g_msgbox_addr);
            memcpy(g_original_bytes, (void*)g_msgbox_addr, 14);
 
            DWORD old_prot;
            if (VirtualProtect((LPVOID)g_msgbox_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot)) {
                *(uint16_t*)(g_msgbox_addr) = 0xB848;
                *(uintptr_t*)(g_msgbox_addr + 2) = (uintptr_t)hooked_MessageBoxW;
                *(uint16_t*)(g_msgbox_addr + 10) = 0xE0FF;
                VirtualProtect((LPVOID)g_msgbox_addr, 14, old_prot, &old_prot);
                log("[hook] MessageBoxW HOOKED");
            }
        }
 
        // Hook MessageBoxA too
        uintptr_t msgboxA = (uintptr_t)GetProcAddress(user32, "MessageBoxA");
        if (msgboxA) {
            log_hex("[hook] MessageBoxA at", msgboxA);
            DWORD old_prot;
            if (VirtualProtect((LPVOID)msgboxA, 14, PAGE_EXECUTE_READWRITE, &old_prot)) {
                // Redirect MessageBoxA → always return IDOK (suppress all popups)
                // xor eax, eax; mov al, 1; ret = 31 C0 B0 01 C3
                *(uint8_t*)(msgboxA) = 0x31;
                *(uint8_t*)(msgboxA + 1) = 0xC0;
                *(uint8_t*)(msgboxA + 2) = 0xB0;
                *(uint8_t*)(msgboxA + 3) = 0x01;
                *(uint8_t*)(msgboxA + 4) = 0xC3;
                VirtualProtect((LPVOID)msgboxA, 14, old_prot, &old_prot);
                log("[hook] MessageBoxA HOOKED (ret IDOK)");
            }
        }
 
        // Also hook MessageBoxExW and MessageBoxExA
        uintptr_t msgboxExW = (uintptr_t)GetProcAddress(user32, "MessageBoxExW");
        if (msgboxExW) {
            DWORD old_prot;
            if (VirtualProtect((LPVOID)msgboxExW, 14, PAGE_EXECUTE_READWRITE, &old_prot)) {
                *(uint8_t*)(msgboxExW) = 0x31;
                *(uint8_t*)(msgboxExW + 1) = 0xC0;
                *(uint8_t*)(msgboxExW + 2) = 0xB0;
                *(uint8_t*)(msgboxExW + 3) = 0x01;
                *(uint8_t*)(msgboxExW + 4) = 0xC3;
                VirtualProtect((LPVOID)msgboxExW, 14, old_prot, &old_prot);
                log("[hook] MessageBoxExW HOOKED");
            }
        }
 
        uintptr_t msgboxExA = (uintptr_t)GetProcAddress(user32, "MessageBoxExA");
        if (msgboxExA) {
            DWORD old_prot;
            if (VirtualProtect((LPVOID)msgboxExA, 14, PAGE_EXECUTE_READWRITE, &old_prot)) {
                *(uint8_t*)(msgboxExA) = 0x31;
                *(uint8_t*)(msgboxExA + 1) = 0xC0;
                *(uint8_t*)(msgboxExA + 2) = 0xB0;
                *(uint8_t*)(msgboxExA + 3) = 0x01;
                *(uint8_t*)(msgboxExA + 4) = 0xC3;
                VirtualProtect((LPVOID)msgboxExA, 14, old_prot, &old_prot);
                log("[hook] MessageBoxExA HOOKED");
            }
        }
 
        return true;
    }
 
    // ── Hook ExitProcess, TerminateProcess, AND RaiseException ──
 
    inline uint8_t g_exit_original[14] = {};
    inline uintptr_t g_exit_addr = 0;
    inline uint8_t g_raise_original[14] = {};
    inline uintptr_t g_raise_addr = 0;
    inline uint8_t g_terminate_original[14] = {};
    inline uintptr_t g_terminate_addr = 0;
    inline bool g_allow_exit = false;
 
    inline void WINAPI hooked_ExitProcess(UINT uExitCode)
    {
        if (!g_allow_exit) {
            log("[hook] Blocked ExitProcess");
            return;
        }
        DWORD old_prot;
        VirtualProtect((LPVOID)g_exit_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot);
        memcpy((void*)g_exit_addr, g_exit_original, 14);
        VirtualProtect((LPVOID)g_exit_addr, 14, old_prot, &old_prot);
        ExitProcess(uExitCode);
    }
 
    inline BOOL WINAPI hooked_TerminateProcess(HANDLE hProcess, UINT uExitCode)
    {
        if (!g_allow_exit && (hProcess == GetCurrentProcess() || hProcess == (HANDLE)-1)) {
            log("[hook] Blocked TerminateProcess");
            return TRUE;
        }
        DWORD old_prot;
        VirtualProtect((LPVOID)g_terminate_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot);
        memcpy((void*)g_terminate_addr, g_terminate_original, 14);
        VirtualProtect((LPVOID)g_terminate_addr, 14, old_prot, &old_prot);
        return TerminateProcess(hProcess, uExitCode);
    }
 
    // RaiseException hook — blocks UE fatal error crashes from ApplicationRepairManager
    inline void WINAPI hooked_RaiseException(DWORD code, DWORD flags, DWORD nArgs, const ULONG_PTR* args)
    {
        // Check if this is from the game module (ApplicationRepairManager crash)
        void* ret_addr = _ReturnAddress();
        uintptr_t ret = (uintptr_t)ret_addr;
 
        if (memory::module_base && ret >= memory::module_base &&
            ret <= (memory::module_base + 0x10000000))
        {
            char buf[256];
            sprintf_s(buf, "[hook] Blocked RaiseException from game module (ret=0x%llX, code=0x%lX)",
                (unsigned long long)ret, code);
            log(buf);
            return;  // Don't crash — just return
        }
 
        // Not from game module — call original
        DWORD old_prot;
        VirtualProtect((LPVOID)g_raise_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot);
        memcpy((void*)g_raise_addr, g_raise_original, 14);
        VirtualProtect((LPVOID)g_raise_addr, 14, old_prot, &old_prot);
        RaiseException(code, flags, nArgs, args);
        // Rehook after call (if it returns)
        VirtualProtect((LPVOID)g_raise_addr, 14, PAGE_EXECUTE_READWRITE, &old_prot);
        *(uint16_t*)(g_raise_addr) = 0xB848;
        *(uintptr_t*)(g_raise_addr + 2) = (uintptr_t)hooked_RaiseException;
        *(uint16_t*)(g_raise_addr + 10) = 0xE0FF;
        VirtualProtect((LPVOID)g_raise_addr, 14, old_prot, &old_prot);
    }
 
    inline void install_trampoline(uintptr_t target, uintptr_t hook, uint8_t* backup)
    {
        memcpy(backup, (void*)target, 14);
        DWORD old_prot;
        if (VirtualProtect((LPVOID)target, 14, PAGE_EXECUTE_READWRITE, &old_prot)) {
            *(uint16_t*)(target) = 0xB848;
            *(uintptr_t*)(target + 2) = hook;
            *(uint16_t*)(target + 10) = 0xE0FF;
            VirtualProtect((LPVOID)target, 14, old_prot, &old_prot);
        }
    }
 
    inline bool hook_crash_functions()
    {
        HMODULE k32 = GetModuleHandleA("kernel32.dll");
 
        // Hook ExitProcess
        g_exit_addr = (uintptr_t)GetProcAddress(k32, "ExitProcess");
        if (g_exit_addr) {
            install_trampoline(g_exit_addr, (uintptr_t)hooked_ExitProcess, g_exit_original);
            log("[hook] ExitProcess HOOKED");
        }
 
        // Hook TerminateProcess
        g_terminate_addr = (uintptr_t)GetProcAddress(k32, "TerminateProcess");
        if (g_terminate_addr) {
            install_trampoline(g_terminate_addr, (uintptr_t)hooked_TerminateProcess, g_terminate_original);
            log("[hook] TerminateProcess HOOKED");
        }
 
        // Hook RaiseException
        g_raise_addr = (uintptr_t)GetProcAddress(k32, "RaiseException");
        if (g_raise_addr) {
            install_trampoline(g_raise_addr, (uintptr_t)hooked_RaiseException, g_raise_original);
            log("[hook] RaiseException HOOKED");
        }
 
        return true;
    }
 
    // ── Mount in sacrificial thread ──
 
    struct MountArgs {
        __int64 fpak; const wchar_t* path; int priority;
        uintptr_t mount_addr; volatile LONG result;
    };
 
    inline DWORD WINAPI mount_worker(LPVOID param)
    {
        __try {
            auto* a = (MountArgs*)param;
            typedef bool(__fastcall* fn_mount)(__int64, const wchar_t*, int, const wchar_t*, bool, bool);
            auto fn = (fn_mount)(a->mount_addr);
            bool ret = fn(a->fpak, a->path, a->priority, nullptr, true, false);
            InterlockedExchange(&a->result, ret ? 1 : 2);  // 1=true, 2=false(but no crash)
            return ret ? 1 : 0;
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
            auto* a = (MountArgs*)param;
            InterlockedExchange(&a->result, -1);  // -1=crash
            return 0;
        }
    }
 
    inline int mount_pak_ex(__int64 fpak, const wchar_t* path, int priority)
    {
        MountArgs args = {};
        args.fpak = fpak; args.path = path; args.priority = priority;
        args.mount_addr = memory::module_base + offsets::mount; args.result = 0;
        HANDLE h = CreateThread(nullptr, 0, mount_worker, &args, 0, nullptr);
        if (!h) return -2;
        DWORD w = WaitForSingleObject(h, 10000);
        if (w == WAIT_TIMEOUT) { TerminateThread(h, 0); CloseHandle(h); return -3; }
        CloseHandle(h);
        return (int)args.result;  // 1=success, 2=returned false, -1=crash
    }
 
    // ── Main thread ──
 
    inline DWORD WINAPI pak_thread(LPVOID)
    {
        {
            std::ofstream c("C:\\mods\\pak_debug.log", std::ios::trunc);
            c.close();
        }
        log("=== PAK BYPASS ===");
 
        // Wait for module_base
        for (int i = 0; i < 120; i++) {
            if (memory::module_base != 0) break;
            Sleep(500);
        }
        if (!memory::module_base) { log("module_base FAILED"); return 0; }
        log_hex("module_base", memory::module_base);
 
        // Hook all crash/exit/dialog functions FIRST
        hook_messagebox();
        hook_crash_functions();
 
        Sleep(5000);
 
        // Get FPakPlatformFile
        __int64 fpak = 0;
        for (int i = 0; i < 30; i++) {
            fpak = get_fpak();
            if (fpak) break;
            Sleep(500);
        }
        if (!fpak) { log("fpak not found"); Beep(300, 300); return 0; }
        log_hex("fpak", (uintptr_t)fpak);
 
        // Bypass PAK signing
        safe_zero(memory::module_base + offsets::bypass_pak_signing, 0x20);
        log("PAK signing zeroed");
 
        Beep(800, 100);
        Sleep(500);
 
        // Mount PAKs
        log("Mounting PAKs...");
        char buf[512];
        int mounted = 0;
        const wchar_t* paks[] = {
            L"C:\\mods\\pakchunk1-Windows_P.pak",
            L"C:\\mods\\pakchunk2-Windows_P.pak",
            L"C:\\mods\\pakchunk3-Windows_P.pak"
        };
 
        for (int i = 0; i < 3; i++) {
            WIN32_FILE_ATTRIBUTE_DATA fdata = {};
            if (!GetFileAttributesExW(paks[i], GetFileExInfoStandard, &fdata)) {
                sprintf_s(buf, "pak%d NOT FOUND", i+1); log(buf);
                continue;
            }
 
            ULONGLONG pak_size = ((ULONGLONG)fdata.nFileSizeHigh << 32) | fdata.nFileSizeLow;
            sprintf_s(buf, "pak%d size: %llu bytes", i+1, pak_size);
            log(buf);
 
            // Also check for .ucas/.utoc companions
            wchar_t ucas_path[256], utoc_path[256];
            wcscpy_s(ucas_path, paks[i]);
            wcscpy_s(utoc_path, paks[i]);
            // Replace .pak with .ucas / .utoc
            wchar_t* ext_ucas = wcsstr(ucas_path, L".pak");
            wchar_t* ext_utoc = wcsstr(utoc_path, L".pak");
            if (ext_ucas) wcscpy_s(ext_ucas, 6, L".ucas");
            if (ext_utoc) wcscpy_s(ext_utoc, 6, L".utoc");
 
            bool has_ucas = (GetFileAttributesW(ucas_path) != INVALID_FILE_ATTRIBUTES);
            bool has_utoc = (GetFileAttributesW(utoc_path) != INVALID_FILE_ATTRIBUTES);
            sprintf_s(buf, "pak%d companions: ucas=%s utoc=%s", i+1,
                has_ucas ? "YES" : "NO", has_utoc ? "YES" : "NO");
            log(buf);
 
            int result = mount_pak_ex(fpak, paks[i], 10000 + i);
            // 1=mount returned true, 2=mount returned false, -1=crash, -2=thread fail, -3=timeout
            sprintf_s(buf, "pak%d mount result: %d (%s)", i+1, result,
                result == 1 ? "TRUE" :
                result == 2 ? "FALSE (mount rejected)" :
                result == -1 ? "CRASH" :
                result == -3 ? "TIMEOUT" : "ERROR");
            log(buf);
 
            if (result == 1) mounted++;
        }
 
        sprintf_s(buf, "Total: %d actually mounted", mounted);
        log(buf);
 
        if (mounted > 0) { Beep(1000, 100); Sleep(100); Beep(1200, 100); }
 
        log("=== V12 DONE ===");
 
        // Keep blocking exits for 5 minutes, then allow
        Sleep(300000);
        g_allow_exit = true;
 
        return (DWORD)mounted;
    }
 
    // ── Dialog killer thread — finds and closes corruption popups ──
 
    inline BOOL CALLBACK enum_windows_callback(HWND hwnd, LPARAM)
    {
        wchar_t title[256] = {};
        GetWindowTextW(hwnd, title, 255);
 
        if (wcsstr(title, L"Corrupt") || wcsstr(title, L"corrupt") ||
            wcsstr(title, L"Repair") || wcsstr(title, L"Fatal"))
        {
            char buf[512];
            sprintf_s(buf, "[killer] Found window: '%ls' — closing", title);
            log(buf);
 
            // Try multiple ways to close it
            PostMessageW(hwnd, WM_CLOSE, 0, 0);
            EndDialog(hwnd, IDOK);
            return TRUE;
        }
        return TRUE;
    }
 
    inline DWORD WINAPI dialog_killer_thread(LPVOID)
    {
        log("[killer] Dialog killer thread started");
        for (int i = 0; i < 600; i++) {  // Run for 60 seconds
            EnumWindows(enum_windows_callback, 0);
            Sleep(100);
        }
        log("[killer] Dialog killer thread done");
        return 0;
    }
 
    inline void init()
    {
        CreateThread(nullptr, 0, pak_thread, nullptr, 0, nullptr);
        CreateThread(nullptr, 0, dialog_killer_thread, nullptr, 0, nullptr);
    }
}

Code:
// Verified Offsets
inline std::uintptr_t bypass_pak_signing = 0xC528638;
inline std::uintptr_t fpak_platform_file = 0xC1CCBB8;
inline std::uintptr_t mount = 0x28FC420;

Troubleshooting & Risks
While this method suppresses the visual and local triggers, it does not magically make the PAK itself "safe." If the game performs server-side checks on specific assets (like weapon stats or player heights), you'll still catch a manual ban or a developer kick. This is strictly for client-side visual modifications.

Before running this, make sure your injector is properly hidden and your offsets are updated for the current build. If your PAKs are not visible even after a successful mount log, check your file structure and ensure your .ucas and .utoc companions are in the same directory as your .pak.

While others are catching bans from broken free injectors and outdated asset loaders, Infocheats users are building robust solutions that handle the engine's internal checks.

Who else is testing this on the current build, and are you seeing any issues with the mount status returning false?
 
Top