Ну давай попробую рассказать, как бы я делал. Вот условно есть функция, давай получим паттерны самой функции для хука например и так же паттерн для получения глобальной s_pLocalPlayer:
Посмотреть вложение 321324
Паттерн самой функции это уникальная последовательность инструкций(машинных кодов, ассемблера), которая будет только у этой функции, для этой функции push rbx, sub rsp, 20h явно не уникально, но вот следующие строчки скорее всего будут её выделять, ну что гадать, перейду во вкладку HexView и посмотрим(каретка должна быть установлена в начале функции перед переходом, чтобы оказаться в начале функции в HexView):
Посмотреть вложение 321326
1 инструкция конкретная, на которой я сейчас нахожусь объединяется темно-зеленой обводкой, тоесть 0x40 0x53 = push rbx.
А вот как будет выглядеть строчка mov rax, cs:s_pLocalPlayer_0:
Посмотреть вложение 321327
Но нужно понимать, что при каждом обновлении игры инструкции хоть и не поменяются(скорее всего), но вот адреса в памяти точно могут съехать, поэтому условно тут инструкция выглядит как
48 8B 05 - это 3 байта отвечающие именно за mov rax на 64битной системе, а 4 байта после
7B 84 E7 00 - это оффсет до глобальной переменной cs:s_pLocalPlayer_0, так вот, после обновления оффсет точно улетит куда-нибудь на Гаити поэтому в паттерн включать его смысла нет, так что саму инструкцию мы оставим, а оффсет сделаем масской(будем допускать, что там могут быть любые значения)
48 8B 05 ?? ?? ?? ??. По такой аналогии я беру условно последовательность байт до вызова функции, если ты не понимаешь где заменять байты на ?? для начала попробуй с ИИ посидеть ему поскидывать инструкции, рано или поздно поймешь что к чему тут:
Посмотреть вложение 321329
40 53 48 83 EC 20 48 8B 05 ?? ?? ?? ?? 48 8B D9 48 3B C1 75 ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ??
Посмотреть вложение 321336
Дальше проверяю, насколько валидный паттерн у меня получился:
Посмотреть вложение 321330
Использую поиск по паттерну что только что собрал и:
Посмотреть вложение 321331/
Нашло 2 функции, 1 из них моя. Сейчас посмотрел, они идентичные по реализации, так что не критично, если у тебя так несколько функций и тебе критично, чтобы была только одна, увеличивай паттерн, собирай больше инструкций.
Ну собственно с функцией готово, теперь через паттерн скан можно получить её адрес который в этом билде
baseModule +
0x01F25B0 и хукать через MinHook.
Для глобальной перменной s_pLocalPlayer_0 ничего не поменяется, я просто паттерн буду делать не с начала функции, а с инструкции mov rax, cs:s_pLocalPlayer_0, так как ищем именно её.
Так же проверяю через поиск по массиву байт в IDA и кстати, если просто убрать 2 первые инструкции и начать поиск, у меня не нашло нужную инструкцию, добавил еще пару инструкций в паттерн получил:
48 8B 05 ?? ?? ?? ?? 48 8B D9 48 3B C1 75 ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 84 C0 74 ?? E8 ?? ?? ?? ??
Посмотреть вложение 321337
Результат поиска теперь:
Посмотреть вложение 321332
Ну и расскажу что с ним делать:
Ищешь адрес инструкции через паттерн скан -> получаешь -> читаешь, прочитаются именно байты
48 8B 05 7B 84 E7 00, берешь оттуда смещение:
7B 84 E7 00, видно, что тут младшим байтом вперед, и по факту смещение имеет значение
0xE7847B и система прочитает именно так, не надо ничего переворачивать(на всякий случай говорю). Смещение отсчитывается не от этой инструкции, а от следующей, тоесть:
Посмотреть вложение 321333
Инструкция начинается на адресе
25B6 и занимает 7 байт,
25B6+
7 =
25BD,
1801F25BD +
E7847B =
18106AA38
Жму G в IDA вставляю адрес:
Посмотреть вложение 321334
Посмотреть вложение 321335
Вуаля.