C# Теоретический: написать JMP для кодовой пещеры в asm
Предположим, что я выделил адрес, где размещена моя кодовая пещера, используя VirtualAllocEx
(возвращает адрес), и я пишу свой код в этот адрес, используя WriteProcessMemory()
,
Вот вопрос:
Как мне написать переход к моей кодовой пещере? Я знаю, что прыжки начинаются с "E9
", но как мне преобразовать адрес, возвращенный VirtualAllocEx
в правильный UInt32 (dword), чтобы отладчик / компилятор понял инструкцию?
Например:
Я по адресу 00402020
(OEP родного приложения). Я пишу прыжок в 004028CF
(пустое место)JMP 004028CF
Msgstr "Инструкция в байтах выглядит так:
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. см. мой пост в этой теме для получения дополнительной информации: