Гайд Создание читов для игр на движке сурс для младенцев. хукинг эндсцены

гений, плейбой, но не миллиардер
Пользователь
Статус
Оффлайн
Регистрация
6 Июн 2017
Сообщения
137
Реакции[?]
90
Поинты[?]
4K
Изначально эта статья писалась для форума эвольва. Но ее автор я, приступим.

Что нам нужно:
IDA Pro с SigMaker плагином
Visual Studio или CLion
x32dbg для дебага
DirectX SDK.

Первое:
Инклудим минхуки, и дхсдк. Пример для cmake:
Код:
include_directories(
        "C:\\Users\\chrshnv\\Desktop\\dxsdk\\Include"
        "C:\\Users\\chrshnv\\Desktop\\minhook-master\\include"
)

link_directories(
        "C:\\Users\\chrshnv\\Desktop\\dxsdk\\Lib\\x86"
        "C:\\Users\\chrshnv\\Desktop\\minhook-master\\build\\VC16\\lib"
)
Теперь создаем наш поток с читом:
Код:
if ( dwReason == DLL_PROCESS_ATTACH )
    {
        CreateThread( nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(main_thread), 0, 0, 0 );
    }
код потока:
Код:
DWORD WINAPI main_thread( )
{
    hooks::init( );

    while( true )
    {
    }

    return TRUE;
}

Теперь нам нужна функция findPattern, я взял ее с csgosimple
C++:
std::uint8_t* helpers::pattern_scan(void* module, const char* signature)
{
    static auto pattern_to_byte = [](const char* pattern) {
        auto bytes = std::vector<int>{};
        auto start = const_cast<char*>(pattern);
        auto end = const_cast<char*>(pattern) + strlen(pattern);

        for(auto current = start; current < end; ++current) {
            if(*current == '?') {
                ++current;
                if(*current == '?')
                    ++current;
                bytes.push_back(-1);
            } else {
                bytes.push_back(strtoul(current, &current, 16));
            }
        }
        return bytes;
    };

    auto dosHeader = (PIMAGE_DOS_HEADER)module;
    auto ntHeaders = (PIMAGE_NT_HEADERS)((std::uint8_t*)module + dosHeader->e_lfanew);

    auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage;
    auto patternBytes = pattern_to_byte(signature);
    auto scanBytes = reinterpret_cast<std::uint8_t*>(module);

    auto s = patternBytes.size();
    auto d = patternBytes.data();

    for(auto i = 0ul; i < sizeOfImage - s; ++i) {
        bool found = true;
        for(auto j = 0ul; j < s; ++j) {
            if(scanBytes[i + j] != d[j] && d[j] != -1) {
                found = false;
                break;
            }
        }
        if(found) {
            return &scanBytes[i];
        }
    }
    return nullptr;
}

И функция get_virtual:
C++:
unsigned int helpers::get_virtual(void* _class, unsigned int index)
{
    return static_cast<unsigned int>((*reinterpret_cast<int**>(_class))[index]);
}

Теперь нам нужно найти паттерн. Открываем shaderapidx9.dll в иде и
Пожалуйста, авторизуйтесь для просмотра ссылки.


Если мы немного посмотрим в слитый исходный код, то увидим, что девайс называется D3DDevice и функции с использованием D3DDevice выкидывают ошибки.

Я к примеру возьму CIndexBufferDx8::Allocate: CreateIndexBuffer failed!\n.

Ищем эту строку в иде.
C++:
v4 = (*(int (__stdcall **)(int, _DWORD, int, _DWORD, int, _DWORD *, _DWORD))(*(_DWORD *)dword_1018698C + 104))(
         dword_1018698C,
         this[7],
         v3,
         0,
         v2,
         this + 2,
         0);
  if ( v4 == -2005532292 || v4 == -2147024882 )
  {
    (*(void (__stdcall **)(int))(*(_DWORD *)dword_1018698C + 20))(dword_1018698C);
    v4 = (*(int (__stdcall **)(int, _DWORD, int, _DWORD, int, _DWORD *, _DWORD))(*(_DWORD *)dword_1018698C + 104))(
           dword_1018698C,
           this[7],
           v3,
           0,
           v2,
           this + 2,
           0);
  }
  if ( v4 >= 0 && this[2] )
  {
    v5 = sub_100B4F10(this[4], this[5]);
    v6 = *(void (__thiscall ***)(int, _DWORD, bool, _DWORD, int, _DWORD, _DWORD))dword_1019EF24;
    v7 = ((__int64 (__thiscall *)(_DWORD *))*(_DWORD *)(*this + 8))(this);
    (*v6)(dword_1019EF24, this[2], (this[9] & 2) != 0, this[7], v5, v7, HIDWORD(v7));
    if ( (this[9] & 2) == 0 )
      *(_DWORD *)this[12] += this[7];
    result = 1;
  }
  else
  {
    Warning("CVertexBufferDx8::Allocate: CreateVertexBuffer failed!\n");
    result = 0;
  }

Референс из исходного кода движка:
C++:
HRESULT hr = Dx9Device()->CreateIndexBuffer(
        m_nBufferSize, usage, format, D3DPOOL_DEFAULT, &m_pIndexBuffer, NULL );

#if !defined( _X360 )
    if ( ( hr == D3DERR_OUTOFVIDEOMEMORY ) || ( hr == E_OUTOFMEMORY ) )
    {
        // Don't have the memory for this.  Try flushing all managed resources
        // out of vid mem and try again.
        // FIXME: need to record this
        Dx9Device()->EvictManagedResources();
        hr = Dx9Device()->CreateIndexBuffer(
            m_nBufferSize, usage, format, D3DPOOL_DEFAULT, &m_pIndexBuffer, NULL );
    }
#endif // !X360

    if ( FAILED(hr) || ( m_pIndexBuffer == NULL ) )
    {
        Warning( "CIndexBufferDx8::Allocate: CreateIndexBuffer failed!\n" );
        return false;
    }

По моему мнению
C++:
v4 = (*(int (__stdcall **)(int, _DWORD, int, _DWORD, int, _DWORD *, _DWORD))(*(_DWORD *)dword_1018698C + 104))(
           dword_1018698C,
           this[7],
           v3,
           0,
           v2,
           this + 2,
           0);
  }
это является вызовом виртуальной функции, с индексом 26.
Проверяем и видим, что CreateIndexBuffer имеет индекс 26, следовательно мы верно трактовали этот код, и dword_1018698C является нашим девайсом. Делаем паттерн, я считаю A1 ? ? ? ? 8D 53 08 красивым паттерном, поэтому возьму его.

Теперь нам надо просканировать паттерн.
Код:
IDirect3DDevice9* device = **( IDirect3DDevice9*** )( helpers::pattern_scan( GetModuleHandle( "shaderapidx9.dll" ), "A1 ? ? ? ? 8D 53 08" ) + 1 );

Инициализируем минхук:
C++:
if( MH_Initialize(  ) != MH_OK )
    throw std::runtime_error( "failed to initialize minhook" );

Создаем прототип эндсцены:
C++:
long __stdcall hooked_endscene( IDirect3DDevice9* device );
    typedef long( __stdcall* endscene_function )( IDirect3DDevice9* );
    extern endscene_function original_endscene;

Хукаем:
C++:
if( MH_CreateHook( target, reinterpret_cast<void*>( &hooked_endscene ), reinterpret_cast<void**>( &original_endscene ) ) != MH_OK )
        throw std::runtime_error( "failed to create endscene" );

    if( MH_EnableHook( MH_ALL_HOOKS ) != MH_OK )
        throw std::runtime_error( "failed to enable hooks" );

В нашем хуке возвращаем оригинал в самом конце.


Я не являюсь профессионалом в этой области, да и я свою же статью криво перевел, но надеюсь она вам понравится. Хев фан
 
saphire alpha user
Забаненный
Статус
Оффлайн
Регистрация
17 Июн 2021
Сообщения
68
Реакции[?]
57
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Годнота
 
гений, плейбой, но не миллиардер
Пользователь
Статус
Оффлайн
Регистрация
6 Июн 2017
Сообщения
137
Реакции[?]
90
Поинты[?]
4K
Отступление по внд проц:
сооздаем оригинал вндпроца:
WNDPROC original_wndproc


Прототип хука вндпроц:
LRESULT hooked_wndproc( HWND hwnd, UINT uparam, WPARAM wparam, LPARAM lparam )

Хукаем:
original_wndproc = reinterpret_cast<WNDPROC>( SetWindowLongPtr( FindWindow( "Valve001", nullptr ), GWLP_WNDPROC, ( LONG_PTR ) hooked_wndproc ) );

Код сразу под имгуи:
C++:
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
LRESULT hooks::hooked_wndproc( HWND hwnd, UINT uparam, WPARAM wparam, LPARAM lparam ) {
    if( ImGui_ImplWin32_WndProcHandler( hwnd, uparam, wparam, lparam ) )
        return true;

    return CallWindowProc( original_wndproc, hwnd, uparam, wparam, lparam );
}
 
Участник
Статус
Оффлайн
Регистрация
30 Дек 2020
Сообщения
400
Реакции[?]
293
Поинты[?]
1K
А где объяснения, что за что отвечает ?
Ты накидал код, чтобы его просто спастили, даже не понимая что они спастят...

Гайд не соответствует названию темы.
 
гений, плейбой, но не миллиардер
Пользователь
Статус
Оффлайн
Регистрация
6 Июн 2017
Сообщения
137
Реакции[?]
90
Поинты[?]
4K
А где объяснения, что за что отвечает ?
Ты накидал код, чтобы его просто спастили, даже не понимая что они спастят...

Гайд не соответствует названию темы.
thank u, next. Тебе буквально объяснили с референсами нахождение паттерна на девайс, с полным объяснением всего нахуй
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
30 Дек 2020
Сообщения
400
Реакции[?]
293
Поинты[?]
1K
thank u, next. Тебе буквально объяснили с референсами нахождение паттерна на девайс, с полным объяснением всего нахуй
1.Не вижу объяснений функции find pattern.
2."Теперь нам надо просканировать паттерн." - для чего, зачем ?
3."И функция get_virtual: " - что это и зачем ?
и так далее..

Ты ничего не объяснил, но считаешь это гайдом.
В гайде все должно быть подробно и понятно расписано.
Но в тоем случае я только вижу, что нам нужно спастить.
 
quality solution
Участник
Статус
Оффлайн
Регистрация
30 Май 2019
Сообщения
579
Реакции[?]
193
Поинты[?]
0
1.Не вижу объяснений функции find pattern.
2."Теперь нам надо просканировать паттерн." - для чего, зачем ?
3."И функция get_virtual: " - что это и зачем ?
и так далее..

Ты ничего не объяснил, но считаешь это гайдом.
В гайде все должно быть подробно и понятно расписано.
Но в тоем случае я только вижу, что нам нужно спастить.
Этот гайд сделан для тех, кто хоть чуточку понимает в геймхакинге, тебе не обязаны все разжёвывать
 
Участник
Статус
Оффлайн
Регистрация
30 Дек 2020
Сообщения
400
Реакции[?]
293
Поинты[?]
1K
Этот гайд сделан для тех, кто хоть чуточку понимает в геймхакинге, тебе не обязаны все разжёвывать
1625656458734.png
Мне это не нужно.
А если и делает гайды, то пусть делает все понятно и "разжёвано".
 
quality solution
Участник
Статус
Оффлайн
Регистрация
30 Май 2019
Сообщения
579
Реакции[?]
193
Поинты[?]
0
Посмотреть вложение 159461
Мне это не нужно.
А если и делает гайды, то пусть делает все понятно и "разжёвано".
Младенцы должны знать хотя бы элементарно принцип работы читов, уметь пользоваться идой, знать язык, если ты даже этого не знаешь, то что поделаешь
 
Сверху Снизу