В данный момент, пишу плагин на C++ для сервера Counter-Strike:Source. К сожалению, многие классы устарели, так как SDK уже года 2 как не обновлялся, однако, можно получить интерфейс класса, дизассемблировав линукс-бинарники сервера. С этим и связана проблема... Первый вопрос. И так, по порядку... Сначала я пытался использовать востановленый интерфейс класса CBasePlayer. Для этого я использовал IDA + мое ПО для построения класса. Получаю я примерно следующее: PS. Класс CBasePlayer наследует несколько классов, если что... Code: abstract_class IBasePlayer_G { public: ~IBasePlayer_G(); // 0 virtual void /*Unknown value*/ /*CBaseEntity*/ SetRefEHandle(CBaseHandle const&); // 1 virtual void /*Unknown value*/ /*CBaseEntity*/ GetRefEHandle(void)const; // 2 virtual void /*Unknown value*/ /*CBaseEntity*/ GetCollideable(void); // 3 virtual void /*Unknown value*/ /*CBaseEntity*/ GetNetworkable(void); // 4 virtual void /*Unknown value*/ /*CBaseEntity*/ GetBaseEntity(void); // 5 virtual void /*Unknown value*/ /*CBaseEntity*/ GetModelIndex(void)const; // 6 virtual void /*Unknown value*/ /*CBaseEntity*/ GetModelName(void)const; // 7 virtual void /*Unknown value*/ /*CBaseEntity*/ SetModelIndex(int); // 8 virtual void /*Unknown value*/ /*CBasePlayer*/ GetServerClass(void); // 9 ... virtual void /*Unknown value*/ /*CBasePlayer*/ CommitSuicide(bool,bool); // 432 virtual void /*Unknown value*/ /*CBasePlayer*/ CommitSuicide(Vector const&,bool,bool); // 433 ... }; Я пытаюсь обратиться к методу CommitSuicide следующим образом: Code: reinterpret_cast< ICSPlayer_G* >( pBase )->CommitSuicide( Vector( 0, 0, 0 ), true, true ); Однако, этот код вызывает ошибку чтения памяти, и правда, во время отладки я вижу примерно следующее: Code: mov eax, [ecx] mov eax, [eax] call [eax + 421 * 4 ] Не понятно, почему вызывается функция с каким-то левым индексом, если я обращаюсь к CommitSuicide, у которой индекс равен 433? Второй вопрос. Я нашел решение своей проблемы, но мне не совсем ясна реализация этого решения. Я нашел на сайте, посвященном разработке плагинов для движка Source примерно следующий код: Code: class EmptyClass {}; static void CommitSuicide( CBaseEntity* pEntity ) { void **this_ptr = *(void ***)&pEntity; void **vtable = *(void ***)pEntity; void *func = vtable[433]; union { CBaseEntity *(EmptyClass::*mfpnew)( void ); void *addr; } u; u.addr = func; (reinterpret_cast<EmptyClass*>(this_ptr)->*u.mfpnew)(); } Он работает корректно, и убивает игрока, как положено. Однако, как видно из сигнатуры вызова, в него не передаются параметры из сигнатуры метода, который я получил, дизассемблировав бинарники. Как вы помните, он выглядит следующим образом: CommitSuicide(Vector const&,bool,bool). Как такое возможно? Функция работает корректно, но в нее не передаются необходимые параметры! PS. При отладке вышеупомянутой реализации, я получаю вызов по корректному индексу (433): Code: mov eax, [ecx] mov eax, [eax] call [eax + 433 * 4 ] Извиняюсь если сделал ошибки в ассемблерном коде, я лишь хотел показать индексы по которым вызываются виртуальные функции.