Итак, компьютерные программы / исполняемые файлы - это просто двоичные данные (0 и 1)?
Да, как изображения, видео и другие данные.
При просмотре с помощью дизассемблера, такого как OllyDbg, он просто пытается вернуть эти 0 и 1 обратно на некоторый язык ассемблера (Intel?), И вывод в основном правильный?
Да, в этом конкретном случае оно всегда будет правильным, поскольку mov al, 61h
всегда собирается в 0xB0 0x61
(в Руководства разработчика программного обеспечения для архитектуры Intel 64 и IA-32 и в других местах, обычно записываемых как B0 61
) в 16-, 32- и 64-битном режиме. Обратите внимание, что 0xB0 0x61
= 0b10110000 0b01100001
.
Вы можете найти кодировку для различных инструкций в Томе 2А. Например, здесь это «B0 + rb MOV r8, imm8 E Valid Valid Переместить imm8 в r8». на стр. 3-644.
Другие инструкции имеют разные значения, в зависимости от того, интерпретируются они в 16/32 или 64-битном режиме. Рассмотрим эту короткую последовательность байтов: 66 83 C0 04 41 80 C0 05
В 16-битном режиме они означают:
00000000 6683C004 add eax,byte +0x4
00000004 41 inc cx
00000005 80C005 add al,0x5
В 32-битном режиме они означают:
00000000 6683C004 add ax,byte +0x4
00000004 41 inc ecx
00000005 80C005 add al,0x5
И, наконец, в 64-битном режиме:
00000000 6683C004 add ax,byte +0x4
00000004 4180C005 add r8b,0x5
Таким образом, инструкции не всегда можно правильно разобрать, не зная контекста (это даже не принимая во внимание то, что в текстовом сегменте могут находиться другие вещи, кроме кода, а код может выполнять такие неприятные вещи, как генерация кода на лету или самообучение. изменить).
Если у меня есть эта программа 10110000 01100001 на моем SSD и я пишу приложение C # / PHP / wtvr, которое читает содержимое файла и выводит их в виде битов, я увижу эти точные цифры 10110000 01100001?
Да, в том смысле, что если приложение содержит инструкцию mov al, 61h
, файл будет содержать байты 0xB0
и 0x61
.
Как операционная система выполняет "выполнение"? Как это говорит процессору, что «эй, возьми эти биты и запусти их»? Могу ли я сделать это в C # / C ++ напрямую?
После загрузки кода в память (и память правильно настроена с точки зрения разрешений) он может просто перейти к нему или вызвать его и запустить. Одна вещь, которую вы должны осознать, хотя операционная система - это просто другая программа, это специальная программа, поскольку она сначала дошла до процессора! Он работает в специальном супервизорном (или гипервизорном) режиме, который допускает то, что обычным (пользовательским) программам запрещено. Подобно настройке вытесняющей многозадачности , которая обеспечивает автоматическое получение процессов.
Первый процессор также отвечает за пробуждение других ядер / процессоров на многоядерном / многопроцессорном компьютере. См. этот ТАК вопрос.
Для вызова кода, который вы загружаете непосредственно в C ++ (я не думаю, что это возможно в C # без использования небезопасного / нативного кода), требуются специфические для платформы приемы. Для Windows вы, вероятно, захотите взглянуть на VirtualProtect
и на linux mprotect(2)
. Или, возможно, более реалистично из файла, который отображается с помощью этого процесса для Windows или mmap(2)
для Linux.