А какие хроники клиента? Если ИЛ то там не получится хукнуть в лоб заменив первые 4 байта функции.
Почему именно первые 4? если в ИЛ то первый байт jmp следующие 4 адрес. В случае ИЛ хукается еще проще просто переписывается адрес 4 байта после джампа т.е. 2-5 байты.
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, что, очевидно, нежелательно).
вот кусок кода правда не мой но как пример подойдет :Оффтоп