Почему вставка символов в исполняемый двоичный файл приводит к его поломке?

Почему вставка символов в исполняемый двоичный файл приводит к его поломке?

И есть ли способ добавить символы, не нарушая скомпилированную программу?

Задний план

Я давно знал, что можно использовать шестнадцатеричный редактор для изменения кода в скомпилированном исполняемом файле, и он по-прежнему будет работать как обычно...

Пример

Например, в приведенном ниже приложении Facebook можно изменить на Lacebook, и программа по-прежнему будет выполняться нормально:

введите здесь описание изображения

введите здесь описание изображения

Но это ломается с новыми персонажами

Я также знаю, что если будут добавлены новые символы, это сломает программу, и она не запустится, или сразу рухнет. Например, добавление My перед Facebook приведет к следующему результату:

введите здесь описание изображения

Что я знаю

Чего я не знаю

  • Я не совсем понимаю связь между операционной системой и исполняемым файлом. Я предполагаю, что когда вы вводите имя программы и нажимаете клавишу возврата, вы, по сути, даете операционной системе указание выполнить этот файл, что в основном означает загрузку файла в память, установку указателя процессора на него и команду 'Go !'
  • Я понимаю, почему наличие лишних символов в текстовой строке двоичного файла может вызвать проблемы.

Что я хотел бы знать

  1. Почему лишние символы приводят к сбою программы?
  2. Что определяет, что программа сломана? ОС? ОС также держит эту программу в изолированной программной среде, чтобы в настоящее время она не приводила к сбою всей системы?
  3. Есть ли способ добавить дополнительные символы в текстовую строку скомпилированной программы через шестнадцатеричный редактор и не прерывать работу приложения?

person Steve Brown    schedule 31.12.2013    source источник
comment
Счетчик программ, как правило, абсолютный, поэтому, если вы будете что-то перемещать, все сломается.   -  person Kerrek SB    schedule 31.12.2013
comment
Очень хороший вопрос, но он требует большого ответа. Если все еще вокруг, я попытаюсь ответить, полностью, позже. А пока представьте, что функции находятся в памяти. Каждый раз, когда вы вызываете функцию, вы говорите коду перейти в определенное место. Если вы добавите дополнительные байты раньше, вы сдвинете код функции на X байтов, и, следовательно, инструкции больше не будут действительны, и вызов функции определенно не сделает то, что вы думаете. Все вызовы функций являются жестко запрограммированными указателями.   -  person nonsensickle    schedule 31.12.2013
comment
В вопросе 3: Нет. Предположим, вы вставили приветствие перед этой строкой Facebook. Затем каждая строка после этого сдвигается вверх на 5 позиций. Вам нужно будет найти каждую строку pointer, которая указывает на строку после вашего изменения, и увеличить ее. (И данные — это не только легко распознаваемые текстовые строки!) Вам также может понадобиться увеличить размер раздела данных в разных точках, если вам не повезет.   -  person Jongware    schedule 31.12.2013
comment
Если вы посмотрите на битовый шаблон F (46) и L (4C), вы заметите, что они имеют одинаковое количество битов, поэтому похоже, что где-то есть контрольная сумма, которая работает с битами. Если вы попробуете 34 ($), 43 (C) или 64 (d), это тоже может сработать. Все остальное сломает контрольную сумму   -  person cup    schedule 01.01.2014


Ответы (3)


Я не совсем понимаю связь между операционной системой и исполняемым файлом. Я предполагаю, что когда вы вводите имя программы и нажимаете клавишу возврата, вы в основном инструктируете операционную систему «выполнить» этот файл, что в основном означает загрузку файла в память, установку указателя процессора на него и сообщение ему 'Идти!'

Современные операционные системы просто отображают файл в память. Они не утруждают себя загрузкой страниц, пока это не понадобится.

Почему лишние символы приводят к сбою программы?

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

Что определяет, что программа сломана? ОС? ОС также держит эту программу в изолированной программной среде, чтобы в настоящее время она не приводила к сбою всей системы?

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

Есть ли способ добавить дополнительные символы в текстовую строку скомпилированной программы через шестнадцатеричный редактор и не прерывать работу приложения?

Наверное не надежно. Как минимум, вам нужно будет надежно определить участки кода, которые необходимо скорректировать. Это может быть удивительно сложно, особенно если кто-то пытался сделать это намеренно.

person David Schwartz    schedule 31.12.2013

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

Если что-то вставить в программу, то адрес всего после этого сдвигается вверх. Но те части программы, которые содержат ссылки на расположение программы и данных, не обновляются, они продолжают указывать на исходные адреса. Кроме того, таблица, содержащая размеры всех разделов, больше неверна, потому что вы увеличили размер любого раздела, который вы изменили.

person Barmar    schedule 31.12.2013

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

Смещения могут возникать в самом формате файла, например, в заголовке, который сообщает загрузчику, где находятся объекты в файле и насколько они велики.

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

Предположим, что в инструкции сказано «перейти на 200 байт вниз от того места, где мы сейчас находимся», и вы вставляете байт в эти 200 байтов (потому что там оказалась строка символов, которую вы хотите изменить). Ой; ветвь по-прежнему занимает 200 байт.

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

person Kaz    schedule 31.12.2013