Вопрос Не могу найти оффсеты на Dota 2 через ida

Начинающий
Статус
Оффлайн
Регистрация
12 Окт 2021
Сообщения
22
Реакции[?]
9
Поинты[?]
8K
Пытаюсь найти оффсеты на доту 2(предположим оффсет m_iHealth), делаю всё по гайду: гружу ддлку, генерирую строки, через jump to xref пытаюсь найти оффсет и тут у меня нет нужных строк как у всех в гайдах(скрин), хелп плиз
1 скрин (мой)
[IMG]
2 скрин(как у чела из одного гайда)
1711974118670.png
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Пытаюсь найти оффсеты на доту 2(предположим оффсет m_iHealth), делаю всё по гайду: гружу ддлку, генерирую строки, через jump to xref пытаюсь найти оффсет и тут у меня нет нужных строк как у всех в гайдах(скрин), хелп плиз
1 скрин (мой)
[IMG]
2 скрин(как у чела из одного гайда)
Посмотреть вложение 273916
Пожалуйста, авторизуйтесь для просмотра ссылки.
ну и даже если просто тыкать по хрефам то все равно всё очень просто
там под хрефом на строку хреф на соответствующую ей структуру(собственно эта строка в структуру и засовывается)
1711983578020.png
 
Начинающий
Статус
Оффлайн
Регистрация
12 Окт 2021
Сообщения
22
Реакции[?]
9
Поинты[?]
8K
Пожалуйста, авторизуйтесь для просмотра ссылки.
ну и даже если просто тыкать по хрефам то все равно всё очень просто
там под хрефом на строку хреф на соответствующую ей структуру(собственно эта строка в структуру и засовывается)
Посмотреть вложение 273925
Понял, спасибо! А как можно такое же окно снизу с дампами сделать как у тебя? Или это не ida?
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Понял, спасибо! А как можно такое же окно снизу с дампами сделать как у тебя? Или это не ida?
это x64dbg. это другой тип инструмента(ида для статического анализа(т.е. не запуская приложение), а дебаггер для динамического(во время запуска прямо смотреть что где как происходит)(но в дебаггере тоже есть инструментарий для статического анализа, не такой мощный просто))
 
Начинающий
Статус
Оффлайн
Регистрация
12 Окт 2021
Сообщения
22
Реакции[?]
9
Поинты[?]
8K
это x64dbg. это другой тип инструмента(ида для статического анализа(т.е. не запуская приложение), а дебаггер для динамического(во время запуска прямо смотреть что где как происходит)(но в дебаггере тоже есть инструментарий для статического анализа, не такой мощный просто))
Понял, спасибо. А можешь пример кода с чтением m_iHealth дать на c++, пожалуйста. Я до этого читал по оффсетам найденным через CE, а сейчас не получается реализовать
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Понял, спасибо. А можешь пример кода с чтением m_iHealth дать на c++, пожалуйста. Я до этого читал по оффсетам найденным через CE, а сейчас не получается реализовать
интернал, тестовый говнокод
C++:
//c++17
#include <Windows.h>
#include <Psapi.h>
#include <string>

using T_ConMsg = void(*)(const char* fmt, ...);
T_ConMsg _ConMsg = nullptr;
template<class... Types>
void CMSG(const char* fmt, Types... Args)
{
    if (_ConMsg)
        _ConMsg(fmt, Args...);
}

using T_CreateInterface = void* (*)(const char* name, int* out_status);
void* CreateInterface(T_CreateInterface function, const char* name)
{
    int out_status{};
    const auto result = function(name, &out_status);
    if (out_status == 0)
        return result;
    return nullptr;
}

bool fuzzy_memcmp(const std::uint8_t* lhs, const std::uint8_t* rhs, std::size_t size, const char* masks) noexcept
{
    constexpr auto wildcard = '?';
    const auto end = lhs + size;
    for (; lhs < end; ++lhs, ++rhs, ++masks)
    {
        if (*masks != wildcard && *lhs != *rhs)
            return false;
    }
    return true;
}

//maybe shit, not really tested
const std::uint8_t* sigscan_naive(const std::uint8_t* base, std::size_t input_size, const uint8_t* pattern,
    std::size_t pattern_size, const char* masks) noexcept
{
    if (
        pattern_size
        && (input_size >= pattern_size)
        && base
        && pattern
        && masks
        )
    {
        const auto alignmentCount = (input_size - pattern_size) + 1;
        const auto end = base + alignmentCount;
        for (auto current = base; current < end; ++current)
        {
            if (fuzzy_memcmp(current, pattern, pattern_size, masks))
                return current;
        }
    }

    return nullptr;
}

BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        if (const auto tier0 = GetModuleHandleA("tier0.dll"); tier0)
        {
            if (const auto ConMsgExport = GetProcAddress(tier0, "?ConMsg@@YAXPEBDZZ"); ConMsgExport)
            {
                _ConMsg = reinterpret_cast<T_ConMsg>(ConMsgExport);
                CMSG("Hello world!\n");

                if (const auto client_dll = GetModuleHandleA("client.dll"); client_dll)
                {
                    MODULEINFO out_modinfo{};
                    if (!K32GetModuleInformation(GetCurrentProcess(), client_dll, &out_modinfo, sizeof(MODULEINFO)))
                        CMSG("K32GetModuleInformation fail: %u\n", GetLastError());
                    else
                    {
                        const char masks[]{ "xxx????xx????xxx????xxx" };
                        const auto entitysystem_xref =
                            sigscan_naive((const std::uint8_t*)client_dll, out_modinfo.SizeOfImage,
                                (const std::uint8_t*)"\x48\x8d\x0d????\xff\x15????\x48\x8b\x0d????\x33\xd2\xe8",
                                std::size(masks) - 1,
                                masks);
                        if (!entitysystem_xref)
                            CMSG("entitysystem_xref not found!\n");
                        else
                        {
                            const auto mov_insn_ptr = entitysystem_xref + 0xD;
                            const auto rel32 = *(std::int32_t*)(mov_insn_ptr + 0x3);
                            const auto entity_system_ptr = (void**)(mov_insn_ptr + 0x7 + rel32);
                            const auto entitysystem = *entity_system_ptr;
                            if (!entitysystem)
                                CMSG("entitysystem not created yet\n");
                            else
                            {
                                CMSG("entitysystem: 0x%p\n", entitysystem);
                                if (const auto engine_dll = GetModuleHandleA("engine2.dll"); engine_dll)
                                {
                                    if (const auto Engine_CIProc = GetProcAddress(engine_dll, "CreateInterface"); Engine_CIProc)
                                    {
                                        const auto engineclient
                                            = CreateInterface(reinterpret_cast<T_CreateInterface>(Engine_CIProc),
                                                "Source2EngineToClient001");
                                        if (engineclient)
                                        {
                                            CMSG("CEngineClient: 0x%p\n", engineclient);

                                            if (const auto engine_vftable = *reinterpret_cast<void***>(engineclient);
                                                engine_vftable)
                                            {
                                                using T_GetLocalPlayerID = void(*)(void* self_engineclient, int* out_result, int splitscreenslot);
                                                const auto GetLocalPlayerID
                                                    = reinterpret_cast<T_GetLocalPlayerID>(engine_vftable[29]);
                                                if (GetLocalPlayerID)
                                                {
                                                    int playerID = 0;
                                                    GetLocalPlayerID(engineclient, &playerID, 0);
                                                    if (playerID >= 0)
                                                    {
                                                        const auto player_controller_entity_ID = playerID + 1;
                                                        CMSG("Local player id: %d\n", playerID);
                                                        CMSG("Local player entity id: %d\n", player_controller_entity_ID);

                                                        constexpr auto ENTITY_SYSTEM_LIST_SIZE = 512;
                                                        constexpr auto ENTITY_SYSTEM_LIST_COUNT = 64;
                                                        constexpr auto indexMask = (ENTITY_SYSTEM_LIST_COUNT * ENTITY_SYSTEM_LIST_SIZE) - 1;
                                                        const auto _GetEntityByIndex = [entitysystem](std::size_t index) -> void*
                                                        {
                                                            const auto entitysystem_lists = (const void**)((char*)entitysystem + 0x10);
                                                            const auto list =
                                                                entitysystem_lists[index / ENTITY_SYSTEM_LIST_SIZE];
                                                            if (list)
                                                            {
                                                                const auto entry_index = index % ENTITY_SYSTEM_LIST_SIZE;
                                                                constexpr auto sizeof_CEntityIdentity = 0x78;
                                                                const auto identity = (char*)list + entry_index * sizeof_CEntityIdentity;
                                                                if (identity)
                                                                {
                                                                    return *(void**)identity;
                                                                }
                                                            }
                                                            return nullptr;
                                                        };
                                                        const auto local_player_controller = _GetEntityByIndex(player_controller_entity_ID);
                                                        CMSG("local_player_controller: 0x%p\n", local_player_controller);
                                                        if (local_player_controller)
                                                        {
                                                            constexpr auto offset_m_hAssignedHero = 0x7d4;

                                                            const auto handle_m_hAssignedHero = *(std::uint32_t*)
                                                                ((char*)local_player_controller + offset_m_hAssignedHero);
                                                            const auto index_m_hAssignedHero = handle_m_hAssignedHero & indexMask;
                                                            CMSG("index_m_hAssignedHero: %u\n", index_m_hAssignedHero);
                                                            const auto local_hero = _GetEntityByIndex(index_m_hAssignedHero);
                                                            CMSG("local_hero: 0x%p\n", local_hero);
                                                            if (local_hero)
                                                            {
                                                                constexpr auto offset_m_iHealth = 0x324;
                                                                CMSG("hp: %d\n", *(int*)((char*)local_hero + offset_m_iHealth));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return TRUE;
}
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
12 Окт 2021
Сообщения
22
Реакции[?]
9
Поинты[?]
8K
интернал, тестовый говнокод
C++:
//c++17
#include <Windows.h>
#include <Psapi.h>
#include <string>

using T_ConMsg = void(*)(const char* fmt, ...);
T_ConMsg _ConMsg = nullptr;
template<class... Types>
void CMSG(const char* fmt, Types... Args)
{
    if (_ConMsg)
        _ConMsg(fmt, Args...);
}

using T_CreateInterface = void* (*)(const char* name, int* out_status);
void* CreateInterface(T_CreateInterface function, const char* name)
{
    int out_status{};
    const auto result = function(name, &out_status);
    if (out_status == 0)
        return result;
    return nullptr;
}

bool fuzzy_memcmp(const std::uint8_t* lhs, const std::uint8_t* rhs, std::size_t size, const char* masks) noexcept
{
    constexpr auto wildcard = '?';
    const auto end = lhs + size;
    for (; lhs < end; ++lhs, ++rhs, ++masks)
    {
        if (*masks != wildcard && *lhs != *rhs)
            return false;
    }
    return true;
}

//maybe shit, not really tested
const std::uint8_t* sigscan_naive(const std::uint8_t* base, std::size_t input_size, const uint8_t* pattern,
    std::size_t pattern_size, const char* masks) noexcept
{
    if (
        pattern_size
        && (input_size >= pattern_size)
        && base
        && pattern
        && masks
        && (strlen(masks) == pattern_size)
        )
    {
        const auto alignmentCount = (input_size - pattern_size) + 1;
        const auto end = base + alignmentCount;
        for (auto current = base; current < end; ++current)
        {
            if (fuzzy_memcmp(current, pattern, pattern_size, masks))
                return current;
        }
    }

    return nullptr;
}

BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        if (const auto tier0 = GetModuleHandleA("tier0.dll"); tier0)
        {
            if (const auto ConMsgExport = GetProcAddress(tier0, "?ConMsg@@YAXPEBDZZ"); ConMsgExport)
            {
                _ConMsg = reinterpret_cast<T_ConMsg>(ConMsgExport);
                CMSG("Hello world!\n");

                if (const auto client_dll = GetModuleHandleA("client.dll"); client_dll)
                {
                    MODULEINFO out_modinfo{};
                    if (!K32GetModuleInformation(GetCurrentProcess(), client_dll, &out_modinfo, sizeof(MODULEINFO)))
                        CMSG("K32GetModuleInformation fail: %u\n", GetLastError());
                    else
                    {
                        const char masks[]{ "xxx????xx????xxx????xxx" };
                        const auto entitysystem_xref =
                            sigscan_naive((const std::uint8_t*)client_dll, out_modinfo.SizeOfImage,
                                (const std::uint8_t*)"\x48\x8d\x0d????\xff\x15????\x48\x8b\x0d????\x33\xd2\xe8",
                                std::size(masks) - 1,
                                masks);
                        if (!entitysystem_xref)
                            CMSG("entitysystem_xref not found!\n");
                        else
                        {
                            const auto mov_insn_ptr = entitysystem_xref + 0xD;
                            const auto rel32 = *(std::int32_t*)(mov_insn_ptr + 0x3);
                            const auto entity_system_ptr = (void**)(mov_insn_ptr + 0x7 + rel32);
                            const auto entitysystem = *entity_system_ptr;
                            if (!entitysystem)
                                CMSG("entitysystem not created yet\n");
                            else
                            {
                                CMSG("entitysystem: 0x%p\n", entitysystem);
                                if (const auto engine_dll = GetModuleHandleA("engine2.dll"); engine_dll)
                                {
                                    if (const auto Engine_CIProc = GetProcAddress(engine_dll, "CreateInterface"); Engine_CIProc)
                                    {
                                        const auto engineclient
                                            = CreateInterface(reinterpret_cast<T_CreateInterface>(Engine_CIProc),
                                                "Source2EngineToClient001");
                                        if (engineclient)
                                        {
                                            CMSG("CEngineClient: 0x%p\n", engineclient);

                                            if (const auto engine_vftable = *reinterpret_cast<void***>(engineclient);
                                                engine_vftable)
                                            {
                                                using T_GetLocalPlayerID = void(*)(void* self_engineclient, int* out_result, int splitscreenslot);
                                                const auto GetLocalPlayerID
                                                    = reinterpret_cast<T_GetLocalPlayerID>(engine_vftable[27]);
                                                if (GetLocalPlayerID)
                                                {
                                                    int playerID = 0;
                                                    GetLocalPlayerID(engineclient, &playerID, 0);
                                                    if (playerID >= 0)
                                                    {
                                                        const auto player_controller_entity_ID = playerID + 1;
                                                        CMSG("Local player id: %d\n", playerID);
                                                        CMSG("Local player entity id: %d\n", player_controller_entity_ID);

                                                        constexpr auto ENTITY_SYSTEM_LIST_SIZE = 512;
                                                        constexpr auto ENTITY_SYSTEM_LIST_COUNT = 64;
                                                        constexpr auto indexMask = (ENTITY_SYSTEM_LIST_COUNT * ENTITY_SYSTEM_LIST_SIZE) - 1;
                                                        const auto _GetEntityByIndex = [entitysystem](std::size_t index) -> void*
                                                        {
                                                            const auto entitysystem_lists = (const void**)((char*)entitysystem + 0x10);
                                                            const auto list =
                                                                entitysystem_lists[index / ENTITY_SYSTEM_LIST_SIZE];
                                                            const auto entry_index = index % ENTITY_SYSTEM_LIST_SIZE;
                                                            constexpr auto sizeof_CEntityIdentity = 0x78;
                                                            const auto identity = (char*)list + entry_index * sizeof_CEntityIdentity;
                                                            if (identity)
                                                            {
                                                                return *(void**)identity;
                                                            }
                                                            return nullptr;
                                                        };
                                                        const auto local_player_controller = _GetEntityByIndex(player_controller_entity_ID);
                                                        CMSG("local_player_controller: 0x%p\n", local_player_controller);
                                                        if (local_player_controller)
                                                        {
                                                            constexpr auto offset_m_hAssignedHero = 0x7e4;

                                                            const auto handle_m_hAssignedHero = *(std::uint32_t*)
                                                                ((char*)local_player_controller + offset_m_hAssignedHero);
                                                            const auto index_m_hAssignedHero = handle_m_hAssignedHero & indexMask;
                                                            CMSG("index_m_hAssignedHero: %u\n", index_m_hAssignedHero);
                                                            const auto local_hero = _GetEntityByIndex(index_m_hAssignedHero);
                                                            CMSG("local_hero: 0x%p\n", local_hero);
                                                            if (local_hero)
                                                            {
                                                                constexpr auto offset_m_iHealth = 0x334;
                                                                CMSG("hp: %d\n", *(int*)((char*)local_hero + offset_m_iHealth));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return TRUE;
}
Спасибо, но можно пример на экстернале, пожалуйста, просто интернал пока что далеко не мой уровень
Спасибо, но можно пример на экстернале, пожалуйста, просто интернал пока что далеко не мой уровень
C++:
uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < offsets.size(); ++i)
    {
        ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}

int GetHP() {
    int hp;

    uintptr_t dynamicptrbaseadd = ModuleBase + 0x46F57F8;

    std::vector<unsigned int> offsets = { 0x8, 0x2D8, 0x50, 0x8, 0x48 };

    uintptr_t Myaddr = FindDMAAddy(hProcess, dynamicptrbaseadd, offsets);

    LPVOID address = reinterpret_cast<LPVOID>(0x46F57F8);

    ReadProcessMemory(hProcess, (LPVOID)Myaddr, &hp, sizeof(hp), 0);

    cout << hp << endl;

    return hp;
}
у меня было что то типо такого кода, но я не совсем понимаю что мне ставить вместо 0x46F57F8
 
Начинающий
Статус
Оффлайн
Регистрация
14 Янв 2024
Сообщения
31
Реакции[?]
1
Поинты[?]
2K
интернал, тестовый говнокод
так можно было? просто попросить пасту)) три дня бился с получением сущности по индексу; спасибо

Спасибо, но можно пример на экстернале, пожалуйста, просто интернал пока что далеко не мой уровень
по мне интернал легче, так как не надо высчитывать смещения памяти (считывать модуль в свою память через ReadProcessMemory и внутри своей памяти находишь относительный адрес по сигне (место где нашел минус место где начинал искать) и прибавляешь его к адресу модуля);

тебе дали готовую пасту, собирай длл, пускай решение называется "Health", далее нужен инжектор, я использую из статьи с хабра, с этим инжектером играю в рейтинге около двух недель без бана, инжечку им длл, которая изменяет значения кваров камеры, з_фар, фог:
Пожалуйста, авторизуйтесь для просмотра ссылки.
код с гх:
Пожалуйста, авторизуйтесь для просмотра ссылки.

в коде надо поправить:

int main() {
cout << "Entry point" << endl;
string dllPath;
GetDllPath("dx9Dll.dll", dllPath);
........

станет:

int main() {
cout << "Entry point" << endl;
string dllPath;
GetDllPath("Health.dll", dllPath); // Health имя твоей собранной длл из пасты
........

если при сборке инжектора будут ошибки, смени кодировку символов в свойствах проекта с юникода на многобайтовую, далее помещаешь длл в папку с собранным инжектором и запускаешь инжект

зы: сам начал изучать реверс и с++ месяц назад, мог написать что-то ошибочно; не воспринимай мои слова за истину))
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
12 Окт 2021
Сообщения
22
Реакции[?]
9
Поинты[?]
8K
так можно было? просто попросить пасту)) три дня бился с получением сущности по индексу; спасибо


по мне интернал легче, так как не надо высчитывать смещения памяти (считывать модуль в свою память через ReadProcessMemory и внутри своей памяти находишь относительный адрес по сигне (место где нашел минус место где начинал искать) и прибавляешь его к адресу модуля);

тебе дали готовую пасту, собирай длл, пускай решение называется "Health", далее нужен инжектор, я использую из статьи с хабра, с этим инжектером играю в рейтинге около двух недель без бана, инжечку им длл, которая изменяет значения кваров камеры, з_фар, фог:
Пожалуйста, авторизуйтесь для просмотра ссылки.
код с гх:
Пожалуйста, авторизуйтесь для просмотра ссылки.

в коде надо поправить:

int main() {
cout << "Entry point" << endl;
string dllPath;
GetDllPath("dx9Dll.dll", dllPath);
........

станет:

int main() {
cout << "Entry point" << endl;
string dllPath;
GetDllPath("Health.dll", dllPath); // Health имя твоей собранной длл из пасты
........

если при сборке инжектора будут ошибки, смени кодировку символов в свойствах проекта с юникода на многобайтовую, далее помещаешь длл в папку с собранным инжектором и запускаешь инжект

зы: сам начал изучать реверс и с++ месяц назад, мог написать что-то ошибочно; не воспринимай мои слова за истину))
Ну хз для меня интернал сложнее кажется. Не вижу смысла брать пасту и пытаться делать что то своё. Пока что хочу понять как работает в экстернале
 
Начинающий
Статус
Оффлайн
Регистрация
14 Янв 2024
Сообщения
31
Реакции[?]
1
Поинты[?]
2K
интернал сложнее кажется
также думал, а главное не понимал как отлаживать заинжекченные длл;

Не вижу смысла брать пасту и пытаться делать что то своё
присоединяешь к процессу дота2, ставишь точку останова в начале инжекта, инжектишься и отлаживашь через шифт + ф9, разбираясь как работает код, а потом правя под свои нужды, например идея: бегаешь в по кадровом цикле по врагам, заглядывая в инвентарь, если находишь в нём вард, тогда запоминаешь булево УНегоЕстьВард = Истина; вард пропал и сумки, тогда отрисовываешь метку о установке варда;
Сейчас изучаю мгуи, пытаюсь понять как рисовать или выводить числа в доте на экран, но что-то не получается)) тут главное терпение...
 
Начинающий
Статус
Оффлайн
Регистрация
12 Окт 2021
Сообщения
22
Реакции[?]
9
Поинты[?]
8K
также думал, а главное не понимал как отлаживать заинжекченные длл;


присоединяешь к процессу дота2, ставишь точку останова в начале инжекта, инжектишься и отлаживашь через шифт + ф9, разбираясь как работает код, а потом правя под свои нужды, например идея: бегаешь в по кадровом цикле по врагам, заглядывая в инвентарь, если находишь в нём вард, тогда запоминаешь булево УНегоЕстьВард = Истина; вард пропал и сумки, тогда отрисовываешь метку о установке варда;
Сейчас изучаю мгуи, пытаюсь понять как рисовать или выводить числа в доте на экран, но что-то не получается)) тут главное терпение...
Не очень понял про отладку, что на шифт + ф9 должно быть?
 
Начинающий
Статус
Оффлайн
Регистрация
14 Янв 2024
Сообщения
31
Реакции[?]
1
Поинты[?]
2K
Не очень понял про отладку
в этой теме объяснили как отлаживать длл: https://yougame.biz/threads/313054/

шифт + ф9 должно быть
выделяешь переменную или выражение и жмём шифт + ф9, откроется окно вычисления, я в нём меняю офсеты и указатели
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Спасибо, но можно пример на экстернале, пожалуйста, просто интернал пока что далеко не мой уровень

C++:
uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < offsets.size(); ++i)
    {
        ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}

int GetHP() {
    int hp;

    uintptr_t dynamicptrbaseadd = ModuleBase + 0x46F57F8;

    std::vector<unsigned int> offsets = { 0x8, 0x2D8, 0x50, 0x8, 0x48 };

    uintptr_t Myaddr = FindDMAAddy(hProcess, dynamicptrbaseadd, offsets);

    LPVOID address = reinterpret_cast<LPVOID>(0x46F57F8);

    ReadProcessMemory(hProcess, (LPVOID)Myaddr, &hp, sizeof(hp), 0);

    cout << hp << endl;

    return hp;
}
у меня было что то типо такого кода, но я не совсем понимаю что мне ставить вместо 0x46F57F8
супердерьмокод
C++:
//c++23
//super shitcode
#include <iostream>
#include <expected>
#include <vector>
#include <format>
#include <span>
#include <array>
#include <source_location>

#include <Windows.h>
#include <Psapi.h>
#include <tlhelp32.h>

bool fuzzy_memcmp(const std::uint8_t* lhs, const std::uint8_t* rhs, std::size_t size, const char* masks) noexcept
{
    constexpr auto wildcard = '?';
    const auto end = lhs + size;
    for (; lhs < end; ++lhs, ++rhs, ++masks)
    {
        if (*masks != wildcard && *lhs != *rhs)
            return false;
    }
    return true;
}

const std::uint8_t* sigscan_naive(const std::uint8_t* base, std::size_t input_size, const uint8_t* pattern,
    std::size_t pattern_size, const char* masks) noexcept
{
    if (
        pattern_size
        && (input_size >= pattern_size)
        && base
        && pattern
        && masks
        )
    {
        const auto alignmentCount = (input_size - pattern_size) + 1;
        const auto end = base + alignmentCount;
        for (auto current = base; current < end; ++current)
        {
            if (fuzzy_memcmp(current, pattern, pattern_size, masks))
                return current;
        }
    }

    return nullptr;
}

std::vector<std::string_view> strsplit(std::string_view input, std::string_view token)
{
    std::vector<std::string_view> result{};
    const auto token_size = token.size();
    std::size_t pos{};
    while ((pos = input.find(token)) != std::string_view::npos)
    {
        result.push_back(input.substr(0, pos));
        input = input.substr(pos + token_size);
    }
    result.push_back(input);
    return result;
}

constexpr auto _invalid_hex_char = (std::numeric_limits<std::uint8_t>::max)();
constexpr std::uint8_t get_hex_char(std::uint8_t x)
{
    if (x >= '0' && x <= '9')
        return x - '0';
    else if (x >= 'A' && x <= 'F')
        return x - 'A' + 0xA;
    else if (x >= 'a' && x <= 'f')
        return x - 'a' + 0xA;
    return _invalid_hex_char;
}

struct _sig
{
    std::vector<std::uint8_t> bytes{};
    std::vector<char> masks{};
};
_sig preprocess_patern_fuzzy(std::string_view textsig)
{
    _sig result{};
    if (!textsig.empty())
    {
        result.bytes.reserve(textsig.size());
        result.masks.reserve(textsig.size());
        for (const auto& chunk : strsplit(textsig, " "))
        {
            if (chunk.size() == 2)
            {
                if (chunk.front() == '?')
                {
                    result.bytes.push_back('?');
                    result.masks.push_back('?');
                }
                else
                {
                    const auto high = get_hex_char(chunk.front());
                    const auto low = get_hex_char(chunk.back());
                    if (high == _invalid_hex_char || low == _invalid_hex_char)
                        return {};
                    result.bytes.push_back((high << 4) | low);
                    result.masks.push_back('x');
                }
            }
            else
                return {};
        }
    }
    return result;
}

constexpr auto _sig_not_found = (std::numeric_limits<std::ptrdiff_t>::max)();
std::ptrdiff_t ExternalSigscanGetRVA(const std::uint8_t* base, std::size_t input_size, std::string_view textsig)
{
    const auto& sig = preprocess_patern_fuzzy(textsig);
    if (!sig.bytes.empty() && sig.bytes.size() == sig.masks.size())
    {
        const auto result =
            sigscan_naive(base, input_size, sig.bytes.data(), sig.bytes.size(), sig.masks.data());
        if (result)
        {
            return result - base;
        }
    }
    return _sig_not_found;
}

std::span<std::uint8_t> GetModuleExternal(HANDLE hProcess, std::string_view moduleName)
{
    std::array<HMODULE, 1024> hMods{};
    DWORD out_size;
    if (K32EnumProcessModules(hProcess, hMods.data(), sizeof(hMods), &out_size))
    {
        for (const auto& mod : std::span{ hMods.data(), out_size / sizeof(HMODULE) })
        {
            std::array<char, MAX_PATH> szModName;
            if (K32GetModuleBaseNameA(hProcess, mod, szModName.data(), (DWORD)szModName.size()))
            {
                if (std::string_view{ szModName.data() } == moduleName)
                {
                    MODULEINFO out_modinfo;
                    if (K32GetModuleInformation(hProcess, mod, &out_modinfo, sizeof(MODULEINFO)))
                    {
                        return { (std::uint8_t*)out_modinfo.lpBaseOfDll, out_modinfo.SizeOfImage };
                    }
                }
            }
        }
    }

    return {};
}

std::vector<std::uint8_t> ReadModule(HANDLE hProcess, std::span<std::uint8_t> mod)
{
    std::vector<std::uint8_t> result{};
    result.resize(mod.size());
    SIZE_T out_size;
    if (ReadProcessMemory(hProcess, mod.data(), result.data(), mod.size(), &out_size)
        && out_size == mod.size())
    {
        return result;
    }
    return {};
}

void* ExternalSigscan(HANDLE hProcess, std::string_view moduleName, std::string_view textsig)
{
    const auto extmod = GetModuleExternal(hProcess, moduleName);
    if (extmod.empty())
        throw std::runtime_error{ std::format("module {} not found!", moduleName) };
    const auto& intmod = ReadModule(hProcess, extmod);
    if (intmod.size() != extmod.size())
        throw std::runtime_error{ std::format("can't map module {}!", moduleName) };

    if (const auto rva = ExternalSigscanGetRVA(intmod.data(), intmod.size(), textsig);
        rva != _sig_not_found)
    {
        return extmod.data() + rva;
    }
    return nullptr;
}

template<class T>
std::expected<T, DWORD> ReadMemory(HANDLE process, const void* ptr) noexcept
{
    if (process != NULL)
    {
        constexpr auto expected_size = sizeof(T);
        T obj;
        SIZE_T out_size;
        if (!ReadProcessMemory(process, ptr, &obj, expected_size, &out_size))
            return std::unexpected{ GetLastError() };

        if (out_size != expected_size)
            return std::unexpected{ ERROR_MORE_DATA };

        return { obj };
    }
    return std::unexpected{ ERROR_INVALID_HANDLE };
}

template<HANDLE invalid_value>
struct handle_raii
{
    HANDLE handle = invalid_value;
    bool IsValid() const noexcept
    {
        return handle != invalid_value;
    }
    ~handle_raii()
    {
        if (IsValid())
            CloseHandle(handle);
    }
    operator HANDLE() const noexcept
    {
        return handle;
    }
};

constexpr DWORD _invalid_pid = (std::numeric_limits<DWORD>::max)();
DWORD GetProcessID(const std::string_view& processName)
{
    if (const handle_raii<INVALID_HANDLE_VALUE> hSnap{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL) };
        hSnap.IsValid())
    {
#pragma push_macro("PROCESSENTRY32")
#pragma push_macro("Process32First")
#pragma push_macro("Process32Next")
#undef PROCESSENTRY32
#undef Process32First
#undef Process32Next

        PROCESSENTRY32 entry{ .dwSize = sizeof(PROCESSENTRY32) };

        for (auto result = Process32First(hSnap, &entry); result; result = Process32Next(hSnap, &entry))
            if (std::string_view{ entry.szExeFile } == processName)
                return entry.th32ProcessID;

#pragma pop_macro("Process32Next")
#pragma pop_macro("Process32First")
#pragma pop_macro("PROCESSENTRY32")
    }
    return _invalid_pid;
}


struct CanReadProcessMemory
{
    HANDLE _process = NULL;

    template<class T>
    std::expected<T, DWORD> Read(const void* ptr) const noexcept
    {
        return ReadMemory<T>(_process, ptr);
    }
};

struct ExternalClass : public CanReadProcessMemory
{
    void* instance_ptr;
    bool HasObject() const noexcept
    {
        return instance_ptr != nullptr;
    }

    template<class T>
    T Member(std::ptrdiff_t offset, const std::source_location& source = std::source_location::current()) const
    {
        const auto obj = Read<T>((char*)instance_ptr + offset);
        if (!obj.has_value())
        {
            throw std::runtime_error
            {
                std::format("error({}) reading member from {}", obj.error(), source.function_name())
            };
        }
        return obj.value();
    }

    template<class T>
    T ExternalClassPointer(std::ptrdiff_t offset, const std::source_location& source = std::source_location::current()) const
        requires(std::derived_from<T, ExternalClass>)
    {
        const auto val = Member<T*>(offset, source);
        return { _process, val };
    }

    std::string ReadNullTerminatedString
    (std::ptrdiff_t offset, const std::source_location& source = std::source_location::current()) const
    {
        std::string str{};
        const char* ptr = Member<char*>(offset, source);
        if (ptr)
        {
            for (char character; (character = Read<char>(ptr).value()) != '\x00'; ++ptr)
                str += character;
        }
        return str;
    }
};

struct _sized_struct {};

template<class T>
    requires(std::derived_from<T, _sized_struct>)
struct ExternalArray : ExternalClass
{
    T At(std::size_t index) const
    {
        return T{ _process, (char*)instance_ptr + T::_sizeof * index };
    }
};

struct PlayerID_t
{
    std::uint32_t value;
};

struct EntityIndex_t
{
    std::int32_t value;
    bool IsValid() const noexcept
    {
        return value != -1;
    }
    static EntityIndex_t from(PlayerID_t playerid) noexcept
    {
        return EntityIndex_t{ static_cast<std::int32_t>(playerid.value + 1) };
    }
};

static constexpr auto ES_ENTITY_LIST_COUNT = 64;
static constexpr auto ES_ENTITY_COUNT_PER_LIST = 512;
struct CHandle
{
    std::int32_t value;
    EntityIndex_t index() const noexcept
    {
        return { value & ((ES_ENTITY_LIST_COUNT * ES_ENTITY_COUNT_PER_LIST) - 1) };
    }
    bool IsValid() const noexcept
    {
        return value != -1;
    }
};

struct CNetworkGameClient : ExternalClass
{
    PlayerID_t LocalPlayerIndex() const
    {
        return Member<PlayerID_t>(0x100);
    }
};

struct C_BaseEntity;
struct CEntityIdentity : ExternalClass, _sized_struct
{
    constexpr static auto _sizeof = 0x78;

    C_BaseEntity GetEntity() const;
    std::string GetName() const
    {
        return ReadNullTerminatedString(0x18);
    }
    std::string GetDesignerName() const
    {
        return ReadNullTerminatedString(0x20);
    }
};

struct C_BaseEntity : ExternalClass
{
    CEntityIdentity GetIdentity() const
    {
        return ExternalClassPointer<CEntityIdentity>(0x10);
    }
    std::string GetName() const
    {
        if (const auto identity = GetIdentity(); identity.HasObject())
            return identity.GetName();
        return {};
    }
    std::string GetDesignerName() const
    {
        if (const auto identity = GetIdentity(); identity.HasObject())
            return identity.GetDesignerName();
        return {};
    }
    int GetHealth() const
    {
        return Member<int>(0x334);
    }
};

struct C_DOTAPlayerController : C_BaseEntity
{
    CHandle GetAssignedHeroHandle() const
    {
        return Member<CHandle>(0x7e4);
    }
};

C_BaseEntity CEntityIdentity::GetEntity() const
{
    return ExternalClassPointer<C_BaseEntity>(0x0);
}

struct CGameEntitySystem : ExternalClass
{
private:
    ExternalArray<CEntityIdentity> GetList(std::size_t listIndex) const
    {
        if (listIndex < ES_ENTITY_LIST_COUNT)
            return ExternalClassPointer<ExternalArray<CEntityIdentity>>(0x10 + listIndex * sizeof(void*));
        return {};
    }
public:
    EntityIndex_t GetHighestIndex() const
    {
        return Member<EntityIndex_t>(0x1510);
    }
    C_BaseEntity GetEntityByIndex(EntityIndex_t index) const
    {
        if (index.value > 0 && index.value < (ES_ENTITY_LIST_COUNT * ES_ENTITY_COUNT_PER_LIST))
        {
            const auto highest = GetHighestIndex();
            if (highest.IsValid() && index.value <= highest.value)
            {
                const auto list_index = index.value / ES_ENTITY_COUNT_PER_LIST;
                const auto index_in_list = index.value % ES_ENTITY_COUNT_PER_LIST;
                const auto list = GetList(list_index);
                if (list.HasObject())
                {
                    const auto identity = list.At(index_in_list);
                    if (identity.HasObject())
                    {
                        return identity.GetEntity();
                    }
                }
            }
        }
        return {};
    }
};

int main()
{
    try
    {
        const auto pid = GetProcessID("dota2.exe");
        if (pid == _invalid_pid)
            throw std::runtime_error{ "No dota2.exe" };
        const handle_raii < HANDLE{ NULL } > process
        {
            OpenProcess(PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid)
        };
        if (!process.IsValid())
            throw std::runtime_error{ "Can't open process" };

        //inside cl_ent_find cmd. string xref "format: ent_find"
        const auto entitysystem_sig = ExternalSigscan(process, "client.dll",
            "48 8D 0D ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 33 D2 E8");
        if (!entitysystem_sig)
            throw std::runtime_error{ "entitysystem_sig null" };

        constexpr auto es_OFFSET_FROM_SIG_TO_XREF = 0xD;
        constexpr auto es_OFFSET_TO_MOV_OPERAND = 0x3;
        constexpr auto es_SIZE_OF_MOV = 0x7;
        char* es_insn_ptr = ((char*)entitysystem_sig + es_OFFSET_FROM_SIG_TO_XREF);
        const auto es_rel32 = ReadMemory<std::int32_t>
            (process, es_insn_ptr + es_OFFSET_TO_MOV_OPERAND).value();
        void* g_pEntitySystem_addr = (es_insn_ptr + es_rel32 + es_SIZE_OF_MOV);
        std::cout << "g_pEntitySystem_addr: " << g_pEntitySystem_addr << std::endl;

        void* _g_pEntitySystem = ReadMemory<void*>(process, g_pEntitySystem_addr).value();
        if (!_g_pEntitySystem)
            throw std::runtime_error{ "CGameEntitySystem not created yet!" };
        CGameEntitySystem g_pEntitySystem{ process, _g_pEntitySystem };

        //inside CEngineClient::GetLocalPlayerIndex. virtual function 27
        const auto CNetworkGameClient_sig = ExternalSigscan(process, "engine2.dll",
            "4C 8B 0D ?? ?? ?? ?? 4D 85 C9 74 ?? 33 C0");
        if (!CNetworkGameClient_sig)
            throw std::runtime_error{ "entitysystem_sig null" };

        constexpr auto ngc_OFFSET_FROM_SIG_TO_XREF = 0;
        constexpr auto ngc_OFFSET_TO_MOV_OPERAND = 0x3;
        constexpr auto ngc_SIZE_OF_MOV = 0x7;

        char* ngc_insn_ptr = ((char*)CNetworkGameClient_sig + ngc_OFFSET_FROM_SIG_TO_XREF);
        const auto ngc_rel32 = ReadMemory<std::int32_t>
            (process, ngc_insn_ptr + ngc_OFFSET_TO_MOV_OPERAND).value();
        void* g_pNetworkGameClient_addr = (ngc_insn_ptr + ngc_rel32 + ngc_SIZE_OF_MOV);
        std::cout << "g_pNetworkGameClient_addr: " << g_pNetworkGameClient_addr << std::endl;

        void* _g_pNetworkGameClient = ReadMemory<void*>(process, g_pNetworkGameClient_addr).value();
        if (!_g_pNetworkGameClient)
            throw std::runtime_error{ "CNetworkGameClient not created yet!" };
        CNetworkGameClient g_pNetworkGameClient{ process, _g_pNetworkGameClient };
        const auto LocalPlayerIndex = g_pNetworkGameClient.LocalPlayerIndex();
        const auto LocalPlayerEntityIndex = EntityIndex_t::from(g_pNetworkGameClient.LocalPlayerIndex());
        std::cout << "LocalPlayerIndex: " << LocalPlayerIndex.value << std::endl;
        std::cout << "LocalPlayerEntityIndex: " << LocalPlayerEntityIndex.value << std::endl;
        const auto LocalPlayerController = g_pEntitySystem.GetEntityByIndex(LocalPlayerEntityIndex);
        std::cout << "Local player entity: " << LocalPlayerController.instance_ptr << std::endl;
        if (LocalPlayerController.HasObject())
        {
            std::cout << "Local player name: " << LocalPlayerController.GetName() << std::endl;
            std::cout << "Local player designer name: " << LocalPlayerController.GetDesignerName() << std::endl;
            const auto local_hero_handle =
                ((C_DOTAPlayerController&)LocalPlayerController).GetAssignedHeroHandle();
            if (local_hero_handle.IsValid())
            {
                const auto local_hero_index = local_hero_handle.index();
                std::cout << "local hero entity index: " << local_hero_index.value << std::endl;
                const auto local_hero = g_pEntitySystem.GetEntityByIndex(local_hero_index);
                std::cout << "Local hero entity: " << local_hero.instance_ptr << std::endl;
                if (local_hero.HasObject())
                {
                    std::cout << "Local hero name: " << local_hero.GetName() << std::endl;
                    std::cout << "Local hero health: " << local_hero.GetHealth() << std::endl;
                }
            }
        }
    }
    catch (const std::exception& ex)
    {
        std::cout << "Exception: " << ex.what() << std::endl;
    }
    return 0;
}
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
если при сборке инжектора будут ошибки, смени кодировку символов в свойствах проекта с юникода на многобайтовую
на будущее/оффтопик: там проблема в том что в коде ебаные макросы вместо API юзаются
GetModuleFileName это не апи. это макрос на либо GetModuleFileNameW либо GetModuleFileNameA в зависимости от настроек проекта
(это относится ко многим апям. у многих есть A/W версии. апи A используют кодировку которая в винде выбрана, апи W используют UTF-16LE)
в коде используется char тип для строк(соответственно это не UTF-16LE(там wchar_t тип, или если быть точнее то std::uint16_t). т.е. нужно юзать A'шные апи) но вместо A'шных апей используются макросы. можно не трогать настройки проекта а просто заменить макросы на нормальные имена апей(правда есть уебанские макросы типа PROCESSENTRY32 и тд которые совпадают с реальным именем типа/функции и надо эти макросы андефать).
кароче лучше(естественно лично мое мнение) использовать конкретные апи конкретные типы и тд и тп. (опять таки никто не мешает использовать A в одном случае, и W в другом случае, в зависимости от нужды/того что дано) а не объединять все в одну кашу
A'шные апи юзаются когда лень/не хочется ебаться с юникодом(A = текущая кодировка которая в винде выбрана. большинство этих кодировок в основном похожи на ASCII, поэтому английские буковки циферки и тд там везде совпадают, поэтому в теории если работаешь чисто с обычными английскими строками то можно не париться и A юзать если тебе похуй, будет почти везде работать), W'шные апи используются когда надо думать об иностранных буковках символах и тд
имена файлов в винде это UCS-2(это как UTF-16 только это древняя кодировка и она не поддается ограничениям "современного" юникода(инвалидный юникод(одинокие суррогаты например) валиден в UCS-2)), поэтому если с файлами работаешь(и ты не знаешь на каком они могут быть языке. и тебе не похуй) то надо W апи юзать(CreateFileW и тд). допустим вот представим у меня есть файл назван русскими буквами, но винда английская(cp1252 кодировка). я используя CreateFileA, никак нахуй не смогу открыть этот файл по имени, априори, потому что в cp1252(европейская кодировка)(которую я скармливаю CreateFileA(точнее он ее так будет воспринимать. кормить я ему могу что угодно совершенно.)) нету русских букв. опять таки имена файлов в UCS-2(т.е. юникод), т.е. то что ты кормишь в CreateFileA потом переводится в юникод и потом уже в юникоде имена сравниваются.
а вот если у меня винда на русском(cp1251(это кириллица)), то я могу закодировать свое имя файла которое мне нужно в cp1251 и скормить его в CreateFileA. он(т.к. винда русская(т.е. системная кодировка cp1251)(ну впринципе кодировка не связана с "версией" винды ее менять в реестре можно но не суть. просто по дефолту какая "версия" такая и кодировка если не менять ее. так то конечно вся суть в кодировке системы а не в "версии")) будет мой текст интерпретировать как cp1251(где есть русские буквы), и потом переводить эти русские буквы в их юникодовый эквивалент(который в реальном имени файла), и все будет работать.
либо я могу закодировать нужное мне имя(хоть на арабском) в UTF-16LE(ну в UCS-2) и просто скормить его в CreateFileW и везде будет работать

с этим инжектером играю в рейтинге около двух недель без бана, инжечку им длл, которая изменяет значения кваров камеры, з_фар, фог:
если что то это самый примитивный инжектор
заинжекченные длл во-первых будут видны в PEB и не только, во-вторых LoadLibraryA может быть хукнута, в-третьих CreateRemoteThread палится(+ еще миллиард других способов задетектить такой инжект), а еще кроме инжекта и сама длл своими действиями может палиться
то что тебя не банят это не значит что тебя не детектят или не могут задетектить
 
Сверху Снизу