Guest User

Untitled

a guest
Jul 28th, 2016
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.79 KB | None | 0 0
  1. 06298B10 CEGun::ComputeTgtLeadPosition
  2. Смотрим дизасм. В самом начале 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. Получаем прототип:
  3. bool __thiscall CEGun::ComputeTgtPosition(CEGun *this, int unknown);
  4. Изучаем, что происходит с аргументом unknown. Ищем его в списке локальных переменных перед кодом функции, тыкаем X на клавиатуре, видим, где он используется, смотрим оба места. В первом он читается в ECX, ниже что-то делается на FPU, после чего fstp куда-то, потом это читается в регистр, потом пишется по [ECX+0], то же самое повторяется для [ECX+4] и [ECX+8]. fstp выталкивает float, по адресу, взятому из аргумента, последовательно пишутся три float, что вместе с названием функции наводит на мысль, что это указатель на трехмерный вектор. Определяем:
  5. struct Vector { float x, y, z; };
  6. Правим прототип:
  7. bool __thiscall CEGun::ComputeTgtPosition(CEGun *this, Vector *position);
  8.  
  9. На самом деле, тебе повезло - функции поэкспортированы, у них есть имена, IDA их деманглит, и прототипы в дизасме уже правильные. А вот если переключиться в HexRays, видно, что он пиздит и показывает неверный прототип - мы уже знаем, что EDI затирается, а HexRays почему-то считает, что в нем передается один из аргументов. Можно тыкнуть Y на прототипе и переубедить HexRays.
  10.  
  11. Дальше. Прототипы для хуков. Это метод класса, значит, проще всего тоже сделать класс (и отключить оптимизации в компиляторе):
  12. #include <cstdio>
  13. #include <cstdint>
  14.  
  15. struct Vector { float x, y, z; };
  16.  
  17. class CEGun
  18. {
  19. public:
  20. // Метод, которым мы заменяем оригинальный метод.
  21. bool ComputeTgtPosition(Vector *dest)
  22. {
  23. printf("Called method: this = %p, dest = %f, %f, %f\n", this, dest->x, dest->y, dest->z);
  24. return false;
  25. }
  26. };
  27.  
  28. int main(void)
  29. {
  30. // Похуй, какой конкретно прототип будет - тебе не нужно его вызывать, тебе нужен только адрес.
  31. printf("Method address: %p\n", &CEGun::ComputeTgtPosition);
  32.  
  33. // Объявляем указатель на метод.
  34. bool (CEGun::*methodPtr)(Vector *) = &CEGun::ComputeTgtPosition;
  35.  
  36. // Тестим наш указатель (например, если ты захочешь в перехваченном методе
  37. // вызвать оригинальный, ты провернешь что-то подобное, только вместо gun
  38. // используешь this, а вместо methodPtr используешь адрес оригинального
  39. // метода).
  40. Vector testvec = { 1.0f, 2.0f, 3.0f };
  41. CEGun *gun = nullptr;
  42. (gun->*methodPtr)(&testvec);
  43. }
  44.  
  45. В этом примере есть все конструкции, которые тебе могут понадобиться. В EasyHook кормишь methodPtr, оно перехватит метод, и при его вызове вызовется твой собственный ComputeTgtPosition.
Add Comment
Please, Sign In to add comment