Русское сообщество по скриптингу

Как работает Hamsandwich и перехват spawn'а игрока

Все вопросы по скриптингу для Metamod, помощь в редактировании плагинов.
Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только скриптинга для
Metamod.


Правила при создании новой темы:
1. При вставке кода плагина необходимо использовать тег [pawn], в противном случае, если тег [pawn] не отображает ваш код, можно использовать тег [code].
2. Любые изображения должны быть загружены, как вложения к вашему сообщению.
3. При описании проблемы или запросе на помощь в редактировании плагина обязательно выкладывайте исходник плагина.

Как работает Hamsandwich и перехват spawn'а игрока

Сообщение Dekart » 06 июн 2012, 10:52

Добрый день!

Собственно возникла необходимость перехватывать spawn каждого игрока в начале раунда. Знаю что модуль Hamsandwich для AmxModX умеет это делать, пробовал разобраться в его исходниках, но не получилось.

Могли бы Вы подсказать как он перехватывает spawn игрока?
Аватара пользователя
Dekart
 
Сообщения: 16
Зарегистрирован: 04 май 2012, 09:45
Благодарил (а): 5 раз.
Поблагодарили: 0 раз.

Re: Как работает Hamsandwich и перехват spawn'а игрока

Сообщение Rejiser » 06 июн 2012, 12:18

Аватара пользователя
Rejiser
 
Сообщения: 2928
Зарегистрирован: 03 сен 2010, 16:23
Благодарил (а): 215 раз.
Поблагодарили: 675 раз.
Языки программирования: Counter-Strike 1.6

Re: Как работает Hamsandwich и перехват spawn'а игрока

Сообщение KORD_12.7 » 06 июн 2012, 15:25


_http://aghl.ru/ - Half-Life и Adrenaline Gamer: за пределами возможного
Аватара пользователя
KORD_12.7
Скриптер
 
Сообщения: 298
Зарегистрирован: 28 сен 2009, 10:14
Откуда: Владивосток
Благодарил (а): 142 раз.
Поблагодарили: 257 раз.
Опыт программирования: Больше трех лет
Языки программирования: Half-Life
Opposing Force
Adrenaline Gamer
Counter-Strike

Re: Как работает Hamsandwich и перехват spawn'а игрока

Сообщение Dekart » 25 июн 2012, 10:35



Это статья скорее о том как использовать Hamsandwich при кодинге на pawn для AmxModX.
Меня же интересует реализация механизмов работы этого модуля на С++.

---------------------------------------------------------------------------------



В этой теме судя по обсуждению, его участники приходят к какому-то решению, но самого решения нет.
Там же есть ссылка на Вы должны зарегистрироваться, чтобы видеть ссылки., где подробно рассматривается алгоритм перехвата, который заключается в получении адреса таблицы виртуальных функций класса через его экземпляр с последующим патчем адресов функций, но приведенное решение является лишь наброском.

На данный момент я использую такой код установки хука для Spawn, взятый с alliedmods:
[pawn]
  1. void *someFunc = NULL;

  2.  

  3. void SetHooks(void)

  4. {

  5.   //Полученние экземпляра класса игрока через ENTITY

  6.   const char *classname = "player";

  7.   edict_t *pEdict = CREATE_ENTITY();

  8.   CALL_GAME_ENTITY(PLID, classname, &pEdict->v);

  9.   if(pEdict->pvPrivateData == NULL)

  10.   {

  11.       REMOVE_ENTITY(pEdict);

  12.       return;

  13.   }

  14.  

  15.   //Получение таблицы виртуальных функций через pvPrivateData экземпляра

  16.   void *pthis = pEdict->pvPrivateData;

  17.   void **vtbl = *(void ***)pthis;

  18.   REMOVE_ENTITY(pEdict);

  19.   if(vtbl == NULL)

  20.     return;

  21.  

  22.   //Получаем адрес оригинальной функции Spawn

  23.   someFunc = vtbl[0];

  24.    

  25.   int **ivtbl = (int **)vtbl;

  26.  

  27.   //Меняем тип доступа к памяти и подменяем адрес оригинальной функции своей функцией Hook_Spawn;

  28.   DWORD oldflags;

  29.   if(VirtualProtect(&ivtbl[0], sizeof(int *), PAGE_READWRITE, &oldflags))

  30.   {

  31.     ivtbl[0] = (int *)Hook_Spawn;

  32.   }

  33. }
[/pawn]

Функция которая получает управление при spawn'е игрока имеет вид:
[pawn]
  1. void Hook_Spawn(void)

  2. {

  3.   void *pthis;

  4.   __asm mov pthis, ecx;

  5.  

  6.   //действия до вызова оригинала

  7.   SERVER_PRINT("::Spawn(void) prehook!\n");

  8.  

  9.   //вызов оригинальной функции

  10. #if defined _WIN32

  11.   reinterpret_cast<void (__fastcall*)(void*,int)>(someFunc)(pthis,0);

  12. #elif defined __linux__

  13.   reinterpret_cast<void (*)(void*)>(someFunc)(pthis);

  14. #endif

  15.  

  16.   //действия после вызова оригинала

  17.   SERVER_PRINT("::Spawn(void) posthook!\n");

  18. }
[/pawn]

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

Причины возникновения ошибки пока не ясны.
Аватара пользователя
Dekart
 
Сообщения: 16
Зарегистрирован: 04 май 2012, 09:45
Благодарил (а): 5 раз.
Поблагодарили: 0 раз.

Re: Как работает Hamsandwich и перехват spawn'а игрока

Сообщение 6a6kin » 25 июн 2012, 11:58

Чтобы выявить ошибку, выводите значения всех указателей, которые были получены "подпольными" путями: someFunc, pThis и т.д.
Функция SetHooks должна возвращать результат установки хуков, т.к. хук может быть и не установлен.
На заказ не пишу.
Аватара пользователя
6a6kin
Скриптер
 
Сообщения: 332
Зарегистрирован: 09 мар 2010, 16:40
Благодарил (а): 38 раз.
Поблагодарили: 278 раз.


Вернуться в Скриптинг

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5