C# Теоретический: написать JMP для кодовой пещеры в asm

Предположим, что я выделил адрес, где размещена моя кодовая пещера, используя VirtualAllocEx (возвращает адрес), и я пишу свой код в этот адрес, используя WriteProcessMemory(),

Вот вопрос:

Как мне написать переход к моей кодовой пещере? Я знаю, что прыжки начинаются с "E9", но как мне преобразовать адрес, возвращенный VirtualAllocEx в правильный UInt32 (dword), чтобы отладчик / компилятор понял инструкцию?

Например:

Я по адресу 00402020 (OEP родного приложения). Я пишу прыжок в 004028CF (пустое место)JMP 004028CFMsgstr "Инструкция в байтах выглядит так:

CPU Disasm
Address   Hex dump      Command                                  Comments
00402020  E9 AA080000   JMP 004028CF

"E9"Вот как мы указываем JMP. Как насчет"AA080000"как мне это сгенерировать?

Мне нужно сделать что-то подобное, чтобы я мог инициализировать JMP к моей кодовой пещере, которая будет расположена по адресу, возвращенному VirtualAllocEx(),

Любая помощь будет с благодарностью!

Заранее спасибо.

2 ответа

Решение

E9 - относительный переход, поэтому последующие 32 бита - это просто смещение указателя текущей инструкции. Подробности см. В Руководстве разработчика программного обеспечения Intel® 64 и IA-32, том 2A: Руководство по набору инструкций, AM стр. 549 и далее. Для получения дополнительной информации см. Руководства разработчика программного обеспечения Intel® 64 и IA-32.

Таким образом, код операции для перехода с 00402020 на 004028CF должен быть следующим.

    E9 00 00 08 AA
Offset   = DestinationAddress - CurrentInstructionPointer
000008AA = 004028CF           - 00402025

Когда инструкция перехода выполнена, указатель инструкции уже установлен на следующую инструкцию. Таким образом, смещение инструкции перехода и текущее значение указателя инструкции отличаются на 5.

CurrentInstructionPointer = AddressOfJumpInstruction + 5

ОБНОВИТЬ

Исправлена ​​ошибка в значении текущей инструкции указателя. Спасибо, г-н.

Чтобы получить относительное смещение, просто вычтите адреса:

uint32_t patch_address = (uint32_t) VirtualAlloc(...);
uint32_t jmp_offset = patch_address - (current_offset + current_len);

примечание: current_len составляет 5 байт для инструкции JMP x86 E9. см. мой пост в этой теме для получения дополнительной информации:

VirtualAlloc C++, внедренный dll, asm

Другие вопросы по тегам