Крашит игру из-за DLL

Статус
В этой теме нельзя размещать новые ответы.

qwertyrus

Новичок
Автор темы
23
2
Переписать external cheat в internal для MTA оказалось труднее, чем я думал(инжект работает и не банит). Заранее извиняюсь если код выглядит плохо, только учусь. Крашит после инжекта, пробовал изменять функцию world_to_screen, крашит в if'ах(внутри функции). Помогите если не трудно
C++:
#include "pch.h"
#include <windows.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <string>


std::vector<int> world_to_screen(std::vector<std::vector<float>> ViewMatrix1, float x, float y, float z) {
    std::vector<int> badcord = { -1, -1 };
    std::vector<int> result(2);
    float screenz = (z * ViewMatrix1[2][2]) + (y * ViewMatrix1[1][2]) + (x * ViewMatrix1[0][2]) + ViewMatrix1[3][2];
    if (screenz < 0.01f) {
        return badcord;
    }
    float screenx = (ViewMatrix1[2][0] * z) + (ViewMatrix1[1][0] * y) + (ViewMatrix1[0][0] * x) + ViewMatrix1[3][0];
    float screeny = (ViewMatrix1[2][1] * z) + (ViewMatrix1[1][1] * y) + (ViewMatrix1[0][1] * x) + ViewMatrix1[3][1];
    float recip = 1.0f / screenz;
    screenx *= recip * 1920;
    screeny *= recip * 1080;
    if (1920 >= screenx && screenx >= 0 && 1080 >= screeny && screeny >= 0) {
        result[0] = static_cast<int>(screenx);
        result[1] = static_cast<int>(screeny);
        return result;
    }
    else {
        return badcord;
    }
}
DWORD WINAPI MainThread(HMODULE hModule)
{
    AllocConsole();
    system("title First project");
    FILE* f;
    freopen_s(&f, "CONOUT$", "w", stdout);
    //printf("Test 1");
    Sleep(200);
    DWORD offsetview = 0xB6FA2C;
    bool espstatus = false;
    DWORD* cped = (DWORD*)0xB6F5F0;
    float* myhealth = (float*)(*cped + 0x540);
    float* myarmour = (float*)(*cped + 0x548);
    DWORD* xyz = (DWORD*)(*cped + 0x14);
    float* x = (float*)(*xyz + 0x30);
    float* y = (float*)(*xyz + 0x30 + 4);
    float* z = (float*)(*xyz + 0x30 + 8);
    std::vector<std::vector<float>> ViewMatrix(4, std::vector<float>(4));
    while (!GetAsyncKeyState(VK_END))
    {

      
        if (GetAsyncKeyState(VK_INSERT)) {
            espstatus = true;
        }

        if (GetAsyncKeyState(VK_DELETE)) {
            espstatus = false;
        }
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {

                ViewMatrix[i][j] = *(float*)(offsetview + 16 * i + 4 * j);
            }
        }
        for (int i = 1; i < 120; i++) {
                DWORD* cpedsearch = (DWORD*)(cped + i * 0x7c4);
                float* health = (float*)(cpedsearch + 0x540);
      
                if (*health <= 160.0f && *health >= 4.0f) {
                    DWORD* pointercoords = (DWORD*)(cpedsearch + 0x14);
                    float* hisx = (float*)(*cpedsearch + 0x30);
                    float* hisy = (float*)(*cpedsearch + 0x34);
                    float* hisz = (float*)(*cpedsearch + 0x38);
                  
                    std::vector<int> onscreen = world_to_screen(ViewMatrix, *hisx, *hisy, *hisz);
                    //далее будет рисование, но пока упустим
                }
            }


        }
  
    if (GetAsyncKeyState(VK_END))
    {
        FreeConsole();
        fclose(f);
    }

    FreeLibraryAndExitThread(hModule, 0);
    return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);        //disables attach and detach notifications
        CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)MainThread, hModule, 0, nullptr));
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
 
Решение
Осталось теперь прикрутить хук директ икса(буду рад если поможешь), а затем отрисовать линии.
Сам недавно разбирался, вот тема:
А вот нужный тебе код:
C++:
#include "MinHook.h"

std::uintptr_t find_device(std::uint32_t Len)
{
    static std::uintptr_t base = [](std::size_t Len)
    {
        std::string path_to(MAX_PATH, '\0');
        if (auto size = GetSystemDirectoryA((LPSTR)path_to.data(), MAX_PATH))
        {
            path_to.resize(size);
            path_to += "\\d3d9.dll";
            std::uintptr_t dwObjBase = reinterpret_cast<std::uintptr_t>(LoadLibraryA(path_to.c_str()));
            while (dwObjBase++ < dwObjBase + Len)
            {
                if...

qwertyrus

Новичок
Автор темы
23
2

qwertyrus

Новичок
Автор темы
23
2
Последнее редактирование:

qwertyrus

Новичок
Автор темы
23
2
А если убрать 76 строку (world_to_screen) — крашит?
Нет. Крашит только с ней. Без нее все ок, функция написана вроде правильно, потому что external работало, а щас переписав под интернал что-то пошло не так.
 

Vintik

Мечтатель
Проверенный
1,469
917
C++:
        for (int i = 1; i < 120; i++) {
                DWORD* cpedsearch = (DWORD*)(cped + i * 0x7c4);
                float* health = (float*)(cpedsearch + 0x540);
    
                if (*health <= 160.0f && *health >= 4.0f) {
                    DWORD* pointercoords = (DWORD*)(cpedsearch + 0x14);
                    float* hisx = (float*)(*cpedsearch + 0x30);
                    float* hisy = (float*)(*cpedsearch + 0x34);
                    float* hisz = (float*)(*cpedsearch + 0x38);
                
                    std::vector<int> onscreen = world_to_screen(ViewMatrix, *hisx, *hisy, *hisz);
                }
Как минимум, ошибка заключается в том, что координаты неправильно считываются (pointercoords вместо cpedsearch).
C++:
float* hisx = (float*)(*pointercoords + 0x30);
float* hisy = (float*)(*pointercoords + 0x34);
float* hisz = (float*)(*pointercoords + 0x38);
И перебор игроков у тебя неверный. Вроде должно быть так:
0xB74490 - Содержит указатель на указатель. Этот указатель:
  • +0 = Содержит указатель на первый элемент в пуле CPed
  • +4 = Содержит указатель на карту байтов, которая обозначает, какие элементы используются в пуле CPed
  • +8 = [dword] Максимальное число элементов в пуле CPed
  • +12 = [dword] Текущее число элементов в пуле CPed
 

qwertyrus

Новичок
Автор темы
23
2
Как минимум, ошибка заключается в том, что координаты неправильно считываются (pointercoords вместо cpedsearch).
C++:
float* hisx = (float*)(*pointercoords + 0x30);
float* hisy = (float*)(*pointercoords + 0x34);
float* hisz = (float*)(*pointercoords + 0x38);
И перебор игроков у тебя неверный. Вроде должно быть так:
Про поинтер, я видимо когда переписывал не заметил и не то вписал, а за перебор спасибо, проверю через некоторое время и отвечу, не можешь помочь с ошибками которые на скрине?
 

Vintik

Мечтатель
Проверенный
1,469
917
Скопировал данный код, выдает много ошибок, библиотеку minhook установил и добавил в проект.
upd ошибок осталось 4
В исходном файле (который тебе скинули) действительно эти функции не определены. Может, там еще какая-нибудь зависимость...
@SobFoX; what you can say about his issue? maybe there are other dependencies because i can't see defenition of this function in code and even in minhook source.
 

qwertyrus

Новичок
Автор темы
23
2
В исходном файле (который тебе скинули) действительно эти функции не определены. Может, там еще какая-нибудь зависимость...
@SobFoX; what you can say about his issue? maybe there are other dependencies because i can't see defenition of this function in code and even in minhook source.
я нашел определение w_findStringIC в другой статье по MTA, но не нашел LogInFile, те две я тоже нашел в интернете, а вот что с этой делать... может её убрать? а вдруг что-то не сработает...

В исходном файле (который тебе скинули) действительно эти функции не определены. Может, там еще какая-нибудь зависимость...
@SobFoX; what you can say about his issue? maybe there are other dependencies because i can't see defenition of this function in code and even in minhook source.
Нашел у автора этого обхода(по ссылке которую давал SobFox на гитхабе такую реализацию, думаю затестирую:
C++:
void __stdcall LogInFile(std::string log_name, const char* log, ...)
{
    char hack_dir[600]; memset(hack_dir, 0, sizeof(hack_dir));
    _getcwd(hack_dir, sizeof(hack_dir)); char new_dir[600];
    memset(new_dir, 0, sizeof(new_dir));
    sprintf(new_dir, "%s\\%s", hack_dir, log_name.c_str());
    static bool once = false; if (!once)
    {
        FILE* hFile = fopen(new_dir, "rb");
        if (hFile) { fclose(hFile); DeleteFileA(new_dir); }
        once = true;
    }
    FILE* hFile = fopen(new_dir, "a+");
    if (hFile)
    {
        time_t t = std::time(0); tm* now = std::localtime(&t);
        char tmp_stamp[600]; memset(tmp_stamp, 0, sizeof(tmp_stamp));
        sprintf(tmp_stamp, "[%d:%d:%d]", now->tm_hour, now->tm_min, now->tm_sec);
        strcat(tmp_stamp, std::string(" " + std::string(log)).c_str());
        va_list arglist; va_start(arglist, log); vfprintf(hFile, tmp_stamp, arglist);
        va_end(arglist); fclose(hFile);
    }
}
 
Последнее редактирование:

Vintik

Мечтатель
Проверенный
1,469
917
может её убрать? а вдруг что-то не сработает...
Это просто логгирование в файл.
К обходу античита MTA это не имеет никакого отношения.
Можешь сделать заглушку:

C++:
void LogInFile(char*, ...)
{
    return;
}

void LogInFile(const char*, ...)
{
    return;
}
 

qwertyrus

Новичок
Автор темы
23
2
Это просто логгирование в файл.
К обходу античита MTA это не имеет никакого отношения.
Можешь сделать заглушку:

C++:
void LogInFile(char*, ...)
{
    return;
}

void LogInFile(const char*, ...)
{
    return;
}
посмотри выше, я нашел фукнцию
 

Vintik

Мечтатель
Проверенный
1,469
917
посмотри выше, я нашел фукнцию
Вижу, можешь и ту оставить. Но тебе вряд-ли нужен лог, ты ж туда даже смотреть не будешь.
А что касаемо самого обхода — мутный он какой-то. Не допилен до конца...
 

qwertyrus

Новичок
Автор темы
23
2
Вижу, можешь и ту оставить. Но тебе вряд-ли нужен лог, ты ж туда даже смотреть не будешь.
А что касаемо самого обхода — мутный он какой-то. Не допилен до конца...
Я нашел статью по самой провинции(где я и тестирую) 3 месячной давности, там почти 1 в 1 обход, но отличия есть. Вот думаю щас протестить этот наверно, потом тот

Вижу, можешь и ту оставить. Но тебе вряд-ли нужен лог, ты ж туда даже смотреть не будешь.
А что касаемо самого обхода — мутный он какой-то. Не допилен до конца...
всё еще крашит, видимо дело не только в том что криво определил, успевает одну координату вывести и крашит(в сампе тоже попробовал, также выводит одну и крашит)
 
Последнее редактирование:
Статус
В этой теме нельзя размещать новые ответы.