Итак, если я все правильно понял
Не совсем.
Это двоичный файл, и его данные непостижимы для нас, людей
Обычно двоичный файл непонятен человеку и машине, особенно когда цель файла неизвестна. Обратите внимание, что не все двоичные файлы являются исполняемыми файлами. Многие двоичные файлы - это файлы данных, которые не содержат никаких машинных инструкций. Вот почему расширения файлов используются при именовании файлов (в некоторых ОС). . Расширение com использовалось CP / M для обозначения исполняемого файла. . Расширение exe было добавлено MS-DOS для обозначения другого исполняемого формата файла. * nixes используют атрибут execute, чтобы указать, какие файлы могут быть выполнены, хотя это может быть как скрипт, так и код.
Как уже упоминалось другими, двоичные файлы, которые содержат числа, должны просматриваться программой hex dump или редактором hex, а не средством просмотра текста.
есть пример содержимого программы ping.exe
Этот файл на самом деле является перемещаемой программой, и не все данные в этом файле представляют машинный код. Здесь есть информация о программе, например, какие динамические библиотеки ей нужны, какие подпрограммы должны быть связаны, требования к стеку, памяти программ и данных, а также точка входа в программу. Операнды адреса в файле могут быть относительными значениями, которые должны быть рассчитаны до абсолютных значений, или ссылками, которые необходимо разрешить.
«Программный файл», о котором вы, вероятно, думаете, называется двоичным файлом изображения или дампом памяти программы. Такой файл будет содержать только машинный код и данные со всеми адресными ссылками, правильно установленными для выполнения.
даже если они знают код ассемблера (самый низкий уровень машинного языка.)
Язык ассемблера не совпадает с языком машин . Типичный (за исключением компьютеров с языками высокого уровня) процессор принимает машинный код в качестве ввода, по одной инструкции за раз. Операндами являются регистры или числовые адреса памяти. Язык ассемблера - это язык более высокого уровня, который может использовать символические метки для положений команд и переменных, а также заменять числовые коды операций мнемоникой. Программа на языке ассемблера должна быть преобразована в машинный язык / код, прежде чем она может быть фактически выполнена (обычно с помощью утилит, называемых ассемблером, компоновщиком и загрузчиком).
Обратная операция, дизассемблирование, может быть выполнена для программных файлов с некоторым успехом и потерей символической информации. Разборка дампа памяти или файла образа программы - это больше проб и ошибок, так как код и расположение данных должны быть определены вручную.
Кстати, есть люди, которые могут читать и кодировать (числовой) машинный код. Конечно, это намного проще на 8-битном процессоре или микроконтроллере, чем на 32-битном процессоре CISC с дюжиной режимов адресации памяти.