Посоны привет! Я тут это все читаю, чето все всё перехватывают. А я понять не могу - это все делается на клиенте с откусанной темидой и ГГ или прям со всем этим добром? Я просто пытаюсь делать хук и у меня крэшится. Причем крэшится не доходя до моего кода, но и не сразу, а только там где я залез своми грязнуми руками в енжин.длл.
Моя первая цель - вызвать MessageBox при вызове OnNpcHtmlMessage
Это все делается под геймгуардом и с темидой, не знаю влияет ли это как то. Просто бот л2тавер показывает что это возможно. Подсобите че не так делаю? Спасибо.
Твоя функция подмены должна быть по параметрам и возвращаемому значению идентична оригинальной функции. Вот так этот метод класса выглядит:
int __thiscall UGameEngine::OnNpcHtmlMessage(UGameEngine *this, struct User *, wchar_t *, int)
Твоя функция подмены должна быть по параметрам и возвращаемому значению идентична оригинальной функции. Вот так этот метод класса выглядит:
int __thiscall UGameEngine::OnNpcHtmlMessage(UGameEngine *this, struct User *, wchar_t *, int)
Это понятно, если я хочу жить после всего этого. Но щас для меня цель отобразить мессадж бокс и гори оно синим пламенем. Ведь должно же по логике проканать. Мне не надо сохранять стэк и прочее ведь? По сути че происходит - вызывается функция из енжин длл OnNpcHtmlMessage а там вместо ее кода уже мой тупо jmp а по этому жмп тупо call MessageBox.
я не переписываю адрес функции в таблице, я хукаюсь внутрь самой функции и мне в принципе пофигу на параметры.
memcpy(addr + 1, &ff, 4); неверно, так как нужно пересчитать относительное смещение т.е.
вместо &ff UGameEngine__OnNpcHtmlMessage - addr - 5;
вот расчет относительного смещения
========================
в отладчике после jmp виден адрес готового перехода который на самом деле вычесляется Оффтоп
Предположим, что функция A расположена по адресу 0×401000, а функция B – по адресу 0×401800. Далее мы определим требуемое относительное смещение. Разница между адресами данных функций составляет 0×800 байт, и мы хотим перейти из функции A в функцию B, так что нам пока не нужно беспокоиться об отрицательных смещениях.
Дальше следует хитрый момент. Предположим, что мы уже записали нашу инструкцию перехода по адресу 0×401000 (функции A), и что данная инструкция выполняется. CPU при этом сделает следующее: сначала он добавит длину инструкции к Указателю на Инструкцию [3] (или Программному Счетчику). Длина инструкции перехода равна пяти байтам, как мы установили ранее. После этого к Указателю на Инструкцию добавляется относительное смещение. Другими словами, CPU вычисляет новое значение Указателя на Инструкцию следующим образом:
instruction_pointer = instruction_pointer + 5 + relative_offset;
Поэтому для вычисления относительного смещения нам нужно переписать формулу в следующем виде:
relative_offset = function_B - function_A - 5;
Мы вычитаем 5, поскольку это длина инструкции перехода, которую CPU добавляет при запуске данной инструкции, а function_A is вычитается из function_B, так как это относительный переход. Разница между адресами функций равна, как мы помним, 0×800 байтам. (Например, если мы забудем вычесть function_A, то CPU перейдет по адресу 0×401800 + 0×401000 + 5, что, очевидно, нежелательно).
вот кусок кода правда не мой но как пример подойдет :Оффтоп