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.

Source Apex Legends — Basic DMA Radar (MemProcFS .vmem)

byte_corvus

Newbie
Newbie
Newbie
Newbie
Status
Offline
Joined
Mar 3, 2026
Messages
546
Reaction score
7
Anyone currently digging into DMA hardware knows that the MemProcFS API can be a bit of a wall for beginners. Found this approach that simplifies things by treating the memory space like a standard file system—effective if you want a chill radar without the risk of a rage-induced manual ban.

The Architecture
Instead of hooking into the game process via standard handles (which EAC loves to flag), this implementation leverages a DMA card to map the system memory to a virtual drive (M:). The code scans for the r5apex process folder and reads the memory.vmem file directly using CreateFileA and ReadFile. It is a bit of a "lazy" way to handle DMA, but it works for an external radar setup.

Core Offsets
The following offsets are currently used in the logic for entity iteration and local player data:
  1. Entity List: 0x612c5e8
  2. Local Player: 0x2563888
  3. Health: 0x324
  4. Shield: 0x1a0
  5. Position: 0x17c
  6. Life State: 0x690

Code:
// 
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <thread>
#include <chrono>
#include <cmath>
#include <Windows.h>
 
using namespace std;
 
// OFFSETS - April 14, 2026
#define OFF_ENTITY_LIST    0x612c5e8
#define OFF_LOCAL_PLAYER   0x2563888
#define OFF_HEALTH         0x324
#define OFF_MAX_HEALTH     0x468
#define OFF_SHIELD         0x1a0
#define OFF_MAX_SHIELD     0x1a4
#define OFF_POSITION       0x17c
#define OFF_TEAM           0x33c
#define OFF_LIFE_STATE     0x690
 
string g_ProcFolder;
string g_MemPath;
HANDLE g_MemFile = INVALID_HANDLE_VALUE;
uint64_t g_Base = 0;
 
// ============================================================================
// READ FROM MEMORY FILE
// ============================================================================
template<typename T>
T Read(uint64_t addr) {
    T val = {};
    if (g_MemFile == INVALID_HANDLE_VALUE || addr < 0x10000) return val;
    
    LARGE_INTEGER pos;
    pos.QuadPart = (LONGLONG)addr;
    
    if (SetFilePointerEx(g_MemFile, pos, NULL, FILE_BEGIN)) {
        DWORD bytesRead = 0;
        ReadFile(g_MemFile, &val, sizeof(T), &bytesRead, NULL);
    }
    return val;
}
 
bool IsValid(uint64_t p) { return p > 0x10000 && p < 0x7FFFFFFFFFFF; }
 
// ============================================================================
// READ TEXT FILE
// ============================================================================
string ReadTextFile(const string& path) {
    ifstream f(path);
    if (!f.is_open()) return "";
    string content;
    getline(f, content);
    f.close();
    return content;
}
 
// ============================================================================
// FIND BASE ADDRESS
// ============================================================================
uint64_t FindBaseAddress(const string& procFolder) {
    cout << "\n[*] Searching for base address..." << endl;
    
    // Method 1: Check modules folder
    string modulesPath = procFolder + "\\modules";
    cout << "[*] Checking: " << modulesPath << endl;
    
    WIN32_FIND_DATAA fd;
    HANDLE hFind = FindFirstFileA((modulesPath + "\\*").c_str(), &fd);
    
    if (hFind != INVALID_HANDLE_VALUE) {
        cout << "[*] Modules found:" << endl;
        do {
            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                string modName = fd.cFileName;
                if (modName != "." && modName != "..") {
                    cout << "    - " << modName << endl;
                    
                    // Check if it's r5apex
                    if (modName.find("r5apex") != string::npos) {
                        string basePath = modulesPath + "\\" + modName + "\\base.txt";
                        string baseStr = ReadTextFile(basePath);
                        
                        if (baseStr.empty()) {
                            // Try without .txt
                            basePath = modulesPath + "\\" + modName + "\\base";
                            baseStr = ReadTextFile(basePath);
                        }
                        
                        if (!baseStr.empty()) {
                            uint64_t base = strtoull(baseStr.c_str(), nullptr, 16);
                            if (base > 0) {
                                cout << "[+] Found base in " << modName << ": 0x" << hex << base << dec << endl;
                                return base;
                            }
                        }
                    }
                }
            }
        } while (FindNextFileA(hFind, &fd));
        FindClose(hFind);
    }
    
    // Method 2: Read from map file (memmap)
    cout << "[*] Trying memmap..." << endl;
    string memmapPath = procFolder + "\\memmap\\memmap.txt";
    ifstream mapFile(memmapPath);
    if (mapFile.is_open()) {
        string line;
        while (getline(mapFile, line)) {
            if (line.find("r5apex") != string::npos && line.find(".exe") != string::npos) {
                // Parse: "00007FF600000000-00007FF600001000 ... r5apex_dx12.exe"
                size_t dash = line.find('-');
                if (dash != string::npos) {
                    string addrStr = line.substr(0, dash);
                    uint64_t base = strtoull(addrStr.c_str(), nullptr, 16);
                    if (base > 0x10000) {
                        cout << "[+] Found base in memmap: 0x" << hex << base << dec << endl;
                        mapFile.close();
                        return base;
                    }
                }
            }
        }
        mapFile.close();
    }
    
    // Method 3: Read from vads
    cout << "[*] Trying vads..." << endl;
    WIN32_FIND_DATAA vfd;
    HANDLE vFind = FindFirstFileA((procFolder + "\\files\\vads\\*.txt").c_str(), &vfd);
    if (vFind != INVALID_HANDLE_VALUE) {
        do {
            string vadName = vfd.cFileName;
            if (vadName.find("r5apex") != string::npos) {
                // Filename format: 00007FF600000000-r5apex_dx12.exe.txt
                size_t dash = vadName.find('-');
                if (dash != string::npos) {
                    string addrStr = vadName.substr(0, dash);
                    uint64_t base = strtoull(addrStr.c_str(), nullptr, 16);
                    if (base > 0x10000) {
                        cout << "[+] Found base in vads: 0x" << hex << base << dec << endl;
                        FindClose(vFind);
                        return base;
                    }
                }
            }
        } while (FindNextFileA(vFind, &vfd));
        FindClose(vFind);
    }
    
    return 0;
}
 
// ============================================================================
// STRUCTURES
// ============================================================================
struct Vec3 { 
    float x, y, z; 
    float Dist(const Vec3& o) const {
        float dx = x - o.x, dy = y - o.y, dz = z - o.z;
        return sqrtf(dx*dx + dy*dy + dz*dz) / 39.62f;
    }
};
 
// ============================================================================
// MAIN
// ============================================================================
int main() {
    cout << "=== APEX RADAR v2 ===" << endl << endl;
    
    // Find Apex process folder
    cout << "[*] Searching M:\\name\\ ..." << endl;
    
    WIN32_FIND_DATAA fd;
    HANDLE hFind = FindFirstFileA("M:\\name\\r5apex*", &fd);
    
    if (hFind == INVALID_HANDLE_VALUE) {
        cout << "[!] Apex not found in M:\\name\\" << endl;
        cout << "[!] Error code: " << GetLastError() << endl;
        
        // Check if M: exists
        if (GetFileAttributesA("M:\\") == INVALID_FILE_ATTRIBUTES) {
            cout << "[!] M: drive does not exist!" << endl;
            cout << "[!] Make sure MemProcFS is running" << endl;
        }
        
        system("pause");
        return 1;
    }
    
    do {
        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            g_ProcFolder = string("M:\\name\\") + fd.cFileName;
            cout << "[+] Found: " << fd.cFileName << endl;
            break;
        }
    } while (FindNextFileA(hFind, &fd));
    FindClose(hFind);
    
    // Find base address
    g_Base = FindBaseAddress(g_ProcFolder);
    
    if (g_Base == 0) {
        cout << "\n[!] Could not auto-detect base address" << endl;
        cout << "[*] Enter base address manually (from MemProcFS):" << endl;
        cout << "[*] Look in M:\\name\\r5apex...\\modules\\ for the base" << endl;
        cout << "\nEnter base (hex, e.g. 7FF600000000): ";
        
        string input;
        cin >> input;
        g_Base = strtoull(input.c_str(), nullptr, 16);
        cin.ignore();
    }
    
    if (g_Base == 0) {
        cout << "[!] Invalid base address" << endl;
        system("pause");
        return 1;
    }
    
    cout << "\n[+] Using base: 0x" << hex << g_Base << dec << endl;
    
    // Open memory file
    g_MemPath = g_ProcFolder + "\\memory.vmem";
    cout << "[*] Opening: " << g_MemPath << endl;
    
    g_MemFile = CreateFileA(
        g_MemPath.c_str(),
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
    
    if (g_MemFile == INVALID_HANDLE_VALUE) {
        cout << "[!] Cannot open memory.vmem" << endl;
        cout << "[!] Error: " << GetLastError() << endl;
        system("pause");
        return 1;
    }
    cout << "[+] Memory file opened!" << endl;
    
    // Test offsets
    cout << "\n=== TESTING ===" << endl;
    uint64_t localPlayer = Read<uint64_t>(g_Base + OFF_LOCAL_PLAYER);
    cout << "LocalPlayer ptr: 0x" << hex << localPlayer << dec << endl;
    
    if (IsValid(localPlayer)) {
        Vec3 pos = Read<Vec3>(localPlayer + OFF_POSITION);
        int hp = Read<int>(localPlayer + OFF_HEALTH);
        int shield = Read<int>(localPlayer + OFF_SHIELD);
        
        cout << "Position: " << pos.x << ", " << pos.y << ", " << pos.z << endl;
        cout << "Health: " << hp << " | Shield: " << shield << endl;
        
        if (hp > 0 && hp <= 150) {
            cout << "\n[+] SUCCESS! Offsets are working!" << endl;
        } else {
            cout << "\n[?] Health value unusual - may need to update offsets" << endl;
        }
    } else {
        cout << "[!] LocalPlayer is NULL - make sure you're in a match!" << endl;
    }
    
    cout << "\nPress Enter to start radar (or Ctrl+C to exit)...";
    cin.get();
    
    // Radar loop
    while (true) {
        system("cls");
        
        uint64_t lp = Read<uint64_t>(g_Base + OFF_LOCAL_PLAYER);
        if (!IsValid(lp)) {
            cout << "Waiting for match..." << endl;
            Sleep(1000);
            continue;
        }
        
        Vec3 myPos = Read<Vec3>(lp + OFF_POSITION);
        int myTeam = Read<int>(lp + OFF_TEAM);
        int myHp = Read<int>(lp + OFF_HEALTH);
        int myShield = Read<int>(lp + OFF_SHIELD);
        
        cout << "=== APEX RADAR ===" << endl;
        cout << "HP: " << myHp << " | Shield: " << myShield << " | Team: " << myTeam << endl;
        cout << "Pos: " << (int)myPos.x << ", " << (int)myPos.y << endl;
        cout << "==================" << endl;
        
        int enemies = 0;
        for (int i = 0; i < 70; i++) {
            uint64_t ent = Read<uint64_t>(g_Base + OFF_ENTITY_LIST + ((uint64_t)(i & 0xFFFF) << 5));
            if (!IsValid(ent) || ent == lp) continue;
            
            int maxHp = Read<int>(ent + OFF_MAX_HEALTH);
            if (maxHp < 100 || maxHp > 150) continue;
            
            int hp = Read<int>(ent + OFF_HEALTH);
            int team = Read<int>(ent + OFF_TEAM);
            int life = Read<int>(ent + OFF_LIFE_STATE);
            
            if (life != 0 || hp <= 0) continue;  // Dead
            if (team == myTeam) continue;  // Teammate
            
            Vec3 pos = Read<Vec3>(ent + OFF_POSITION);
            int shield = Read<int>(ent + OFF_SHIELD);
            float dist = myPos.Dist(pos);
            
            printf("[ENEMY] HP: %d+%d | Dist: %.0fm\n", hp, shield, dist);
            enemies++;
        }
        
        if (enemies == 0) {
            cout << "No enemies found" << endl;
        }
        
        cout << "\nTotal enemies: " << enemies << endl;
        Sleep(150);
    }
    
    CloseHandle(g_MemFile);
    return 0;
}

Technical Notes & Troubleshooting
This method relies on MemProcFS being active and correctly mapping the memory. If the M: drive is missing, the tool will obviously fail to initialize. Also, reading from .vmem is strictly slower than using the native Vmm.dll functions, but for a 2D radar, the latency is negligible.

Anti-Cheat Context
Since this is 100% DMA, you are physically bypassing the OS kernel for memory access. EAC has a hard time with this unless your firmware is pasted or your TLP (Transaction Layer Packet) signatures are flagged. Keep your firmware private, and don't run a visible overlay on the same machine—use a second PC or a fuser if you want to stay truly safe.

have fun reversing
 
Last edited by a moderator:
Top