Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 06298B10 CEGun::ComputeTgtLeadPosition
- Смотрим дизасм. В самом начале mov esi,ecx. Т.е., в ECX что-то содержится, иначе компилятор не стал бы его сохранять. Смотрим остальные регистры: EAX затирается, EDX затирается, ESI сохраняется и затирается, EDI сохраняется и затирается, EBX и EBP не используются. Значит, это обычный __thiscall (в ECX передается this, в стеке аргументы, вызываемая функция сама чистит стек). Скроллим в конец функции: retn 4. Т.е., у нас есть 4 байта аргументов. Заодно видим там mov al,1 в одной ветке и xor al,al (т.е., нечто эквивалентное, что mov al,0) в другой, что как бы намекает нам, что возвращается один байт, т.е., либо char, либо bool, а учитывая, в al пишутся 0 или 1 - это однозначно bool. Получаем прототип:
- bool __thiscall CEGun::ComputeTgtPosition(CEGun *this, int unknown);
- Изучаем, что происходит с аргументом unknown. Ищем его в списке локальных переменных перед кодом функции, тыкаем X на клавиатуре, видим, где он используется, смотрим оба места. В первом он читается в ECX, ниже что-то делается на FPU, после чего fstp куда-то, потом это читается в регистр, потом пишется по [ECX+0], то же самое повторяется для [ECX+4] и [ECX+8]. fstp выталкивает float, по адресу, взятому из аргумента, последовательно пишутся три float, что вместе с названием функции наводит на мысль, что это указатель на трехмерный вектор. Определяем:
- struct Vector { float x, y, z; };
- Правим прототип:
- bool __thiscall CEGun::ComputeTgtPosition(CEGun *this, Vector *position);
- На самом деле, тебе повезло - функции поэкспортированы, у них есть имена, IDA их деманглит, и прототипы в дизасме уже правильные. А вот если переключиться в HexRays, видно, что он пиздит и показывает неверный прототип - мы уже знаем, что EDI затирается, а HexRays почему-то считает, что в нем передается один из аргументов. Можно тыкнуть Y на прототипе и переубедить HexRays.
- Дальше. Прототипы для хуков. Это метод класса, значит, проще всего тоже сделать класс (и отключить оптимизации в компиляторе):
- #include <cstdio>
- #include <cstdint>
- struct Vector { float x, y, z; };
- class CEGun
- {
- public:
- // Метод, которым мы заменяем оригинальный метод.
- bool ComputeTgtPosition(Vector *dest)
- {
- printf("Called method: this = %p, dest = %f, %f, %f\n", this, dest->x, dest->y, dest->z);
- return false;
- }
- };
- int main(void)
- {
- // Похуй, какой конкретно прототип будет - тебе не нужно его вызывать, тебе нужен только адрес.
- printf("Method address: %p\n", &CEGun::ComputeTgtPosition);
- // Объявляем указатель на метод.
- bool (CEGun::*methodPtr)(Vector *) = &CEGun::ComputeTgtPosition;
- // Тестим наш указатель (например, если ты захочешь в перехваченном методе
- // вызвать оригинальный, ты провернешь что-то подобное, только вместо gun
- // используешь this, а вместо methodPtr используешь адрес оригинального
- // метода).
- Vector testvec = { 1.0f, 2.0f, 3.0f };
- CEGun *gun = nullptr;
- (gun->*methodPtr)(&testvec);
- }
- В этом примере есть все конструкции, которые тебе могут понадобиться. В EasyHook кормишь methodPtr, оно перехватит метод, и при его вызове вызовется твой собственный ComputeTgtPosition.
Add Comment
Please, Sign In to add comment