C # Теоретический: написать JMP для кодовой пещеры в asm - PullRequest
6 голосов
/ 24 апреля 2009

Предположим, что я выделил адрес, на котором размещена моя кодовая пещера, с помощью 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().

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

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

Ответы [ 2 ]

4 голосов
/ 24 апреля 2009

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

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

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

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

CurrentInstructionPointer = AddressOfJumpInstruction + 5

UPDATE

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

1 голос
/ 10 августа 2011

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

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

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

VirtualAlloc C ++, внедренная dll, asm

...