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

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

Вот вопрос:

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

Например:

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

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

«E9» - это то, как мы обозначаем JMP. Что насчет "AA080000", как мне его сгенерировать?

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

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

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


person Ivan Prodanov    schedule 24.04.2009    source источник
comment
Что за бит С # в этом вопросе?   -  person Steven    schedule 24.04.2009


Ответы (2)


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

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

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

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

CurrentInstructionPointer = AddressOfJumpInstruction + 5

ОБНОВЛЕНИЕ

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

person Daniel Brückner    schedule 24.04.2009
comment
Я спрашиваю, как преобразовать 004028CF в AA080000, как преобразовать адрес назначения в эти 32 бита, чтобы инструкция стала действительной? - person Ivan Prodanov; 24.04.2009
comment
Вы могли бы сообщить мне адрес назначения - (минус) текущий адрес, вместо этого предоставив мне этот PDF-файл на 600 страниц. Однако, как я уже упоминал, я ценю ваши усилия, поэтому я принимаю ваш ответ. Спасибо! - person Ivan Prodanov; 24.04.2009
comment
@ Дэниел: то, что ты здесь говоришь, неправильно! Правильная формула для этого случая: до - от - 5 - person newgre; 24.04.2009
comment
Если подумать, что E9 - это относительный переход, то последующие 32 бита являются просто смещением к текущему указателю инструкции. проясняет смысл. ^^ Меня немного смутил ваш AA080000, потому что он не соответствует разнице, и я хотел подтвердить, что прав, прежде чем добавлять пример. - person Daniel Brückner; 24.04.2009
comment
На самом деле, вы ошибаетесь! Его AA, а не AF. Jmp имеет длину 5 байтов, он начинает считать после этих 5 байтов, поэтому AF-5 = AA. Правильный? ;) - person Ivan Prodanov; 24.04.2009
comment
Спасибо, jn. Проверено в мануале и обновлен ответ. Я некоторое время не занимался программированием на ассемблере ... начинаю забывать и не могу вспомнить, что push SP также помещает в стек. СП или СП + 4? - person Daniel Brückner; 24.04.2009
comment
ESP (на x86) всегда указывает на последний недавно отправленный элемент в стеке. Когда вы помещаете элемент в стек, сначала уменьшается значение ESP, а затем параметр сохраняется в [ESP]. - person newgre; 24.04.2009

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

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

person mschmoock    schedule 10.08.2011