Гайд Безопасная инициализация и работа с SAMP [3]

  1. Создание ASI-плагина с нуля
  2. Хуки – что это такое и как с ними работать
  3. Безопасная инициализация и работа с SAMP
  4. Работа с рендером и Directx9
  5. Обработка событий окна + ImGui

В этом гайде будет рассказано как инициализироваться без потоков, а также как работать с SAMP'ом

При использовании на других ресурсах необходимо указание авторства и ссылки на оригинальную темы!

Все действия производились на Visual Studio 2019 с параметром /std:c++17, в других версиях интерфейс может отличаться.

И так, начнем:

Создаем новый проект, настраиваем его.
В свойствах проекта, в вкладке общие, стандарт языка C++ ставим /std:c++17

Добавляем sampapi в наш проект:

Первый способ:

  1. В верхнем меню жмем Git -> Создать репозиторий Git(Create git repository)
  2. В открывшемся окне выбираем либо github репозиторий, либо локальный репозиторий и жмем Создать.
  3. Снова жмем Git -> Открыть в командной строке (Open in command line).
  4. В консоли пишем git submodule add https://github.com/BlastHackNet/SAMP-API.git
  5. Ждем завершения операции и далее жмем Файл(File) -> Добавить(Add) -> Существующий проект (Existing projeect). Открываем папку с нашим проектом, заходим в папку SAMP-API и выбираем sampapi.vcxproj.
  6. Открываем настройки проекта, выбираем C/C++ -> Общие -> Дополнительные каталоги включаемых файлов(Additional directories of included files). Жмем изменить
    В открывшемся окне жмем на иконку файла со звездочкой, и жмем на появившуюся кнопку ...
    Переходим в директорию path_to_project\SAMP-API\include и жмем выбор папки.
  7. Переходим в настройки проекта sampapi
    Набор инструментов платформы(Build tools) - выбираем свое(у меня это v142
    Версия пакета SDK для Windows - выбираем свое(у меня это 10.0)
  8. Заходим в настройки нашего основного проекта, Компоновщик(Linker) -> Дополнительные каталоги библиотек(Additional library directories)
    Повторяем те же самые операции что в шаге 6, но выбираем папку path_to_project\SAMP-API\build\bin
  9. Далее переходим в вкладку Ввод(Input) и в поле Дополнительные зависимости(Additional dependecies) в начало вписываем Release\sampapi.lib; для Release конфигурации проект, и Debug\sampapi.lib;. Точка с запятой ОБЯЗАТЕЛЬНА
  10. Жмем правой кнопкой по проекту sampapi, Только проект -> Собрать только sampapi(делаем это для Release и Debug конфигураций)
Второй способ:
Скачиваем репозиторий, распаковываем по пути path_to_project
Повторяем шаги 5-10 из первого способа.

Готово, мы подключили sampapi

Теперь добавим библиотеку для хуков в наш проект:
Начну свое описание с подключения моей библиотеки для хуков - kthook
  1. Скачиваем kthook из репозитория и распаковываем в себе в папку с кодом(Пкм по проекту -> открыть папку в проводнике).
    Папку tests перекидывать к себе не нужно.
  2. Скачиваем ktsignal из репозитория и распаковываем содержимое ktsignal-master в папку kthook\ktsignal
  3. Жмем показать все файлы
    1631461120229.png
    ПКМ по папке kthook -> Включить в проект
  4. Т.к. мы не используем CMake, тогда мы должны вручную переназначить все зависимости для kthook
  5. Добавляем папку kthook в Дополнительные каталоги включаемых файлов(Additional directories of included files) (как в шаге 6 у sampapi)
  6. В kthook.hpp изменяем #include "ktsignal/ktsignal.hpp" на #include "ktsignal/include/ktsignal/ktsignal.hpp"
  7. Также ради собственного удобства добавляем kthook/include Дополнительные каталоги включаемых файлов(Additional directories of included files)

Вместо kthook могу посоветовать вам SRHook либо MinHook
SRHook подключается также как и kthook, MinHook можно подключить также двумя способами, как и sampapi.
Но я рекомендую установить его через vcpkg. vcpkg install minhook

И теперь перейдем к написанию кода:
SAMP инициализирует свои структуры в вызове CHud::DrawRadar, поэтому мы перехватим эту функцию, и после ее вызова будем уверены что самп инициализировался.
Для инициализации плагина лично я обычно использую хук на CTimer::Update
C++:
using CTimer__Update = void(__cdecl*)();
void* func_addr = reinterpret_cast<void*>(0x561B10);

Создаем хук:
C++:
#include "kthook/kthook.hpp"

using CHud__DrawRadar = void(__cdecl*)(); // Прототип CHud::DrawRadar

kthook::kthook_simple_t<CHud__DrawRadar> samp_init_hook{ reinterpret_cast<void*>(0x58A330) }; // хук на CHud::DrawRadar

Создаем функцию-коллбэк для хука:

C++:
#include "sampapi/CChat.h"
void HOOK_after_samp_init() {
    static bool inited = false; // переменная инициализации
    namespace samp = sampapi::v037r3; // Ваша версия сампа, у меня это 037r3
    if (!inited && samp::RefChat() != nullptr) { // если еще не инициализировались, и чат сампа уже инициализировался
        samp::RefChat()->AddMessage(0xFFFFFFFF, "Этот текст выведен после инициализации сампа"); // Выводим сообщение
        samp::RefChat()->m_debugColor = 0xFFFF0000; // Меняем цвет системных сообщений сампа на красный
        inited = true; // отмечаем что иницализировались
    }
}
samp::RefChat() аналогичен SF->getSAMP()->getChat()

Подключаем нашу функцию к хуку:

C++:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        samp_init_hook.after.connect(HOOK_after_samp_init); // Подключаем нашу функцию-коллбэк после вызова CHud::DrawRadar
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

C++:
#include <windows.h>
#include "sampapi/CChat.h"
#include "kthook/kthook.hpp"

using CHud__DrawRadar = void(__cdecl*)(); // Прототип CHud::DrawRadar

kthook::kthook_simple_t<CHud__DrawRadar> samp_init_hook{ reinterpret_cast<void*>(0x58A330) }; // хук на CHud::DrawRadar

void HOOK_after_samp_init() {
    static bool inited = false; // переменная инициализации
    namespace samp = sampapi::v037r3; // Ваша версия сампа, у меня это 037r3
    if (!inited && samp::RefChat() != nullptr) { // если еще не инициализировались, и чат сампа уже инициализировался
        samp::RefChat()->AddMessage(0xFFFFFFFF, "Этот текст выведен после инициализации сампа"); // Выводим сообщение
        samp::RefChat()->m_debugColor = 0xFFFF0000; // Меняем цвет системных сообщений сампа на красный
        inited = true; // отмечаем что иницализировались
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        samp_init_hook.after.connect(HOOK_after_samp_init); // Подключаем нашу функцию-коллбэк после вызова CHud::DrawRadar
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Компилируем, запускаем и видим:
1631464876180.png
 
Последнее редактирование:

loganhackerdff

Известный
868
520
simple хук чё сам после первого вызова убирается? надо бы после инициализации убрать хук
 

kin4stat

mq-team
Автор темы
Всефорумный модератор
2,731
4,693
simple хук чё сам после первого вызова убирается? надо бы после инициализации убрать хук
static bool inited же
Внутри самого слота нельзя делать дисконнект, т.к. это удаляет текущий итератор, в следовательно и при итерации все сломается
 

loganhackerdff

Известный
868
520
static bool inited же
Внутри самого слота нельзя делать дисконнект, т.к. это удаляет текущий итератор, в следовательно и при итерации все сломается
это то да, но зачем, можно же просто убрать хук после инициализации
 

ARMOR

kjor32 is legend
Модератор
4,827
6,013
Новый гайд, по новой делать вид как будто я все понял и просто переписывать код в VS и думать что я пиздец програмист после того как код заработал
 

etereon

MQ-Team
Проверенный
323
836
  • Нравится
  • Вау
Реакции: Hristot, PanSeek и AnWu
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
можно пожалуста проект, ничего не получается :ссссссссссссссссссссссссссссссссссссссссссссссссссссссссс
 

manukhov

Известный
126
128
Надо добавить, что для первого способа нужно установить Git для Windows в VS Installer
 
  • Нравится
Реакции: kin4stat

sc6ut

неизвестный
Модератор
382
1,074
а тут https://github.com/KiN4StAt/kthook/ преднамеренно папка xbyak при скачке пуста для подрыва пердаков?
я бы назвал это защитой от долбаебов, которые бросаются что то делать не научившись пользоваться базовыми вещами. почитай про гит братишка)
 
  • Нравится
Реакции: F0RQU1N and

Grinyov

Потрачен
2
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
1653383481412.png

Делал как надо, но тут какая-то херня. ПАМАГИТИ
 

ya_noob

Участник
57
7
почему папка xbyak пуста, хотя от xbyak.h многое зависит (файл которого нет)?

почему папка xbyak пуста, хотя от xbyak.h многое зависит (файл которого нет)?
Скачал с репозитория xbyak, закинул содержимое в папку с этим же названием. Все отлично, но есть одна проблема. EO135 пространство имен "kthook" не содержит члена "kthook_simple_t"
 

Вложения

  • Снимок экрана (188).png
    Снимок экрана (188).png
    166.6 KB · Просмотры: 42
Последнее редактирование: