Адреса в 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, и я также угадаю (после прочтения комментариев), что вы пытаетесь исправить двоичный файл, находящийся на диске.
Исправление двоичного файла на диске:
а. Первый способ сделать это - убрать таблицу перемещения из 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 необходимые строки в стек и переместит указатели на строки в стеке, таким образом, код не нуждается в перемещении, поскольку он является частью независимого от ядов кода кода.
Исправление двоичного файла в памяти:
а. Независимый код позиции (см. Выше)
б. Используйте VirtualAllocEx, этот API, после вызова, вернет адрес, по которому вы можете написать, таким образом, вы просто располагаете сопоставленный адрес в памяти и знаете, куда и как внедрить свой код.