Адреса в OllyDbg Изменение при перезагрузке программы

Это мой первый пост, и я новичок в сборке и отладке, так что терпите меня, пожалуйста.

Я пытался внедрить некоторый код (небольшой вызов MessageBoxA) в исполняемый файл Блокнота Windows 7. Однако я столкнулся с проблемой адресов. Сначала я открыл исполняемый файл в OllyDbg, затем перешел к строке, содержащей текст ASCII "notepad.pdb". Затем я поместил строку ASCII ниже этого (например, "INJECTED NOTEPAD"). Далее под этим я ввел этот код asm:

PUSH 0
PUSH address_of_ASCII_string ; In this case, 00A6B668C
PUSH address_of_ASCII_string ; In this case, 00A6B668C
PUSH 0
CALL MessageBoxA

Затем я перешел к первой строке кода в программе (просто щелкнув правой кнопкой мыши и нажав Go to Origin (или просто нажав * на цифровой клавиатуре)) Затем я заменил первую строку инструкцией JMP на адрес первого Нажмите 0 в моем введенном коде. Затем я вставил замененную инструкцию в конец своего введенного кода. После этого я помещаю инструкцию JMP в строку кода после моей инструкции JMP, которая переходит к моему введенному коду (да, я только что описал кодовую пещеру или что-то вроде этого). Все работает нормально, когда я его запускаю. Однако, когда я сохраняю измененный код в новом исполняемом файле и снова запускаю его с OllyDbg, он не работает. Когда я пытаюсь сослаться на строку ASCII, которую я вставил, адрес совершенно неверный. Пример в картинках ниже:

Как видите, я помещаю строку в стек, но когда я снова загружаю измененную программу в отладчик, адрес строки изменяется, а мой код - нет. Поэтому, когда я вызываю функцию MessageBoxA, она выдает ошибку, потому что я загрузил неправильный адрес для аргументов Text и Caption. Как это исправить?

1 ответ

То, с чем вы столкнулись, - это эффекты ASLR. Короче говоря, это означает, что исполняемый файл, работающий в ОС (в данном примере Windows), не будет иметь один и тот же базовый адрес при нескольких выполнениях.

Итак, есть несколько способов внедрить ваш код в другой двоичный файл, я опишу здесь 2, и я также угадаю (после прочтения комментариев), что вы пытаетесь исправить двоичный файл, находящийся на диске.

  1. Исправление двоичного файла на диске:

    а. Первый способ сделать это - убрать таблицу перемещения из PE. Я бы определенно не рекомендовал этот способ, поскольку в будущем он может вызвать сбой исполняемого файла в случае, если он не будет загружен на свой предпочтительный базовый адрес ( OptionalHeader.ImageBase), который является значением по умолчанию, которое все инструкции, нуждающиеся в перемещении, будут использовать в качестве базы для добавления. смещение к.

    Допустим, у вас есть строка со смещением 0x600 из базы изображений, если исполняемый файл сопоставлен с его предпочтительным базовым адресом (обычно 0x00400000) строка будет храниться по адресу 0x00400000, Ваш компилятор будет связывать файл с адресом 0x00400000 + 0x600 так 0x00400600, Что происходит, когда исполняемый файл загружается на другой базовый адрес? В этом случае загрузчик исполняемого файла Windows будет добавлять смещение базового адреса (фактически сопоставленного минус предпочтительный базовый адрес) к каждой записи перемещения (в приведенном выше примере он понадобится). Так что в случае, если исполняемый файл будет загружен в 0x00500000 загрузчик добавит 0x00100000 к этой записи перемещения, ведущей к абсолютному адресу 0x00500600,

    б. Второй путь - добавить запись о перемещении в двоичный файл. Таким образом, в отличие от способа, описанного в (а), вы не будете вредить двоичному файлу и добавите только запись о перемещении, которая при загрузке исполняемого файла загрузчик изменит адрес на правильный (если вы добавили правильный запись).

    с. Напишите независимый от позиции код и исправьте двоичный файл, используя этот код. Пример:

    sub     esp, 10*4
    mov     byte [esp], 0x68 ; 'h'
    mov     byte [esp + 1], 0x69 ; 'i'
    mov     byte [esp + 2], 0x00 ; null byte
    mov     byte [esp + 3], 0x79 ; 'y'
    mov     byte [esp + 4], 0x6f ; 'o'
    mov     byte [esp + 5], 0x75 ; 'u'
    mov     byte [esp + 6], 0x00 ; null byte
    mov     eax, esp
    push    0
    push    eax
    add     eax, 3
    push    eax
    push    0
    call    [MessageBoxA]  
    

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

  2. Исправление двоичного файла в памяти:

    а. Независимый код позиции (см. Выше)

    б. Используйте VirtualAllocEx, этот API, после вызова, вернет адрес, по которому вы можете написать, таким образом, вы просто располагаете сопоставленный адрес в памяти и знаете, куда и как внедрить свой код.

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