Тайна бинарных файлов

Тайна бинарных файлов

Речь идет о файлах прямо из компилятора, скажем, g++, и -oфлаге (outfile).

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

Когда вы их распознаете, вы получаете неразборчивый вывод, но также и целые слова.

Если вы их подаете, то сразу получаете ответ - похоже, что никаких вычислений нет. Действительно ли двоичные файлы имеют заголовки с такой информацией?

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

Кроме того, если вы каким-то образом заполучите руководство к вашему процессору, сможете ли вы написать двоичный файл вручную, по одной машинной инструкции за раз? Это было бы ужасно неэффективно, нооченьбыло бы интересно, если бы вам удалось заставить его работать хотя бы для демонстрации «Hello World!».

решение1

Этот вопрос Суперпользователя:Почему вы не видите двоичный код, когда открываете двоичный файл в текстовом редакторе?довольно хорошо отвечает вашему первому пункту.

Двоичные и текстовые данные не разделены: это просто данные. Это зависит от интерпретации, которая делает их тем или иным. Если вы откроете двоичные данные (например, файл изображения) в текстовом редакторе, большая их часть не будет иметь смысла, поскольку они не соответствуют выбранной вами интерпретации (как текст).

Файлы хранятся в виде нулей и единиц (например, напряжение/отсутствие напряжения в памяти, намагниченность/отсутствие намагниченности на жестком диске). Вы не видите нулей и единиц при catоткрытии файлов, поскольку последовательности 0/1 не будут иметь большого смысла для человека; символы имеют больше смысла, а шестнадцатеричный дамп лучше подходит для большинства целей (попробуйте hexdumpна файле).

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

Наконец: да, вы можете писать программы на языке ассемблера, используя коды операций процессора напрямую. Взгляните наВведение в программирование на ассемблере UNIXиДокументация Intel x86для отправной точки.

решение2

Все файлы хранятся в виде 1 и 0, cat просто пытается интерпретировать каждый БАЙТ (8 бит) как символ, поэтому вы видите непонятные символы.

решение3

Все файлы по своей сути являются бинарными: они хранятся в виде последовательностибиты.

Части файлов фактически сгруппированы вбайты. Каждый файл состоит из целого числа байтов. Все системы Unix, и фактически почти все компьютеры, имеют байты, состоящие из 8 бит (известные какоктетыв сетевой терминологии). Существует естественный способ интерпретировать байты как 8-битные числа, т. е. числа от 0 до 2 8 -1 = 255.

Чтобы увидеть их как двоичные, вам нужен инструмент, который записывает их в двоичной нотации. Люди не очень хорошо приспособлены к двоичной нотации: слишком много времени уходит на то, чтобы что-то записать. Чаще используютшестнадцатеричныйнотация с 16 различными цифрами. Например, 41(шестьдесят пять в шестнадцатеричном формате) удобнее читать, чем 01000001(шестьдесят пять в двоичном формате). Вы можете использовать команду, напримерod(«восьмеричный дамп») или hexdumpили hdдля вывода списка файлов с восьмеричной или шестнадцатеричной записью для каждого байта ( od -t x1переключается в шестнадцатеричный формат).

Байты могут представлять символы. Существует несколькокодировки символовиспользуется в мире unix. Они все основаны наASCII, который определяет интерпретацию байтов от 0 до 127. Обратите внимание, что это определяет значение только для половины возможных значений байтов. Например, 65 представляет заглавную букву A, 97 представляет строчную букву a, 30 представляет цифру 0и т. д. Некоторые кодировки символов представляют каждый символ одним байтом; например, влатинский-1кодировка, 163 представляет £, 241 представляет ñи так далее. Максимальное количество символов, которые можно представить таким образом, составляет 256, что не так уж много; поэтому существуют другие кодировки, которые используют более одного байта на символ. Фактически стандартная кодировка в мире unix в настоящее время — этоUTF-8, который представляет собой кодировку переменной длины (разные символы занимают разное количество байтов) дляНабор символов Unicode.

Текстовый файл — это двоичный файл, который содержит понятный текст. Фактически, для программ unix файл является текстовым файлом, пока он соответствует двум условиям:

  • Текстовый файл не может содержать нулевой байт (байт с числовым значением 0). Этот байт не представляет никакой символ и используется как специальный внутренний маркер во многих программах обработки текста.
  • Текстовый файл состоит из последовательности строк, и каждая строка заканчивается символомновая линиясимвол (имеющий числовое значение 10).

Исполняемые файлы машины — это особый вид двоичных файлов. Если вы запустите команду catна них, вы увидите мусор с редкими фрагментами текста. Эти файлы могут по совпадению содержать команды и для вашего терминала. Вы можете использовать программу, stringsчтобы увидеть все текстовые фрагменты в двоичном файле, опустив непечатаемые символы.

Исполняемые файлы машины не являются последовательностью машинных инструкций: они также содержат немного дополнительной информации, которая сообщает операционной системе, как загрузить файл в память, обычно также некоторые данные, используемые программой, и, возможно, отладочную информацию. Большинство систем unix используютЭЛЬФФормат для исполняемых файлов машины. Этот формат определяет, как файл, содержащий машинный код, делится на разделы, и эта часть не зависит от архитектуры машины; некоторые разделы содержат код, и значение этого кода специфично для конкретной архитектуры машины.

Вы можете использовать команду objdump -D /path/to/machine-executableдля отображения списка исполняемого файла в удобной для чтения форме:язык ассемблера. Ну, в любом случае, читаемый обученным человеком. Язык ассемблера специфичен для архитектуры процессора и напрямую отображается в машинные инструкции.

Можно написать полную программу на языке ассемблера, но это редко делается для нетривиальных программ, потому что это занимает много времени. Если вы действительно сумасшедший, вы можете написать свою программу прямо в двоичном коде. Некоторые люди пытались придуматьсамая короткая возможная программа, которая печатаетHello world; Райан Хензи объясняет, как написать142-байтный исполняемый файл ELF для процессоров ПК; Брайан Райтерпроанализировал формат ELF и создал 45-байтовую программукоторую Linux готов выполнить (эта программа ничего не выводит).

Существуют также исполняемые файлы, которые не являются двоичными файлами; они известны какскрипты. И наоборот, существует множество двоичных файлов, которые не являются исполняемыми: изображения, видео, сжатые файлы, документы текстового процессора, библиотеки кода безвходная точка, исполняемые файлы для других архитектур процессоров, …

Связанный контент