Skip to content
MPGHThe Dark Arts
/
RegisterLog in
Forum
Community
What's NewLatest posts across the boardTrendingHottest threads right nowSubscribedThreads you follow
Discussion
GeneralIntroductionsEntertainmentDebate FortFlaming & Rage
Board
News & AnnouncementsMPGH TimesSuggestions & HelpGiveaways
More Sections
Art & Graphic DesignProgrammingHackingCryptocurrency
Hacks & Cheats
Games
ValorantCS2 / CS:GOCall of Duty / WarzoneFortniteApex LegendsEscape From Tarkov
+14 moreLeague of LegendsGTA VMinecraftRustROTMGBattlefieldTroveBattleOnCombat ArmsCrossFireBlackshotRuneScapeDayZDead by Daylight
Resources
Game Hacking TutorialsReverse EngineeringGeneral Game HackingAnti-CheatConsole Game Hacking
Tools
Game Hacking ToolsTrainers & CheatsHack/Release NewsNew
Submit a release →Share your cheat, tool, or config with the community.
AINEW
AI Tools
General & DiscussionPrompt EngineeringLLM JailbreaksHotAI Agents & AutomationLocal / Open Models
AI × Gaming
AI Aimbots & VisionML Anti-CheatGame Bots & Automation
Create
AI Coding / Vibe CodingAI Art & MediaAI Voice & TTS
The AI frontier →Where game hacking meets modern machine learning. Jump in.
Marketplace
Buy & Sell
SellingBuyingTradingUser Services
Trust & Safety
Middleman LoungeMarketplace TalkVouch Copy Profiles
Money
Cryptocurrency TalkCurrency ExchangeWork & Job Offers
Start selling →List accounts, services, and goods. Use the middleman to trade safe.
MPGH The Dark Arts

A community for offensive security research, reverse engineering, and AI.

Community

ForumMarketplaceSearch

Account

RegisterLog in

Legal

Privacy PolicyForum RulesHelp & FAQ
© 2026 MPGH · All rights reserved.Built by the community, for the community. For educational purposes onlyContent is shared for security research and education — we don't condone illegal use. You're responsible for complying with applicable laws. Use at your own risk.
Home › Forum › MultiPlayer Game Hacks & Cheats › Other MMORPG Hacks › Trove Hacks & Cheats › Silent Aim & EntityList

PostSilent Aim & EntityList

Posts 1–15 of 16 · Page 1 of 2
FAISAL32
FAISAL32
Silent Aim & EntityList
i got a lot of requests from people asking about silent aim or EntityList
because there are so many i can’t reply to everyone
so i made this post for everyone to benefit from

first before the explanation starts there are some points to mention
first the explanation will be in c++ cuz most people here know and use it
second using this source is your own responsibility it’s just for explanation only if it causes u a ban that’s not on me
let’s start the explanation now

Explanation of Entity Extraction (GetAllEntities) and Silent Aim System in Trove:

Part 1: ------------Extracting Entities (GetAllEntities)

1- Understanding the Data Structure: Linked List in Game Memory
The game doesn’t store all entities in a single fixed location
Instead, it uses a linked list
Each entity contains a pointer to the next entity
This approach is flexible and allows adding or removing entities without rearranging all memory

2- Finding the Starting Point (Base Address)
Everything starts from the World address in memory
We use a GetAddress function with specific offsets to reach it:
Code:
uintptr_t world = GetAddress(proc, base, {0x11F8514, 0x0});
This address acts like the main key to the game world in memory

3- Accessing the List Info (Node Info)
From world, we go to offset 0x7C to get the linked list info address:
Code:
uintptr_t nodeInfo = GetAddress(hProcess, world, {0x7C});
4- Reading the List Data (Base Address, Size, Step)
Inside nodeInfo we read:

baseAddr: start of the memory region containing entities

size: number of entities

step: byte distance between consecutive entities

Code example:
Code:
ReadValue(hProcess, nodeInfo, "uint", &baseAddr);
ReadValue(hProcess, GetAddress(hProcess, nodeInfo, {0x8}), "uint", &size);
ReadValue(hProcess, GetAddress(hProcess, nodeInfo, {0x4}), "uint", &step);
5- Iterating Through the List to Collect Entity Addresses
Start at baseAddr
Move in increments of step bytes
At each step, read the next pointer to the next element
Continue until you hit a null or invalid pointer
Code:
for (uint32_t i = 0; i < size; ++i) {
    uintptr_t addr = baseAddr + i * step;
    while (addr) {
        uint32_t next = 0;
        if (!ReadValue(hProcess, addr, "uint", &next)) break;
        if (next != 1) nodes.push_back(addr);
        addr = next & ~1u; // Clear lowest bit as flag
    }
}
6- Extracting Each Entity’s Data
For each address in nodes, follow specific offsets to get the actual entity address:
Code:
uintptr_t ent = GetAddress(hProcess, node, {0x10, 0xC4, 0x4, 0x0});
if (!ent) continue;
Then read entity data like position, health, level, etc., similarly

7- Result
The function returns a ready-to-use vector/list of entities for any system you want (tracking, targeting, analysis)

Part 2: ------------Silent Aim System
1- Silent Aim Concept
Instead of moving the camera or mouse to aim, you modify the forward vector used by the game for aiming
This way you hit targets without visible camera movement, making it look legit

2- Allocating Memory in the Game for the Forward Vector
Reserve 3 float slots for X, Y, Z coordinates in the game’s memory using VirtualAllocEx:
Code:
void* addr = VirtualAllocEx(hProcess, nullptr, sizeof(float), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
allocatedSilentAimAddresses[i] = reinterpret_cast<uintptr_t>(addr);
3- Finding the Closest Entity and Targeting
Read player and camera positions
Loop through entities calculating distance
Pick the closest entity within a max range (e.g., 40 units):
Code:
if (dist < closestDist && dist <= MAX_RANGE) {
    closestDist = dist;
    closestEntity = e;
}
4- Calculating the Forward Vector
Compute the vector from camera to target:
Code:
auto [fx, fy, fz] = GetForwardVector(cx, cy, cz, closestEntity.x, closestEntity.y, closestEntity.z);

5- Writing the Vector to Game Memory
Write the negated values (game expects inverted vector):
Code:
WriteFloat(hProcess, allocatedSilentAimAddresses[0], -fx);
WriteFloat(hProcess, allocatedSilentAimAddresses[1], -fy);
WriteFloat(hProcess, allocatedSilentAimAddresses[2], -fz);
6- Patching Game Instructions Using silentAimOffsets With Instruction Signatures
Fixed offsets for movss instructions that read the vector values:
Code:
const std::array<uintptr_t, 3> silentAimOffsets = {
    0x2FDCA3, // F3 0F 10 82 DC 00 00 00  (X component)
    0x2FDCD9, // F3 0F 10 82 E0 00 00 00  (Y component)
    0x2FDD0F  // F3 0F 10 82 E4 00 00 00  (Z component)
};
We patch instructions to point to our new memory addresses:
Code:
BYTE patch[8] = { 0xF3, 0x0F, 0x10, 0x05 }; // movss with absolute address
memcpy(patch + 4, &allocatedSilentAimAddresses[index], 4);
WriteBytes(hProcess, base + silentAimOffsets[index], patch, 8);
7- Why Use This Patching Method?
Cleaner and simpler than manually editing each instruction and calculating relative addresses

Centralizes changes to a fixed memory area

Easy to revert by restoring original instruction bytes stored earlier

8- Cleaning Up Allocated Memory
After done, free allocated memory:
Code:
VirtualFreeEx(hProcess, (LPVOID)allocatedSilentAimAddresses[i], 0, MEM_RELEASE);
Summary:
* Entities extracted by traversing a linked list in game memory step by step

* Silent Aim works by modifying aiming vector, no visible camera movement

* Using fixed offsets and absolute addressing for patching is safe, clean, and reversible

* Proper allocation and freeing of memory ensures stability

finally i wanna say of course i won’t leave u hanging
i made a simple source code and a tool u can use right away or check anything in it
good luck to everyone

 
source code
Code:
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <cstdint>
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cfloat>
#include <array>
#include <cstdint>

// Define localPlayer offset
const uintptr_t localPlayerOffset = 0x11FAD74;

// Blacklist keywords
const std::vector<std::string> blacklist_keywords = {
    "pet", "portal", "abilities", "placeable", "cornerstone",
    "services", "client", "karma", "outpost", "minion", "custom"
};

// Offsets for positions, camera, and silent aim
const std::vector<uintptr_t> positionOffsets = {localPlayerOffset, 0x8, 0x28, 0xC4, 0x4, 0x80};
const std::vector<uintptr_t> camOffsets = {localPlayerOffset, 0x20, 0x70};
const std::array<uintptr_t, 3> silentAimOffsets = {
    0x2FDCA3, // F3 0F 10 82 DC 00 00 00
    0x2FDCD9, // F3 0F 10 82 E0 00 00 00
    0x2FDD0F  // F3 0F 10 82 E4 00 00 00
};

// Max range for targeting entities
const float MAX_RANGE = 40.0f;

struct Entity {
    std::string name;
    float x, y, z;
    float scale;
    int level;
    int death;
    double health;
};

uintptr_t GetAddress(HANDLE hProcess, uintptr_t base, const std::vector<uintptr_t>& offsets) {
    uintptr_t address = base;
    for (size_t i = 0; i + 1 < offsets.size(); ++i) {
        uint32_t tmp = 0;
        if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address + offsets[i]), &tmp, sizeof(tmp), nullptr) || tmp == 0) {
            return 0;
        }
        address = tmp;
    }
    return offsets.empty() ? address : (address + offsets.back());
}

float ReadFloat(HANDLE hProcess, uintptr_t address) {
    float value = 0.0f;
    ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), &value, sizeof(value), nullptr);
    return value;
}

bool WriteFloat(HANDLE hProcess, uintptr_t address, float value) {
    SIZE_T bytesWritten;
    bool result = WriteProcessMemory(hProcess, reinterpret_cast<LPVOID>(address), &value, sizeof(value), &bytesWritten);
    return result && bytesWritten == sizeof(value);
}

std::string ReadString(HANDLE hProcess, uintptr_t address, size_t maxLen) {
    std::vector<char> buffer(maxLen);
    SIZE_T bytesRead;
    if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), buffer.data(), maxLen, &bytesRead)) {
        return {};
    }
    size_t len = 0;
    while (len < bytesRead && buffer[len] != '\0') ++len;
    return std::string(buffer.data(), len);
}

bool ReadValue(HANDLE hProcess, uintptr_t address, const std::string& type, void* out) {
    SIZE_T bytesRead;
    if (type == "float") {
        return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(float), &bytesRead) && bytesRead == sizeof(float);
    } else if (type == "uint") {
        return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(uint32_t), &bytesRead) && bytesRead == sizeof(uint32_t);
    } else if (type == "double") {
        return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(double), &bytesRead) && bytesRead == sizeof(double);
    } else if (type == "int") {
        return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(int32_t), &bytesRead) && bytesRead == sizeof(int32_t);
    }
    return false;
}

std::vector<Entity> GetAllEntities(HANDLE hProcess, uintptr_t world) {
    std::vector<Entity> entities;
    if (!world) return entities;

    uintptr_t nodeInfo = GetAddress(hProcess, world, {0x7C});
    if (!nodeInfo) return entities;

    uint32_t baseAddr = 0;
    ReadValue(hProcess, nodeInfo, "uint", &baseAddr);
    if (!baseAddr) return entities;

    uint32_t size = 0, step = 0;
    uintptr_t sizeAddr = GetAddress(hProcess, nodeInfo, {0x8});
    ReadValue(hProcess, sizeAddr, "uint", &size);
    uintptr_t stepAddr = GetAddress(hProcess, nodeInfo, {0x4});
    ReadValue(hProcess, stepAddr, "uint", &step);

    std::vector<uintptr_t> nodes;
    for (uint32_t i = 0; i < size; ++i) {
        uintptr_t addr = baseAddr + i * step;
        while (addr) {
            uint32_t next = 0;
            if (!ReadValue(hProcess, addr, "uint", &next)) break;
            if (next != 1) nodes.push_back(addr);
            addr = next & ~1u;
        }
    }

    for (auto node : nodes) {
        uintptr_t ent = GetAddress(hProcess, node, {0x10, 0xC4, 0x4, 0x0});
        if (!ent) continue;

        uintptr_t nameAddr = GetAddress(hProcess, ent, {0x58, 0x64, 0x0});
        auto name = ReadString(hProcess, nameAddr, 96);
        if (name.empty()) continue;

        uintptr_t posAddr = GetAddress(hProcess, ent, {0x58, 0xC4, 0x4, 0x80});
        float x=0,y=0,z=0;
        ReadValue(hProcess, posAddr, "float", &x);
        ReadValue(hProcess, posAddr+4, "float", &y);
        ReadValue(hProcess, posAddr+8, "float", &z);

        float scale = 0;
        ReadValue(hProcess, posAddr+0x74, "float", &scale);

        int level = 0;
        uintptr_t lvlAddr = GetAddress(hProcess, ent, {0x58, 0xC4, 0x54, 0x120});
        ReadValue(hProcess, lvlAddr, "int", &level);

        int death = 0;
        uintptr_t deathAddr = GetAddress(hProcess, ent, {0x58, 0x0});
        ReadValue(hProcess, deathAddr, "int", &death);

        double health = 0;
        uintptr_t healthAddr = GetAddress(hProcess, ent, {0x58, 0xC4, 0x84, 0x80});
        ReadValue(hProcess, healthAddr, "double", &health);

        entities.push_back({name, x, y, z, scale, level, death, health});
    }

    std::cout << "\n[Info] Base: 0x" << std::hex << baseAddr << " Size: " << std::dec << size << " Step: " << step << std::endl;
    std::cout << "[Info] Total entities found: " << entities.size() << std::endl;

    return entities;
}

DWORD GetPID(const std::wstring& name) {
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32W e{sizeof(e)};
    if (Process32FirstW(snap, &e)) do {} while (Process32NextW(snap, &e) && name != e.szExeFile);
    CloseHandle(snap);
    return name == e.szExeFile ? e.th32ProcessID : 0;
}

std::tuple<float, float, float> GetForwardVector(float sx, float sy, float sz, float dx, float dy, float dz) {
    float vx = dx - sx;
    float vy = dy - sy;
    float vz = dz - sz;
    float length = sqrt(vx * vx + vy * vy + vz * vz);
    if (length == 0) return {0.0f, 0.0f, 0.0f};
    return {vx / length, vy / length, vz / length};
}

bool ContainsKeyword(const std::string& str, const std::vector<std::string>& keywords) {
    for (const auto& kw : keywords) {
        if (str.find(kw) != std::string::npos) return true;
    }
    return false;
}

// Silent Aim variables
std::array<uintptr_t, 3> allocatedSilentAimAddresses = {0, 0, 0};
std::array<std::vector<BYTE>, 3> originalInstructions;
std::array<uintptr_t, 3> instructionAddresses;

bool AllocateRemoteFloats(HANDLE hProcess) {
    for (int i = 0; i < 3; i++) {
        void* addr = VirtualAllocEx(hProcess, nullptr, sizeof(float), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (!addr) {
            std::cerr << "Allocation failed at index " << i << std::endl;
            return false;
        }
        allocatedSilentAimAddresses[i] = reinterpret_cast<uintptr_t>(addr);
        std::cout << "Allocated memory at: 0x" << std::hex << allocatedSilentAimAddresses[i] << std::endl;
    }
    return true;
}

bool ReadBytes(HANDLE hProcess, uintptr_t address, BYTE* buffer, SIZE_T size) {
    SIZE_T bytesRead;
    return ReadProcessMemory(hProcess, (LPCVOID)address, buffer, size, &bytesRead) && bytesRead == size;
}

bool WriteBytes(HANDLE hProcess, uintptr_t address, BYTE* buffer, SIZE_T size) {
    SIZE_T bytesWritten;
    return WriteProcessMemory(hProcess, (LPVOID)address, buffer, size, &bytesWritten) && bytesWritten == size;
}

bool PatchMovssInstruction(HANDLE hProcess, int index, uintptr_t baseAddress) {
    uintptr_t instrAddr = baseAddress + silentAimOffsets[index];
    instructionAddresses[index] = instrAddr;

    std::vector<BYTE> orig(8);
    if (!ReadBytes(hProcess, instrAddr, orig.data(), 8)) {
        std::cerr << "Failed to read original instruction at " << std::hex << instrAddr << std::endl;
        return false;
    }
    originalInstructions[index] = orig;

    // Patch bytes f3 0f 10 05 + 4 bytes relative address
    BYTE patch[8] = { 0xF3, 0x0F, 0x10, 0x05 }; // movss instruction
    uint32_t absAddr = static_cast<uint32_t>(allocatedSilentAimAddresses[index]); // Absolute address
    memcpy(patch + 4, &absAddr, sizeof(absAddr)); // Write absolute address in bytes

    if (!WriteBytes(hProcess, instrAddr, patch, 8)) {
        std::cerr << "Failed to write patch at " << std::hex << instrAddr << std::endl;
        return false;
    }

    std::cout << "Patched movss at 0x" << std::hex << instrAddr << " to point to 0x" << allocatedSilentAimAddresses[index] << std::endl;
    return true;
}

void RestoreOriginalInstructions(HANDLE hProcess) {
    for (int i = 0; i < 3; i++) {
        if (!originalInstructions[i].empty() && instructionAddresses[i] != 0) {
            WriteBytes(hProcess, instructionAddresses[i], originalInstructions[i].data(), originalInstructions[i].size());
            std::cout << "Restored original instruction at 0x" << std::hex << instructionAddresses[i] << std::endl;
        }
    }
}

void FreeAllocatedMemory(HANDLE hProcess) {
    for (int i = 0; i < 3; i++) {
        if (allocatedSilentAimAddresses[i]) {
            VirtualFreeEx(hProcess, (LPVOID)allocatedSilentAimAddresses[i], 0, MEM_RELEASE);
            std::cout << "Freed memory at 0x" << std::hex << allocatedSilentAimAddresses[i] << std::endl;
            allocatedSilentAimAddresses[i] = 0;
        }
    }
}

void WriteSilentAimVector(HANDLE hProcess, float fx, float fy, float fz) {
    if (!allocatedSilentAimAddresses[0] || !allocatedSilentAimAddresses[1] || !allocatedSilentAimAddresses[2]) {
        std::cerr << "Silent Aim addresses not allocated" << std::endl;
        return;
    }

    std::cout << "Writing Silent Aim vector to addresses: "
              << std::hex
              << "X: 0x" << allocatedSilentAimAddresses[0] << " "
              << "Y: 0x" << allocatedSilentAimAddresses[1] << " "
              << "Z: 0x" << allocatedSilentAimAddresses[2] << std::dec << std::endl;

    if (!WriteFloat(hProcess, allocatedSilentAimAddresses[0], -fx) ||
        !WriteFloat(hProcess, allocatedSilentAimAddresses[1], -fy) ||
        !WriteFloat(hProcess, allocatedSilentAimAddresses[2], -fz)) {
        std::cerr << "Failed to write Silent Aim vector values" << std::endl;
    }
}

int main() {
    DWORD pid = GetPID(L"Trove.exe");
    if (!pid) {
        std::cerr << "Failed to find Trove.exe process." << std::endl;
        return 1;
    }

    HANDLE proc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (!proc) {
        std::cerr << "Failed to open Trove.exe process." << std::endl;
        return 1;
    }

    HMODULE mods[1024]; DWORD needed;
    EnumProcessModules(proc, mods, sizeof(mods), &needed);
    uintptr_t base = reinterpret_cast<uintptr_t>(mods[0]);

    if (!AllocateRemoteFloats(proc)) {
        std::cerr << "Failed to allocate memory for Silent Aim" << std::endl;
        CloseHandle(proc);
        return 1;
    }
    for (int i = 0; i < 3; i++) {
        if (!PatchMovssInstruction(proc, i, base)) {
            std::cerr << "Failed to patch movss instruction" << std::endl;
            RestoreOriginalInstructions(proc);
            FreeAllocatedMemory(proc);
            CloseHandle(proc);
            return 1;
        }
    }
    std::cout << "Silent Aim initialized successfully" << std::endl;

    while (true) {
        uintptr_t localPlayer = GetAddress(proc, base, {localPlayerOffset});
        uintptr_t playerPosPtr = GetAddress(proc, base, positionOffsets);
        uintptr_t camPtr = GetAddress(proc, base, camOffsets);
    
        uintptr_t world = GetAddress(proc, base, {0x11F8514, 0x0});
        auto allEntities = GetAllEntities(proc, world);
    
        std::vector<Entity> filteredEntities;
        for (const auto& e : allEntities) {
            if (!ContainsKeyword(e.name, blacklist_keywords)) {
                filteredEntities.push_back(e);
            }
        }
    
        float px = ReadFloat(proc, playerPosPtr);
        float py = ReadFloat(proc, playerPosPtr + 4);
        float pz = ReadFloat(proc, playerPosPtr + 8);
    
        float cx = ReadFloat(proc, camPtr);
        float cy = ReadFloat(proc, camPtr + 4);
        float cz = ReadFloat(proc, camPtr + 8);
    
        // Print player and camera coordinates
        std::cout << "[PlayerPos] x: " << px << ", y: " << py << ", z: " << pz << std::endl;
        std::cout << "[CamPos] x: " << cx << ", y: " << cy << ", z: " << cz << std::endl;
    
        float closestDist = FLT_MAX;
        Entity closestEntity = {"", 0, 0, 0, 0, 0, 0, 0.0};
        bool found = false;
        for (const auto& e : filteredEntities) {
            float dx = e.x - px;
            float dy = e.y - py;
            float dz = e.z - pz;
            float dist = sqrt(dx * dx + dy * dy + dz * dz);
            if (dist < closestDist && dist <= MAX_RANGE) {
                closestDist = dist;
                closestEntity = e;
                found = true;
            }
        }
    
        if (found) {
            auto [fx, fy, fz] = GetForwardVector(cx, cy, cz, closestEntity.x, closestEntity.y, closestEntity.z);
            WriteSilentAimVector(proc, fx, fy, fz);
    
            std::cout << "[SilentAim] Target: " << closestEntity.name << " Vector: (" << fx << ", " << fy << ", " << fz << ") Distance: " << closestDist << std::endl;
        } else {
            std::cout << "No valid entity found for Silent Aim within range " << MAX_RANGE << ".\n";
        }
    
        Sleep(10);
    }

    RestoreOriginalInstructions(proc);
    FreeAllocatedMemory(proc);

    CloseHandle(proc);
    return 0;
}
#1 · 1y ago
28
2837164889
I don't know where the problem lies, whether it's a permission modification issue or
// troveaim.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#pragma warning(disable: 4067) // 忽略警告
#pragma clang diagnostic ignored "-Wc++17-extensions"
#define _HAS_CXX17 1
#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WAR NING
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <cstdint>
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cfloat>
#include <array>
#include <cstdint>

// Define localPlayer offset
const uintptr_t localPlayerOffset = 0x1098438;

// Blacklist keywords
const std::vector<std::string> blacklist_keywords = {
"pet", "portal", "abilities", "placeable", "cornerstone",
"services", "client", "karma", "outpost", "minion", "custom"
};

// Offsets for positions, camera, and silent aim
const std::vector<uintptr_t> positionOffsets = { localPlayerOffset, 0x8, 0x28, 0xC4, 0x4, 0x80 };
const std::vector<uintptr_t> camOffsets = { localPlayerOffset, 0x20, 0x70 };
const std::array<uintptr_t, 3> silentAimOffsets = {
0x3FAEB3, // F3 0F 10 82 DC 00 00 00
0x3FAEE9, // F3 0F 10 82 E0 00 00 00
0x3FAF1F // F3 0F 10 82 E4 00 00 00
};

// Max range for targeting entities
const float MAX_RANGE = 40.0f;

struct Entity {
std::string name;
float x, y, z;
float scale;
int level;
int death;
double health;
};

uintptr_t GetAddress(HANDLE hProcess, uintptr_t base, const std::vector<uintptr_t>& offsets) {
uintptr_t address = base;
for (size_t i = 0; i + 1 < offsets.size(); ++i) {
uint32_t tmp = 0;
if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address + offsets[i]), &tmp, sizeof(tmp), nullptr) || tmp == 0) {
return 0;
}
address = tmp;
}
return offsets.empty() ? address : (address + offsets.back());
}

float ReadFloat(HANDLE hProcess, uintptr_t address) {
float value = 0.0f;
ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), &value, sizeof(value), nullptr);
return value;
}

bool WriteFloat(HANDLE hProcess, uintptr_t address, float value) {
SIZE_T bytesWritten;
bool result = WriteProcessMemory(hProcess, reinterpret_cast<LPVOID>(address), &value, sizeof(value), &bytesWritten);
return result && bytesWritten == sizeof(value);
}

std::string ReadString(HANDLE hProcess, uintptr_t address, size_t maxLen) {
std::vector<char> buffer(maxLen);
SIZE_T bytesRead;
if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), buffer.data(), maxLen, &bytesRead)) {
return {};
}
size_t len = 0;
while (len < bytesRead && buffer[len] != '\0') ++len;
return std::string(buffer.data(), len);
}

bool ReadValue(HANDLE hProcess, uintptr_t address, const std::string& type, void* out) {
SIZE_T bytesRead;
if (type == "float") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(float), &bytesRead) && bytesRead == sizeof(float);
}
else if (type == "uint") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(uint32_t), &bytesRead) && bytesRead == sizeof(uint32_t);
}
else if (type == "double") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(double), &bytesRead) && bytesRead == sizeof(double);
}
else if (type == "int") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(int32_t), &bytesRead) && bytesRead == sizeof(int32_t);
}
return false;
}

std::vector<Entity> GetAllEntities(HANDLE hProcess, uintptr_t world) {
std::vector<Entity> entities;
if (!world) return entities;

uintptr_t nodeInfo = GetAddress(hProcess, world, { 0x7C });
if (!nodeInfo) return entities;

uint32_t baseAddr = 0;
ReadValue(hProcess, nodeInfo, "uint", &baseAddr);
if (!baseAddr) return entities;

uint32_t size = 0, step = 0;
uintptr_t sizeAddr = GetAddress(hProcess, nodeInfo, { 0x8 });
ReadValue(hProcess, sizeAddr, "uint", &size);
uintptr_t stepAddr = GetAddress(hProcess, nodeInfo, { 0x4 });
ReadValue(hProcess, stepAddr, "uint", &step);

std::vector<uintptr_t> nodes;
for (uint32_t i = 0; i < size; ++i) {
uintptr_t addr = baseAddr + i * step;
while (addr) {
uint32_t next = 0;
if (!ReadValue(hProcess, addr, "uint", &next)) break;
if (next != 1) nodes.push_back(addr);
addr = next & ~1u;
}
}

for (auto node : nodes) {
uintptr_t ent = GetAddress(hProcess, node, { 0x10, 0xC4, 0x4, 0x0 });
if (!ent) continue;

uintptr_t nameAddr = GetAddress(hProcess, ent, { 0x58, 0x64, 0x0 });
auto name = ReadString(hProcess, nameAddr, 96);
if (name.empty()) continue;

uintptr_t posAddr = GetAddress(hProcess, ent, { 0x58, 0xC4, 0x4, 0x80 });
float x = 0, y = 0, z = 0;
ReadValue(hProcess, posAddr, "float", &x);
ReadValue(hProcess, posAddr + 4, "float", &y);
ReadValue(hProcess, posAddr + 8, "float", &z);

float scale = 0;
ReadValue(hProcess, posAddr + 0x74, "float", &scale);

int level = 0;
uintptr_t lvlAddr = GetAddress(hProcess, ent, { 0x58, 0xC4, 0x54, 0x120 });
ReadValue(hProcess, lvlAddr, "int", &level);

int death = 0;
uintptr_t deathAddr = GetAddress(hProcess, ent, { 0x58, 0x0 });
ReadValue(hProcess, deathAddr, "int", &death);

double health = 0;
uintptr_t healthAddr = GetAddress(hProcess, ent, { 0x58, 0xC4, 0x84, 0x80 });
ReadValue(hProcess, healthAddr, "double", &health);

entities.push_back({ name, x, y, z, scale, level, death, health });
}

std::cout << "\n[Info] Base: 0x" << std::hex << baseAddr << " Size: " << std::dec << size << " Step: " << step << std::endl;
std::cout << "[Info] Total entities found: " << entities.size() << std::endl;

return entities;
}

DWORD GetPID(const std::wstring& name) {
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W e{ sizeof(e) };
if (Process32FirstW(snap, &e)) do {} while (Process32NextW(snap, &e) && name != e.szExeFile);
CloseHandle(snap);
return name == e.szExeFile ? e.th32ProcessID : 0;
}

std::tuple<float, float, float> GetForwardVector(float sx, float sy, float sz, float dx, float dy, float dz) {
float vx = dx - sx;
float vy = dy - sy;
float vz = dz - sz;
float length = sqrt(vx * vx + vy * vy + vz * vz);
if (length == 0) return { 0.0f, 0.0f, 0.0f };
return { vx / length, vy / length, vz / length };
}

bool ContainsKeyword(const std::string& str, const std::vector<std::string>& keywords) {
for (const auto& kw : keywords) {
if (str.find(kw) != std::string::npos) return true;
}
return false;
}

// Silent Aim variables
std::array<uintptr_t, 3> allocatedSilentAimAddresses = { 0, 0, 0 };
std::array<std::vector<BYTE>, 3> originalInstructions;
std::array<uintptr_t, 3> instructionAddresses;

bool AllocateRemoteFloats(HANDLE hProcess) {
for (int i = 0; i < 3; i++) {
void* addr = VirtualAllocEx(hProcess, nullptr, sizeof(float), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!addr) {
std::cerr << "索引处分配失败 " << i << std::endl;
return false;
}
allocatedSilentAimAddresses[i] = reinterpret_cast<uintptr_t>(addr);
std::cout << "分配的内存在: 0x" << std::hex << allocatedSilentAimAddresses[i] << std::endl;
}
return true;
}

bool ReadBytes(HANDLE hProcess, uintptr_t address, BYTE* buffer, SIZE_T size) {
SIZE_T bytesRead;
return ReadProcessMemory(hProcess, (LPCVOID)address, buffer, size, &bytesRead) && bytesRead == size;
}

bool WriteBytes(HANDLE hProcess, uintptr_t address, BYTE* buffer, SIZE_T size) {
SIZE_T bytesWritten;
return WriteProcessMemory(hProcess, (LPVOID)address, buffer, size, &bytesWritten) && bytesWritten == size;
}

bool PatchMovssInstruction(HANDLE hProcess, int index, uintptr_t baseAddress) {
uintptr_t instrAddr = baseAddress + silentAimOffsets[index];
instructionAddresses[index] = instrAddr;

std::vector<BYTE> orig(8);
if (!ReadBytes(hProcess, instrAddr, orig.data(), 8)) {
std::cerr << "无法读取原始指令 " << std::hex << instrAddr << std::endl;
return false;
}
originalInstructions[index] = orig;

// Patch bytes f3 0f 10 05 + 4 bytes relative address
BYTE patch[8] = { 0xF3, 0x0F, 0x10, 0x05 }; // movss instruction
uint32_t absAddr = static_cast<uint32_t>(allocatedSilentAimAddresses[index]); // Absolute address
memcpy(patch + 4, &absAddr, sizeof(absAddr)); // Write absolute address in bytes

if (!WriteBytes(hProcess, instrAddr, patch, 8)) {
std::cerr << "未能在此处写补丁 " << std::hex << instrAddr << std::endl;
return false;
}

std::cout << "修补的 movss 在 0x" << std::hex << instrAddr << " 指向 0x" << allocatedSilentAimAddresses[index] << std::endl;
return true;
}

void RestoreOriginalInstructions(HANDLE hProcess) {
for (int i = 0; i < 3; i++) {
if (!originalInstructions[i].empty() && instructionAddresses[i] != 0) {
WriteBytes(hProcess, instructionAddresses[i], originalInstructions[i].data(), originalInstructions[i].size());
std::cout << "恢复原始指令于 0x" << std::hex << instructionAddresses[i] << std::endl;
}
}
}

void FreeAllocatedMemory(HANDLE hProcess) {
for (int i = 0; i < 3; i++) {
if (allocatedSilentAimAddresses[i]) {
VirtualFreeEx(hProcess, (LPVOID)allocatedSilentAimAddresses[i], 0, MEM_RELEASE);
std::cout << "释放的内存在 0x" << std::hex << allocatedSilentAimAddresses[i] << std::endl;
allocatedSilentAimAddresses[i] = 0;
}
}
}

void WriteSilentAimVector(HANDLE hProcess, float fx, float fy, float fz) {
if (!allocatedSilentAimAddresses[0] || !allocatedSilentAimAddresses[1] || !allocatedSilentAimAddresses[2]) {
std::cerr << "静默瞄准地址未分配" << std::endl;
return;
}

std::cout << "将静默目标向量写入地址: "
<< std::hex
<< "X: 0x" << allocatedSilentAimAddresses[0] << " "
<< "Y: 0x" << allocatedSilentAimAddresses[1] << " "
<< "Z: 0x" << allocatedSilentAimAddresses[2] << std::dec << std::endl;

if (!WriteFloat(hProcess, allocatedSilentAimAddresses[0], -fx) ||
!WriteFloat(hProcess, allocatedSilentAimAddresses[1], -fy) ||
!WriteFloat(hProcess, allocatedSilentAimAddresses[2], -fz)) {
std::cerr << "无法写入静默瞄准向量值" << std::endl;
}
}

int main() {
int world = 0x10984B0;
DWORD pid = GetPID(L"Trove.exe");
if (!pid) {
std::cerr << "没找到宝藏世界进程." << std::endl;
return 1;
}

HANDLE proc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!proc) {
std::cerr << "无法打开宝藏世界进程." << std::endl;
return 1;
}

HMODULE mods[1024]; DWORD needed;
EnumProcessModules(proc, mods, sizeof(mods), &needed);
uintptr_t base = reinterpret_cast<uintptr_t>(mods[0]);

if (!AllocateRemoteFloats(proc)) {
std::cerr << "分配内存以进行静默瞄准失败" << std::endl;
CloseHandle(proc);
return 1;
}
for (int i = 0; i < 3; i++) {
if (!PatchMovssInstruction(proc, i, base)) {
std::cerr << "无法修补movss指令" << std::endl;
RestoreOriginalInstructions(proc);
FreeAllocatedMemory(proc);
CloseHandle(proc);
return 1;
}
}
std::cout << "静默瞄准成功初始化" << std::endl;

while (true) {
uintptr_t localPlayer = GetAddress(proc, base, { localPlayerOffset });
uintptr_t playerPosPtr = GetAddress(proc, base, positionOffsets);
uintptr_t camPtr = GetAddress(proc, base, camOffsets);

uintptr_t world = GetAddress(proc, base, { 0x10984B0, 0x0 });//世界指针
auto allEntities = GetAllEntities(proc, world);

std::vector<Entity> filteredEntities;
for (const auto& e : allEntities) {
if (!ContainsKeyword(e.name, blacklist_keywords)) {
filteredEntities.push_back(e);
}
}

float px = ReadFloat(proc, playerPosPtr);
float py = ReadFloat(proc, playerPosPtr + 4);
float pz = ReadFloat(proc, playerPosPtr + 8);

float cx = ReadFloat(proc, camPtr);
float cy = ReadFloat(proc, camPtr + 4);
float cz = ReadFloat(proc, camPtr + 8);

// Print player and camera coordinates
std::cout << "[PlayerPos] x: " << px << ", y: " << py << ", z: " << pz << std::endl;
std::cout << "[CamPos] x: " << cx << ", y: " << cy << ", z: " << cz << std::endl;

float closestDist = FLT_MAX;
Entity closestEntity = { "", 0, 0, 0, 0, 0, 0, 0.0 };
bool found = false;
for (const auto& e : filteredEntities) {
float dx = e.x - px;
float dy = e.y - py;
float dz = e.z - pz;
float dist = sqrt(dx * dx + dy * dy + dz * dz);
if (dist < closestDist && dist <= MAX_RANGE) {
closestDist = dist;
closestEntity = e;
found = true;
}
}

if (found) {
auto [fx, fy, fz] = GetForwardVector(cx, cy, cz, closestEntity.x, closestEntity.y, closestEntity.z);
WriteSilentAimVector(proc, fx, fy, fz);

std::cout << "[SilentAim] 目标: " << closestEntity.name << " 向量: (" << fx << ", " << fy << ", " << fz << ") 距离: " << closestDist << std::endl;
}
else {
std::cout << "在范围内未找到有效的静音瞄准实体" << MAX_RANGE << ".\n";
}

Sleep(10);
}

RestoreOriginalInstructions(proc);
FreeAllocatedMemory(proc);

CloseHandle(proc);
return 0;
}
#2 · 1y ago
FAISAL32
FAISAL32
Quote Originally Posted by 2837164889 View Post
// troveaim.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#pragma warning(disable: 4067) // 忽略警告
#pragma clang diagnostic ignored "-Wc++17-extensions"
#define _HAS_CXX17 1
#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WAR NING
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <cstdint>
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cfloat>
#include <array>
#include <cstdint>

// Define localPlayer offset
const uintptr_t localPlayerOffset = 0x1098438;

// Blacklist keywords
const std::vector<std::string> blacklist_keywords = {
"pet", "portal", "abilities", "placeable", "cornerstone",
"services", "client", "karma", "outpost", "minion", "custom"
};

// Offsets for positions, camera, and silent aim
const std::vector<uintptr_t> positionOffsets = { localPlayerOffset, 0x8, 0x28, 0xC4, 0x4, 0x80 };
const std::vector<uintptr_t> camOffsets = { localPlayerOffset, 0x20, 0x70 };
const std::array<uintptr_t, 3> silentAimOffsets = {
0x3FAEB3, // F3 0F 10 82 DC 00 00 00
0x3FAEE9, // F3 0F 10 82 E0 00 00 00
0x3FAF1F // F3 0F 10 82 E4 00 00 00
};

// Max range for targeting entities
const float MAX_RANGE = 40.0f;

struct Entity {
std::string name;
float x, y, z;
float scale;
int level;
int death;
double health;
};

uintptr_t GetAddress(HANDLE hProcess, uintptr_t base, const std::vector<uintptr_t>& offsets) {
uintptr_t address = base;
for (size_t i = 0; i + 1 < offsets.size(); ++i) {
uint32_t tmp = 0;
if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address + offsets[i]), &tmp, sizeof(tmp), nullptr) || tmp == 0) {
return 0;
}
address = tmp;
}
return offsets.empty() ? address : (address + offsets.back());
}

float ReadFloat(HANDLE hProcess, uintptr_t address) {
float value = 0.0f;
ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), &value, sizeof(value), nullptr);
return value;
}

bool WriteFloat(HANDLE hProcess, uintptr_t address, float value) {
SIZE_T bytesWritten;
bool result = WriteProcessMemory(hProcess, reinterpret_cast<LPVOID>(address), &value, sizeof(value), &bytesWritten);
return result && bytesWritten == sizeof(value);
}

std::string ReadString(HANDLE hProcess, uintptr_t address, size_t maxLen) {
std::vector<char> buffer(maxLen);
SIZE_T bytesRead;
if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), buffer.data(), maxLen, &bytesRead)) {
return {};
}
size_t len = 0;
while (len < bytesRead && buffer[len] != '\0') ++len;
return std::string(buffer.data(), len);
}

bool ReadValue(HANDLE hProcess, uintptr_t address, const std::string& type, void* out) {
SIZE_T bytesRead;
if (type == "float") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(float), &bytesRead) && bytesRead == sizeof(float);
}
else if (type == "uint") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(uint32_t), &bytesRead) && bytesRead == sizeof(uint32_t);
}
else if (type == "double") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(double), &bytesRead) && bytesRead == sizeof(double);
}
else if (type == "int") {
return ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(address), out, sizeof(int32_t), &bytesRead) && bytesRead == sizeof(int32_t);
}
return false;
}

std::vector<Entity> GetAllEntities(HANDLE hProcess, uintptr_t world) {
std::vector<Entity> entities;
if (!world) return entities;

uintptr_t nodeInfo = GetAddress(hProcess, world, { 0x7C });
if (!nodeInfo) return entities;

uint32_t baseAddr = 0;
ReadValue(hProcess, nodeInfo, "uint", &baseAddr);
if (!baseAddr) return entities;

uint32_t size = 0, step = 0;
uintptr_t sizeAddr = GetAddress(hProcess, nodeInfo, { 0x8 });
ReadValue(hProcess, sizeAddr, "uint", &size);
uintptr_t stepAddr = GetAddress(hProcess, nodeInfo, { 0x4 });
ReadValue(hProcess, stepAddr, "uint", &step);

std::vector<uintptr_t> nodes;
for (uint32_t i = 0; i < size; ++i) {
uintptr_t addr = baseAddr + i * step;
while (addr) {
uint32_t next = 0;
if (!ReadValue(hProcess, addr, "uint", &next)) break;
if (next != 1) nodes.push_back(addr);
addr = next & ~1u;
}
}

for (auto node : nodes) {
uintptr_t ent = GetAddress(hProcess, node, { 0x10, 0xC4, 0x4, 0x0 });
if (!ent) continue;

uintptr_t nameAddr = GetAddress(hProcess, ent, { 0x58, 0x64, 0x0 });
auto name = ReadString(hProcess, nameAddr, 96);
if (name.empty()) continue;

uintptr_t posAddr = GetAddress(hProcess, ent, { 0x58, 0xC4, 0x4, 0x80 });
float x = 0, y = 0, z = 0;
ReadValue(hProcess, posAddr, "float", &x);
ReadValue(hProcess, posAddr + 4, "float", &y);
ReadValue(hProcess, posAddr + 8, "float", &z);

float scale = 0;
ReadValue(hProcess, posAddr + 0x74, "float", &scale);

int level = 0;
uintptr_t lvlAddr = GetAddress(hProcess, ent, { 0x58, 0xC4, 0x54, 0x120 });
ReadValue(hProcess, lvlAddr, "int", &level);

int death = 0;
uintptr_t deathAddr = GetAddress(hProcess, ent, { 0x58, 0x0 });
ReadValue(hProcess, deathAddr, "int", &death);

double health = 0;
uintptr_t healthAddr = GetAddress(hProcess, ent, { 0x58, 0xC4, 0x84, 0x80 });
ReadValue(hProcess, healthAddr, "double", &health);

entities.push_back({ name, x, y, z, scale, level, death, health });
}

std::cout << "\n[Info] Base: 0x" << std::hex << baseAddr << " Size: " << std::dec << size << " Step: " << step << std::endl;
std::cout << "[Info] Total entities found: " << entities.size() << std::endl;

return entities;
}

DWORD GetPID(const std::wstring& name) {
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W e{ sizeof(e) };
if (Process32FirstW(snap, &e)) do {} while (Process32NextW(snap, &e) && name != e.szExeFile);
CloseHandle(snap);
return name == e.szExeFile ? e.th32ProcessID : 0;
}

std::tuple<float, float, float> GetForwardVector(float sx, float sy, float sz, float dx, float dy, float dz) {
float vx = dx - sx;
float vy = dy - sy;
float vz = dz - sz;
float length = sqrt(vx * vx + vy * vy + vz * vz);
if (length == 0) return { 0.0f, 0.0f, 0.0f };
return { vx / length, vy / length, vz / length };
}

bool ContainsKeyword(const std::string& str, const std::vector<std::string>& keywords) {
for (const auto& kw : keywords) {
if (str.find(kw) != std::string::npos) return true;
}
return false;
}

// Silent Aim variables
std::array<uintptr_t, 3> allocatedSilentAimAddresses = { 0, 0, 0 };
std::array<std::vector<BYTE>, 3> originalInstructions;
std::array<uintptr_t, 3> instructionAddresses;

bool AllocateRemoteFloats(HANDLE hProcess) {
for (int i = 0; i < 3; i++) {
void* addr = VirtualAllocEx(hProcess, nullptr, sizeof(float), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!addr) {
std::cerr << "索引处分配失败 " << i << std::endl;
return false;
}
allocatedSilentAimAddresses[i] = reinterpret_cast<uintptr_t>(addr);
std::cout << "分配的内存在: 0x" << std::hex << allocatedSilentAimAddresses[i] << std::endl;
}
return true;
}

bool ReadBytes(HANDLE hProcess, uintptr_t address, BYTE* buffer, SIZE_T size) {
SIZE_T bytesRead;
return ReadProcessMemory(hProcess, (LPCVOID)address, buffer, size, &bytesRead) && bytesRead == size;
}

bool WriteBytes(HANDLE hProcess, uintptr_t address, BYTE* buffer, SIZE_T size) {
SIZE_T bytesWritten;
return WriteProcessMemory(hProcess, (LPVOID)address, buffer, size, &bytesWritten) && bytesWritten == size;
}

bool PatchMovssInstruction(HANDLE hProcess, int index, uintptr_t baseAddress) {
uintptr_t instrAddr = baseAddress + silentAimOffsets[index];
instructionAddresses[index] = instrAddr;

std::vector<BYTE> orig(8);
if (!ReadBytes(hProcess, instrAddr, orig.data(), 8)) {
std::cerr << "无法读取原始指令 " << std::hex << instrAddr << std::endl;
return false;
}
originalInstructions[index] = orig;

// Patch bytes f3 0f 10 05 + 4 bytes relative address
BYTE patch[8] = { 0xF3, 0x0F, 0x10, 0x05 }; // movss instruction
uint32_t absAddr = static_cast<uint32_t>(allocatedSilentAimAddresses[index]); // Absolute address
memcpy(patch + 4, &absAddr, sizeof(absAddr)); // Write absolute address in bytes

if (!WriteBytes(hProcess, instrAddr, patch, 8)) {
std::cerr << "未能在此处写补丁 " << std::hex << instrAddr << std::endl;
return false;
}

std::cout << "修补的 movss 在 0x" << std::hex << instrAddr << " 指向 0x" << allocatedSilentAimAddresses[index] << std::endl;
return true;
}

void RestoreOriginalInstructions(HANDLE hProcess) {
for (int i = 0; i < 3; i++) {
if (!originalInstructions[i].empty() && instructionAddresses[i] != 0) {
WriteBytes(hProcess, instructionAddresses[i], originalInstructions[i].data(), originalInstructions[i].size());
std::cout << "恢复原始指令于 0x" << std::hex << instructionAddresses[i] << std::endl;
}
}
}

void FreeAllocatedMemory(HANDLE hProcess) {
for (int i = 0; i < 3; i++) {
if (allocatedSilentAimAddresses[i]) {
VirtualFreeEx(hProcess, (LPVOID)allocatedSilentAimAddresses[i], 0, MEM_RELEASE);
std::cout << "释放的内存在 0x" << std::hex << allocatedSilentAimAddresses[i] << std::endl;
allocatedSilentAimAddresses[i] = 0;
}
}
}

void WriteSilentAimVector(HANDLE hProcess, float fx, float fy, float fz) {
if (!allocatedSilentAimAddresses[0] || !allocatedSilentAimAddresses[1] || !allocatedSilentAimAddresses[2]) {
std::cerr << "静默瞄准地址未分配" << std::endl;
return;
}

std::cout << "将静默目标向量写入地址: "
<< std::hex
<< "X: 0x" << allocatedSilentAimAddresses[0] << " "
<< "Y: 0x" << allocatedSilentAimAddresses[1] << " "
<< "Z: 0x" << allocatedSilentAimAddresses[2] << std::dec << std::endl;

if (!WriteFloat(hProcess, allocatedSilentAimAddresses[0], -fx) ||
!WriteFloat(hProcess, allocatedSilentAimAddresses[1], -fy) ||
!WriteFloat(hProcess, allocatedSilentAimAddresses[2], -fz)) {
std::cerr << "无法写入静默瞄准向量值" << std::endl;
}
}

int main() {
int world = 0x10984B0;
DWORD pid = GetPID(L"Trove.exe");
if (!pid) {
std::cerr << "没找到宝藏世界进程." << std::endl;
return 1;
}

HANDLE proc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!proc) {
std::cerr << "无法打开宝藏世界进程." << std::endl;
return 1;
}

HMODULE mods[1024]; DWORD needed;
EnumProcessModules(proc, mods, sizeof(mods), &needed);
uintptr_t base = reinterpret_cast<uintptr_t>(mods[0]);

if (!AllocateRemoteFloats(proc)) {
std::cerr << "分配内存以进行静默瞄准失败" << std::endl;
CloseHandle(proc);
return 1;
}
for (int i = 0; i < 3; i++) {
if (!PatchMovssInstruction(proc, i, base)) {
std::cerr << "无法修补movss指令" << std::endl;
RestoreOriginalInstructions(proc);
FreeAllocatedMemory(proc);
CloseHandle(proc);
return 1;
}
}
std::cout << "静默瞄准成功初始化" << std::endl;

while (true) {
uintptr_t localPlayer = GetAddress(proc, base, { localPlayerOffset });
uintptr_t playerPosPtr = GetAddress(proc, base, positionOffsets);
uintptr_t camPtr = GetAddress(proc, base, camOffsets);

uintptr_t world = GetAddress(proc, base, { 0x10984B0, 0x0 });//世界指针
auto allEntities = GetAllEntities(proc, world);

std::vector<Entity> filteredEntities;
for (const auto& e : allEntities) {
if (!ContainsKeyword(e.name, blacklist_keywords)) {
filteredEntities.push_back(e);
}
}

float px = ReadFloat(proc, playerPosPtr);
float py = ReadFloat(proc, playerPosPtr + 4);
float pz = ReadFloat(proc, playerPosPtr + 8);

float cx = ReadFloat(proc, camPtr);
float cy = ReadFloat(proc, camPtr + 4);
float cz = ReadFloat(proc, camPtr + 8);

// Print player and camera coordinates
std::cout << "[PlayerPos] x: " << px << ", y: " << py << ", z: " << pz << std::endl;
std::cout << "[CamPos] x: " << cx << ", y: " << cy << ", z: " << cz << std::endl;

float closestDist = FLT_MAX;
Entity closestEntity = { "", 0, 0, 0, 0, 0, 0, 0.0 };
bool found = false;
for (const auto& e : filteredEntities) {
float dx = e.x - px;
float dy = e.y - py;
float dz = e.z - pz;
float dist = sqrt(dx * dx + dy * dy + dz * dz);
if (dist < closestDist && dist <= MAX_RANGE) {
closestDist = dist;
closestEntity = e;
found = true;
}
}

if (found) {
auto [fx, fy, fz] = GetForwardVector(cx, cy, cz, closestEntity.x, closestEntity.y, closestEntity.z);
WriteSilentAimVector(proc, fx, fy, fz);

std::cout << "[SilentAim] 目标: " << closestEntity.name << " 向量: (" << fx << ", " << fy << ", " << fz << ") 距离: " << closestDist << std::endl;
}
else {
std::cout << "在范围内未找到有效的静音瞄准实体" << MAX_RANGE << ".\n";
}

Sleep(10);
}

RestoreOriginalInstructions(proc);
FreeAllocatedMemory(proc);

CloseHandle(proc);
return 0;
}
The code looks great, I don't see any errors in it

but the issue is with your SilentAimOffsets
I’m not sure how you got those addresses
but they’re supposed to look like this instead

Code:
const std::array<uintptr_t, 3> silentAimOffsets = {
    0x2DAEB3, // F3 0F 10 82 DC 00 00 00
    0x2DAEE9, // F3 0F 10 82 E0 00 00 00
    0x2DAF1F // F3 0F 10 82 E4 00 00 00
};
also bro, I already added a comment with their signature
you can use it to find them yourself
#3 · 1y ago
28
2837164889
The game crashed.
Thank you, brother. My address was wrong, your code was correct. You've worked hard! Thank you very much!
bool PatchMovssInstruction(HANDLE hProcess, int index, uintptr_t baseAddress) {
//uintptr_t instrAddr = baseAddress + silentAimOffsets[index];
uintptr_t instrAddr = silentAimOffsets[index];
//Moreover, I just realized that the relative path added here is the reason why I was wondering why mine had no effect.
Still, I really appreciate you sharing the code.
#4 · edited 1y ago · 1y ago
SI
sillybean42
The New SilentAim pointer seem to be:
0x012B9640
0x012B9678
0x012B96AC

but its still not working for me. i know i got the right world and player pointers,
but im new to all of this so i might have done something wrong when getting the SilentAim pointers, or the code is not working anymore. :/
#5 · 8mo ago
FAISAL32
FAISAL32
Quote Originally Posted by sillybean42 View Post
The New SilentAim pointer seem to be:
0x012B9640
0x012B9678
0x012B96AC

but its still not working for me. i know i got the right world and player pointers,
but im new to all of this so i might have done something wrong when getting the SilentAim pointers, or the code is not working anymore. :/
use the signature to search for it
there’s a wrong pointer included with them but look for the pointer in the Trove.exe module the other one ignore it

also here are the correct pointers:
Code:
const std::array<uintptr_t, 3> silentAimOffsets = {
0x2FE643// F3 0F 10 82 DC 00 00 00
0x2FE679// F3 0F 10 82 E0 00 00 00
0x2FE6AF// F3 0F 10 82 E4 00 00 00
}
#6 · 8mo ago
FunTrat0r
FunTrat0r
how do i get the localplayer offset, it seems to be wrong
the entity list and localplayer offsets seems to be wrong.

Correct Localplayer offset: 0x11FF548
I am not sure about the entity list offsets/World Offset :/
#7 · edited 8mo ago · 8mo ago
SI
sillybean42
Quote Originally Posted by FunTrat0r View Post
the entity list and localplayer offsets seems to be wrong.

Correct Localplayer offset: 0x11FF548
I am not sure about the entity list offsets/World Offset :/
yes Localplayer offset is 0x11FF548

and the World offset is 0x11FF5A4
#8 · 8mo ago
ISVIE
ISVIE
ty for help
#9 · 8mo ago
QW
qwertrewq123
Can i update silent.exe with dnSpy program?
#10 · 7mo ago
FAISAL32
FAISAL32
Quote Originally Posted by qwertrewq123 View Post
Can i update silent.exe with dnSpy program?
u gonna use dnspy to check it ??
it only works with .NET not C++
also if u need it i attached the source code u can use it just update the pointers and it will work
needs compiling
#11 · 7mo ago
QW
qwertrewq123
Idk witch program the use you..

idk how update pointers..

Do u show video?

Thank you for help.
#12 · edited 7mo ago · 7mo ago
EH
ehhTomekk
Quote Originally Posted by qwertrewq123 View Post
Idk witch program the use you..

idk how update pointers..

Do u show video? my DC: **********.

Thank you for help.
First of all, pretty sure mentioning ur discord tag here is against the rules.
And also, if you wanna learn how to update the pointers then watch literally any cheat engine guide on youtube. The sources on mpgh like this silentAim or the AngelsD AutoDungeon give you EVERYTHING you need to update these pointers yourself, you literally dont even have to go looking for the right ones because you literally get the answer spoonfed to you. All you have to do is put these 20 minutes of work in to figure out how to use Cheat Engine, if you refuse to do that then I really doubt anyone on here will wanna help you in the slightest.
#13 · 7mo ago
QW
qwertrewq123
i search but i dont understand how to work CE. Maybe i s tupid.

give me yt video
#14 · 7mo ago
QW
qwertrewq123
Tutorial video big help for me.. pls give me for help
#15 · 7mo ago
Posts 1–15 of 16 · Page 1 of 2

Post a Reply

Similar Threads

  • CA SILENTBy GameTrainerMaker in Combat Arms Hack Coding / Programming / Source Code
    18Last post 16y ago
  • Silent aimBy adryan3s in CrossFire Discussions
    10Last post 16y ago
  • Silent FITH ModBy dave:)) in Soldier Front Hacks
    35Last post 14y ago
  • Have they done a silent patch?By Allan990 in Combat Arms Help
    3Last post 15y ago
  • Silent PatchBy Chemixx in WarRock Discussions
    10Last post 16y ago

Tags for this Thread

None