Написание ВМ - правильно сформированный байт-код? - PullRequest
8 голосов
/ 12 мая 2010

Я пишу виртуальную машину на С просто для удовольствия. Хромой, я знаю, но, к счастью, я на ТАК, так что, надеюсь, никто не будет смеяться :))

Я написал очень быструю и грязную виртуальную машину, которая читает строки (моего собственного) ASM и делает вещи. Сейчас у меня только 3 инструкции: add, jmp, end. Все хорошо, и на самом деле очень круто иметь возможность кормить строки (делать что-то вроде write_line(&prog[1], "jmp", regA, regB, 0); и затем запускать программу:

while (machine.code_pointer <= BOUNDS && DONE != true)
{
    run_line(&prog[machine.cp]);
}

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

Мой вопрос больше относится к "наилучшей практике", но я думаю, что есть правильный ответ на него. Я делаю виртуальную машину способной читать двоичные файлы (сохраняя байты в unsigned char[]) и выполнять байт-код. Мой вопрос: это задача виртуальной машины, чтобы убедиться, что байт-код правильно сформирован или просто работа компилятора, чтобы убедиться, что бинарный файл, который он выдает, правильно сформирован?

Я спрашиваю об этом только потому, что произойдет, если кто-то отредактирует двоичный файл и испортит содержимое (удалит его произвольные части и т. Д.). Очевидно, что программа будет глючной и, вероятно, не будет работать. Это даже проблема ВМ? Я уверен, что люди намного умнее, чем я, нашли решение этих проблем, мне просто любопытно, что они!

Ответы [ 6 ]

15 голосов
/ 12 мая 2010

Это работа виртуальной машины, чтобы убедиться, что байт-код правильно сформирован, или это просто работа компилятора, чтобы убедиться, что бинарный файл, который он выдает, правильно сформирован?

Вам решать.

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

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

2 голосов
/ 12 мая 2010

Виртуальные машины, которые интерпретируют байт-код, обычно имеют некоторый способ проверки их ввода; например, Java выдаст VerifyError, если файл класса находится в несогласованном состоянии

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

2 голосов
/ 12 мая 2010

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

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

1 голос
/ 30 августа 2011

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

0 голосов
/ 14 мая 2010

Я бы сказал, что ваша виртуальная машина может позволить эмулированному процессору загореться, пока сама реализация виртуальной машины не потерпит крах. Как разработчик виртуальной машины, вы можете установить правила. Но если вы хотите, чтобы компании, выпускающие виртуальное оборудование, виртуально покупали ваш виртуальный чип, вам придется сделать что-то более простое для ошибок: хорошими вариантами может быть создание исключения (сложнее в реализации) или перезагрузка процессора (гораздо проще). Или, может быть, вы просто определяете каждый код операции как допустимый, за исключением того, что некоторые «недокументированы» - они делают что-то неуказанное, кроме сбоя вашей реализации. Обоснование: если (!) Ваша реализация виртуальной машины должна запускать несколько экземпляров гостя одновременно, было бы очень плохо, если бы один гость мог вызвать сбой других.

0 голосов
/ 12 мая 2010

Имеет смысл, чтобы компилятор делал как можно больше проверок работоспособности (поскольку он должен делать это только один раз), но всегда будут проблемы, которые не могут быть обнаружены статическим анализом, такие как стек [кашель] переполнение, ошибки диапазона массива и т. п.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...