- 387
- 135
как создать коллбек на событие в игре?
ну, как "хуки" сетевые, только на внутриигровые события (любое действие, совершённое/спровоцированное игроком)
Последнее редактирование:
как создать коллбек на событие в игре?
ну, как "хуки" сетевые, только на внутриигровые события (любое действие, совершённое/спровоцированное игроком)
у меня на гитхабе в BulletTracer есть хук этой функцииСпасибо за ссылку! Правильно ли я понимаю, что функции из библиотеки SF и PSDK (в частности DoBulletImpact()) использует не только программист, но и игра? Т.е. этот хук действительно будет срабатывать на игровые события или только если эта функция будет вызвана из плагина?
Могу тебе кинуть пример хука на urmem DoBulletImpact. По логике вещей должен код работать, но 100 процентной гарантии не даю ибо пишу не со своего компа и пишу без компилятора. Скажу сам, я сам до сих пор не особо в хуках разбираюсь.
Ссылка на urmemC++:#include "urmem.hpp" urmem::hook hook;//Определение обьекта нашего хука(вроде правильно сказал по терминологии) //Определяем тело нашей функции куда мы хотим чтобы шли данные с хука void DoBulletImpact(void *_this,CEntity* owner, CEntity* victim, CVector* startPoint, CVector* endPoint, CColPoint* colPoint, int arg5) { hook.call<urmem::calling_convention::thiscall,void *, CEntity*, CEntity*, CVector *, CVector *, CColPoint *, int> (_this, owner, victim, startPoint, endPoint, colPoint, arg5); //Вызываем оригинальную функцию. } //В иницилизацию плагина hook.install(0x73B550, urmem::get_func_addr(&DoBulletImpact)); //Первый параметр метода - это куда мы ставим хук. //Второй - это адресс нашего метода или функции. Если это метод класса, то он должен быть статичным. //В выгрызку плагина hook.disable();
Ссылка на опредление метода DoBulletImpact и его адресс
Скажу от себя еще. Этой либой я лично не ставил хуки на thiscall и все делал исключительно на свой глаз и код может быть не рабочим.
//Убран код с подключением библиотек и mainloop().
urmem::hook urmemHook;
void UpdateAimingCoors(void* _this, void* edx, CVector const* AimingTargetCoors)
{
SF->getSAMP()->getChat()->AddChatMessage(-1, "UpdateAimingCoors");
SF->getSAMP()->getChat()->AddChatMessage(-1, "UpdateAimingCoors. posX: %f; posY: %f; posZ: %f",
AimingTargetCoors->fX,
AimingTargetCoors->fY,
AimingTargetCoors->fZ);
urmemHook.call<urmem::calling_convention::thiscall>
(_this, AimingTargetCoors);
}
void DoBulletImpact(void* _this, void* edx,
CEntity* owner, CEntity* victim,
CVector* startPoint, CVector* endPoint,CColPoint* colPoint,
int arg5)
{
SF->getSAMP()->getChat()->AddChatMessage(-1, "DoBulletImpact");
urmemHook.call<urmem::calling_convention::thiscall>
(_this, owner, victim,
startPoint, endPoint, colPoint,
arg5);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
switch (dwReasonForCall)
{
case DLL_PROCESS_ATTACH:
SF->initPlugin(mainloop, hModule);
urmemHook.install(0x50CB10, urmem::get_func_addr(&UpdateAimingCoors));
urmemHook.install(0x73B550, urmem::get_func_addr(&DoBulletImpact));
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
urmemHook.disable();
break;
}
return TRUE;
}
Как минимум у самой функции хука DoBulletImpact должно быть соглашение о вызове __fastcall (если msvc, на mingw __thiscall)Что я делаю неправильно?
Добавление __fastcall ничего не изменило, на __thiscall жалуется VS.Как минимум у самой функции хука DoBulletImpact должно быть соглашение о вызове __fastcall (если msvc, на mingw __thiscall)
urmem не пользовался, сказать не могуДобавление __fastcall ничего не изменило, на __thiscall жалуется VS.
urmem не пользовался, сказать не могу
__fastcall на обе функции нужен
//Убран код с подключением библиотек и mainloop().
urmem::hook urmemHook;
void __fastcall UpdateAimingCoors(void* _this, void* edx, CVector const* AimingTargetCoors)
{
SF->getSAMP()->getChat()->AddChatMessage(-1, "UpdateAimingCoors");
SF->getSAMP()->getChat()->AddChatMessage(-1, "UpdateAimingCoors. posX: %f; posY: %f; posZ: %f",
AimingTargetCoors->fX,
AimingTargetCoors->fY,
AimingTargetCoors->fZ);
urmemHook.call<urmem::calling_convention::thiscall>
(_this, AimingTargetCoors);
}
void __fastcall DoBulletImpact(void* _this, void* edx,
CEntity* owner, CEntity* victim,
CVector* startPoint, CVector* endPoint,CColPoint* colPoint,
int arg5)
{
SF->getSAMP()->getChat()->AddChatMessage(-1, "DoBulletImpact");
urmemHook.call<urmem::calling_convention::thiscall>
(_this, owner, victim,
startPoint, endPoint, colPoint,
arg5);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
switch (dwReasonForCall)
{
case DLL_PROCESS_ATTACH:
SF->initPlugin(mainloop, hModule);
urmemHook.install(0x50CB10, urmem::get_func_addr(&UpdateAimingCoors));
urmemHook.install(0x73B550, urmem::get_func_addr(&DoBulletImpact));
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
urmemHook.disable();
break;
}
return TRUE;
}
Конечно, блять, не работает. На один обьект надо вешать один хук. У тебя на один обьект 2 хука.C++://Убран код с подключением библиотек и mainloop(). urmem::hook urmemHook; urmemHook.install(0x50CB10, urmem::get_func_addr(&UpdateAimingCoors)); urmemHook.install(0x73B550, urmem::get_func_addr(&DoBulletImpact)); }
Вот так сделал, не работает.
Конечно, блять, не работает. На один обьект надо вешать один хук. У тебя на один обьект 2 хука.
urmem::hook urmemHookAimingCoords;
void __fastcall UpdateAimingCoors(void* _this, void* edx, CVector const* AimingTargetCoors)
{
SF->getSAMP()->getChat()->AddChatMessage(-1, "UpdateAimingCoors");
SF->getSAMP()->getChat()->AddChatMessage(-1, "UpdateAimingCoors. posX: %f; posY: %f; posZ: %f",
AimingTargetCoors->fX,
AimingTargetCoors->fY,
AimingTargetCoors->fZ);
urmemHookAimingCoords.call<urmem::calling_convention::thiscall>
(_this, AimingTargetCoors);
}
urmem::hook urmemHookDoBulletImpact;
void __fastcall DoBulletImpact(void* _this, void* edx,
CEntity* owner, CEntity* victim,
CVector* startPoint, CVector* endPoint,CColPoint* colPoint,
int arg5)
{
SF->getSAMP()->getChat()->AddChatMessage(-1, "DoBulletImpact");
SF->getSAMP()->getChat()->AddChatMessage(-1, "DoBulletImpact. posX: %f; posY: %f; posZ: %f",
endPoint->fX,
endPoint->fY,
endPoint->fZ);
urmemHookDoBulletImpact.call<urmem::calling_convention::thiscall>
(_this, owner, victim,
startPoint, endPoint, colPoint,
arg5);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
switch (dwReasonForCall)
{
case DLL_PROCESS_ATTACH:
SF->initPlugin(mainloop, hModule);
urmemHookAimingCoords.install(0x50CB10, urmem::get_func_addr(&UpdateAimingCoors));
urmemHookDoBulletImpact.install(0x73B550, urmem::get_func_addr(&DoBulletImpact));
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
urmemHookAimingCoords.disable();
urmemHookDoBulletImpact.disable();
break;
}
return TRUE;
}
Пытаюсь разобраться с Вашим примером. «Трамплин» fpDoImpact совсем непонятный, можете объяснить что это, зачем нужно и как это объявить без классов?у меня на гитхабе в BulletTracer есть хук этой функции
kin4stat - Overview
18 y.o. student :). kin4stat has 50 repositories available. Follow their code on GitHub.github.com
Пытаюсь разобраться с Вашим примером. «Трамплин» fpDoImpact совсем непонятный, можете объяснить что это, зачем нужно и как это объявить без классов?
typedef void(__fastcall* DoBulletImpact)(void*, void*, CEntity*, CEntity*, CVector*, CVector*, CColPoint*, int);
DoBulletImpact fpDoImpact = 0;
void __fastcall DoBulletImpactHooked(void* weapon, void* EDX, CEntity* owner, CEntity* victim, CVector* startPoint, CVector* endPoint, CColPoint* colPoint, int arg5) {
if (victim != nullptr) {
}
return fpDoImpact(weapon, EDX, owner, victim, startPoint, endPoint, colPoint, arg5);
}
MH_CreateHook((void*)0x73B550, &DoBulletImpactHooked, reinterpret_cast<LPVOID*>(&fpDoImpact));
MH_EnableHook((void*)0x73B550);
C++:typedef void(__fastcall* DoBulletImpact)(void*, void*, CEntity*, CEntity*, CVector*, CVector*, CColPoint*, int); DoBulletImpact fpDoImpact = 0; void __fastcall DoBulletImpactHooked(void* weapon, void* EDX, CEntity* owner, CEntity* victim, CVector* startPoint, CVector* endPoint, CColPoint* colPoint, int arg5) { if (victim != nullptr) { } return fpDoImpact(weapon, EDX, owner, victim, startPoint, endPoint, colPoint, arg5); }
C++:MH_CreateHook((void*)0x73B550, &DoBulletImpactHooked, reinterpret_cast<LPVOID*>(&fpDoImpact)); MH_EnableHook((void*)0x73B550);
В папке build2.0 не появилось файла с расширением .sln. Уточните, в CMake в поле исходников нужно указывать папку, скачанную из ГитХаба или что-то другое? Я скачал архив и распаковал minhook-master в проект в папку SDK, теперь в папке SDK\Minhook всего четыре папки и один документ: Libs, Includes, build2.0, minhook-master и CMakeLists.txt. Зачем там Libs и Includes — пока непонятно.Насколько я понимаю, тебе для начала нужно понять как подключать статические/динамические библиотеки в целом.
Нашёл один гайдик на msdn, он как раз под твой случай, разве что он ориентирован на подключение библиотеки динамической компоновки (DLL).
- Факин msdn (для начала стоит по нему пробежаться)
Вроде бы я понял, что тебя именно надо, так что можешь попробовать следовать этому гайдику:
1) Сперва тебе надо получить .lib библиотеку для включения в проект, а также заголовки этой библиотеки (.h).
2) Дальше я попытаюсь объяснить как их получить, но потом ты должен их по своему желанию распределить в проекте по папкам. Например создашь папку sdk (ужасная практика, но пусть будет так). Далее в ней создашь папочку MinHook и туда вставишь заголовочные файлы и файл библиотеки по папкам (includes и Libs соответственно). Опять же подмечу - это ужасная практика, я ее не рекомендую даже знать. Желательно так всё распределить, чтобы при подключении можно было видеть откуда эта шняга, к примеру: #include <MinHook/MinHook.h>
Ниче сложного нет, но ты наверное потеряешь связь с реальностью после этого. Да и тем более проект не крупный. Так что мое предложение сойдет.
3) Давно не юзал минхук, но вроде помню, что изначально там нету файла либы (.lib). Тебе её надо получить. Идёшь в их репо на github, клонируешь его к себе. Берешь утилитку Cmake, фигачишь туда путь до CMakeList.txt и ставишь output каталог, можешь, к примеру, назвать как build2.0 (практика еще ужаснее, чем прошлая).
По итогу:
Посмотреть вложение 91885
p.s: (это всё примеры, я на самом деле ниче не собирал, т.к мне лень. По памяти буду писать)
Тыкаешь Configure с дефолт пресетами, если у тебя жизнь мёдом, то всё будет ок, а если будут траблы, то гугли.
Помочь с пониманием того, какая у тебя жизнь, поможет лог снизу. Если там всё ДАН, то идешь дальше.
Посмотреть вложение 91886
4) Идешь в папку build2.0, открываешь солюшн нашего минхука. Вроде minhook.sln или чёт такое, не помню. Собираешь солюшн (решение). Решений там дохуя наскок я помню. Все тебе их собирать вроде не нужно. Но т.к я не помню, что там за решения - собирай всё. Либо ищи minhook project, если он есть там, и собирай его.
Шлёпаешь в папку под названием... ... Если ты нихуя не менял, то она должна называться как конфигурация, под которой ты всё билдил. Debug там, release и вся эта шняга.
Вуаля, там лежит файл либы (статической).
Копируешь этот файл в свой проект в папку sdk\MinHook\Libs\Этотфайл.lib
5) Где ты нахуй будешь брать определения функций, если у тебя их нет. Идёшь как Херлок Шолмс искать файл заголовка/ов от минхука в той же папке, куда ты отдельно должен был склонировать их репо с github. Ищешь там папку include, в ней лежит MinHook.h. Копируешь его в свой проект: \свой проект\sdk\MinHook\includes\MinHook.h.
Готово.
6) Тепешь идешь в проект -> Свойства проекта.
Тут у нас есть отдельный котёл для наших либ. Для всего допотопного говна
мелкомягкие (microsoft) предусмотрели отдельные 2 раздела в иерархии свойств
проекта, специально для линковки ДОПОЛНИТЕЛЬНЫХ либ!
Там всё тоже самое, но с оговоркой: либы тут ДОПОЛНИТЕЛЬНЫЕ.
Грубо говоря это и есть те самые 2 котла для наших дополнительных:
- Включаемых каталогов
- Каталогов либ
Они только имеют в названии "допольнительных"!
Расположение:
Доп.каталоги включаемых файлов: C/C++ -> Общие (General) (Сюда ты пихаешь путь sdk\MinHook\includes)
Доп.каталоги либ: Компоновщик (Linker) -> Общие (General) (Сюды пихаешь sdk\MinHook\Libs)
Далее тебе надо задать в Additional Dependency (я хуй знает раздел, т.к вс не открыта). Поищи. Добавляешь название либы, которую ты получил с окончанием .lib
7) Идешь в файл с энтри поинтом или куда тебе там надо. В main.h может быть, я хуй знает. И добавляешь MinHook.h
Плюсом через прагма комментируешь объектный файл (про объектник тебе знать не надо, но ты делаешь именно это, эта препроцессорная директива оставит коммент для объектника о том: какое название либы, юзер коммент (то самое название либы), версия компилятора, опции для линкера и т.п) (#pragma comment(lib, "название_либы.lib")). И всё, можешь юзать всё из минхуков.
Хочу подметить. Собирая это всё через gcc, он тебя пошлёт нахуй, т.к pragma comment - это фишка МелкоМягких.
8) Этот гайд написан новичком для новичка с целью осветить некоторые моменты, и самому въебать время на написание этой статьи. Но прийдется погуглить местами, т.к я наверное не всё описал.
Хочу чтобы меня крутые дяди по 15 лет, которые шарят больше, чем я, и могут что-то дополнить, - сделать это. Хочу посмотреть чего я не знаю и просветиться.
upd: по итогу я решил её собрать и подключить... BTW, эта d после разрядки - це debug версия значит.
Посмотреть вложение 91888
А ваще юзайте детур от мелкомягких, чё вы как лопухи.
p.s: объезд.lib топ!
src:
- github minhook
- кодпроджект (тут можно глянуть как в коде выглядит комментирование либы для объектника и юзание)
- факин гуд тред о минхуке (старый вроде, p.s: забыл глянуть дату поста, перед тем как закрыть вкладку)
1) Да, объяснил ниже.В папке build2.0 не появилось файла с расширением .sln. Уточните, в CMake в поле исходников нужно указывать папку, скачанную из ГитХаба или что-то другое? Я скачал архив и распаковал minhook-master в проект в папку SDK, теперь в папке SDK\Minhook всего четыре папки и один документ: Libs, Includes, build2.0, minhook-master и CMakeLists.txt. Зачем там Libs и Includes — пока непонятно.
Как собрать 32-битную версию?1) Да, объяснил ниже.
2) Ты не так разбил по папкам. Надо иначе, ниже объяснил.
Проект с гитхаба тебе нужно просто распаковать в любую другою папку. Но не в проект! И уж тем более не в SDK. SDK - это софт для разработки. Грубо говоря зависимости. Эта папка для зависимостей. А уже в ней есть папки MinHook и в ней Libs и includes. Ты должен собрать либу, которая у тебя должна быть абсолютно в другой папке. После чего ты получаешь файл либы и ищешь в папке github проекта хидер файлы .h. Их ты раскидываешь УЖЕ В СВОЙ проект в папку зависимостей - в нашем случае SDK/MinHook/Libs (для .lib), а SDK/MinHook/includes (для .h).
Почему в build2.0 не появилось файла sln? Перепроверьте то, как вы указали пути в Cmake. Там где source - там должен быть путь до папки github проекта. Там где папка для сбилженых бинарников - там указываешь тот же путь, но создаешь новую папку (но она вроде и сама должна создаться). Например build2.0.
Далее конфигурируешь через кнопку configure, там выбираешь версию vs которая у тебя стоит. После конфигурации нажимаешь Generate. Смотришь в лог снизу, чтобы было всё окей. Далее идешь в папку и там ищешь sln. Всё, дальше всё в гайде.