Просто наткнулся. Чтобы прояснить эту тему для остальных из нас: Расчет относительного смещения JMP для патча кодовой пещеры работает путем вычитания вашего адреса патча с вашим текущим адресом счетчика программы:
uint32_t patch_address = (uint32_t) VirtualAlloc(...);
uint32_t jmp_offset = patch_address - (current_offset + current_len);
Примечание: current_len - это количество байтов, которое принимает ваша инструкция JMP. Это зависит от того, является ли это коротким JMP (EB) или длинным прыжком (E9). В вашем примере 2 байта, но обычный JMP (E8 0x12345678) занимает 5 байтов.
Итак, здесь мы видим, что ваш пример не будет работать легко, потому что вам придется переопределить следующие байты, которые принадлежат следующему MOV и даже инструкции CALL. Это основано на том факте, что ваша кодовая пещера имеет большее расстояние до текущего смещения инструкции, поскольку она расположена в другом регионе в адресном пространстве.
Итак, вы можете скопировать перезаписанные 7 байт в свою пещеру. Это может работать, только если вы не связываетесь с регистрацией EDI в вашем патче (из-за «MOV ECX, EDI»). И вам придется исправить адрес CALLs, который вы перезаписываете. Так что это, вероятно, не лучшее место для размещения кодовой пещеры, но это выполнимо.
Я написал свою собственную библиотеку перехвата, которая заботится об универсальных аргументах регистров, очистке стека и перезаписанных дополнениях asm, но я предлагаю использовать вышеупомянутые фреймворки.
С уважением,
майкл