С помощью https://github.com/icedland/iced из ассемблерных инструкций делается массив байт машинных инструкций — внутри C# проекта прямо. На лету. Получается просто массив двоичных данных. Потом этот массив записывается в память и с помощью такой магии:
Здравствуйте, Shmj, Вы писали:
S>Интересная, оказывается, есть возможность почти прямо из коробки.
Не вижу ничего интересного. Природа unsafe в C#/.Net такова, что можно делать всё, что угодно, включая секс с гусями.
Вот динамическое порождение верифицируемого кода в рантайм — это интересно, потому что можно получать высокопроизводительный код, не рискуя ни стабильностью, ни безопасностью.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Shmj, Вы писали:
S>Если этот делегат дернуть — то исполнятся машинные инструкции, которые вы сформировали в рантайме
Нда... когда программисту делать нечего, он... дёргает... делегаты
Ты зачем это всё понаписал? Ты хвалишься или спамишь? Или просто дурью маешься вместо бизнес-задач? Ну так до тебя Рихтер уже вволю намаялся — читай, вникай.
Здравствуйте, Shmj, Вы писали:
S>Интересная, оказывается, есть возможность почти прямо из коробки.
не проще написать библиотеку на c и вызвать через DllImport?
Здравствуйте, Евгений Музыченко, Вы писали: ЕМ>Значит, он либо пользуется каким-нибудь защищенным кодогенератором, порождающим заведомо безопасный код, либо не работает при включенном DEP.
Хм. Чисто академический вопрос: а что помешает моему приложению дёрнуть VirtualAlloc c PAGE_EXECUTE_READWRITE?
Сам JIT естественно делает именно это, иначе он бы не смог делать свою работу. Со стороны OS нет никакой возможности узнать, порождается ли код защищённым кодогенератором, или злонамеренным трояном.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Значит, он либо пользуется каким-нибудь защищенным кодогенератором, порождающим заведомо безопасный код, либо не работает при включенном DEP. ЕМ>У меня DEP включен по умолчанию, и явных исключений нет — значит, среди работающего у меня софта такого безобразия не имеется.
DEP/NX у всех включён по умолчанию. И даже наличие этого флажка на исполнимом файле, всего лишь означает, что он просто обещает быть совместим с этим режимом.
И это никак не связано с возможностью того, что процесс сам себе может выделить страницу памяти, и маркировать её как исполнимую.
А вот управление этим разрешением (на порождение или изменение исполнимого кода) — тоже существует в виде process mitigation policy, но врядли такой запрет можно ожидать от программы, которая полностью основана на JIT-рантайме, да ещё и с набором примитивов на борту, которые активно это используют.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Евгений Музыченко, Вы писали: ЕМ>>А, пардон, это я попутал DEP с политиками запрета исполнения неподписанного кода, которые в ядре уже давно обязательны, а в user-mode — пока еще добровольны. S>Ну, пока не очень понятно, как эти политики будут совмещаться с JIT. Ну, то есть можно, наверное, построить защиту на том, что право на динамическое порождение исполняемого кода предоставляется только коду, который подписан сертификатом производителя ОС. Тогда дотнет и джава смогут выполнять JIT, а какие-нибудь опенсорсные решения — не смогут. S>Но выглядит это всё довольно хрупко.
В Маке так и работает и ничего.
Если нет у приложения разрешения на JIT изначально то ему будет нельзя.
То есть при подписи указываем в специальном файле, что будет у нас JIT и подписываем.
Из замеченного, маководу не любят языки с JIT из-за этого дополнительного шага =)
Здравствуйте, _NN_, Вы писали: _NN>В Маке так и работает и ничего.
_NN>Если нет у приложения разрешения на JIT изначально то ему будет нельзя. _NN>То есть при подписи указываем в специальном файле, что будет у нас JIT и подписываем.
Но это же опять хрупко: смотрите, если гранулярность разрешения — приложение, то как мы отличим работу православного JIT от злоумышленного генератора в стиле топикстартера?
То есть мат ставится в три хода: Пишем нормальное, добронравное приложение, которое пользуется JIT. Подписываем официальным сертификатом благонадёжного разработчика. В приложении имеется дырка в стиле log4j, которая позволяет исполнять сторонний код (а способов такое сделать — много; тут и плагины, и уязвимости сторонних библиотек)
Засовываем через эту дырку сторонний код. Сам по себе этот код написан на IL, который обрабатывается всё ещё православным JIT.
Засунутый сторонний код порождает нативный код, который уже не является безопасным, и делает всякие нехорошести с приложением и его окружением.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Чего ни одна мало-мальски грамотно настроенная система сделать не даст.
Ну почему же в отдельном процессе, компьютере в песочнице делай что угодно
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Тогда какой в этом смысл? ТС же, типа, открыл возможность делать это везде и всегда.
Ну смысл такого рода бывает постоянно в том же C#. Деревья выражений, Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript ну и прочие динамические компиляторы.
Как тут Sinclair заметил
Вот динамическое порождение верифицируемого кода в рантайм — это интересно, потому что можно получать высокопроизводительный код, не рискуя ни стабильностью, ни безопасностью.
Да можно сгенерить код и безопасно выполнить в отдельном процессе песочнице
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Serginio1, Вы писали:
S>>в отдельном процессе, компьютере в песочнице делай что угодно
ЕМ>Тогда какой в этом смысл? ТС же, типа, открыл возможность делать это везде и всегда.
Ну если ты доверяешь этому коду или можешь его верифицировать безопасность, то проблем то нет.
Если не доверяешь, то песочница
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Ну если ты доверяешь этому коду или можешь его верифицировать безопасность, то проблем то нет. S>Если не доверяешь, то песочница
Ну вот я приобрел приложение, которое генерит код для выполнения каких-либо работ. Как я могу "верифицировать безопасность" любого кода, который оно может породить?
А если этот код будет всегда выполняться в отдельном процессе-песочнице, то какие функции, сложные или невозможные для "готового" кода, он мог бы выполнять?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Serginio1, Вы писали:
S>>Ну если ты доверяешь этому коду или можешь его верифицировать безопасность, то проблем то нет. S>>Если не доверяешь, то песочница
ЕМ>Ну вот я приобрел приложение, которое генерит код для выполнения каких-либо работ. Как я могу "верифицировать безопасность" любого кода, который оно может породить?
ЕМ>А если этот код будет всегда выполняться в отдельном процессе-песочнице, то какие функции, сложные или невозможные для "готового" кода, он мог бы выполнять?
Ну а как антивирусы верифицируют код? Есть инструменты которые могут помогать верифицировать. Так же можно верифицировать и Il код и нативный код.
Либо ты доверяешь источнику, либо нет
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>а как антивирусы верифицируют код?
По известным образцам вредоносного кода, по известным признакам его же. Здесь важно то, что однажды проверенный код не меняется со временем.
S>Либо ты доверяешь источнику, либо нет
Вот у Вас есть два варианта:
— купить у некой компании кофе-машину, поставить ее дома, и использовать самостоятельно;
— нанять у той же компании человека, который будет жить в Вашем доме и готовить Вам кофе.
Будет ли степень "доверия к источнику" одинаковой в обоих вариантах?
ЕМ>Вот у Вас есть два варианта:
ЕМ>- купить у некой компании кофе-машину, поставить ее дома, и использовать самостоятельно;
ЕМ>- нанять у той же компании человека, который будет жить в Вашем доме и готовить Вам кофе.
ЕМ>Будет ли степень "доверия к источнику" одинаковой в обоих вариантах?
Ну если ты не доверяешь источнику, то выполняй в песочнице! В чем проблема то?
Здравствуйте, Serginio1, Вы писали:
S> Ну если ты не доверяешь источнику, то выполняй в песочнице! В чем проблема то?
Вы намеренно тупите, или прикидываетесь? Что значит "доверяешь источнику"? Вот конкретно Вы каждому источнику либо доверяете безгранично, либо не доверяете совсем, или так есть какие-то промежуточные варианты?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Чего ни одна мало-мальски грамотно настроенная система сделать не даст.
Любой CLR это делает из коробки с первых версий. Это называется indirect call. Эта возможность была всегда, это просто нельзя было описать в C# нормальным языком без переписывания IL.
Здравствуйте, Sinclair, Вы писали:
S>что помешает моему приложению дёрнуть VirtualAlloc c PAGE_EXECUTE_READWRITE?
А, пардон, это я попутал DEP с политиками запрета исполнения неподписанного кода, которые в ядре уже давно обязательны, а в user-mode — пока еще добровольны.
Re[10]: Запуск нейтивного ассемблера из C# на лету
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Serginio1, Вы писали:
S>> Ну если ты не доверяешь источнику, то выполняй в песочнице! В чем проблема то?
ЕМ>Вы намеренно тупите, или прикидываетесь? Что значит "доверяешь источнику"? Вот конкретно Вы каждому источнику либо доверяете безгранично, либо не доверяете совсем, или так есть какие-то промежуточные варианты?
Да потому, что в .Net кодогенерация в рантайме это обычное и массовое явление.
Либо ты как разработчик используешь сторонний код то ты либо ему доверяешь, либо выполняешь в песочнице. Третий вариант не используешь вовсе
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Евгений Музыченко, Вы писали: ЕМ>А, пардон, это я попутал DEP с политиками запрета исполнения неподписанного кода, которые в ядре уже давно обязательны, а в user-mode — пока еще добровольны.
Ну, пока не очень понятно, как эти политики будут совмещаться с JIT. Ну, то есть можно, наверное, построить защиту на том, что право на динамическое порождение исполняемого кода предоставляется только коду, который подписан сертификатом производителя ОС. Тогда дотнет и джава смогут выполнять JIT, а какие-нибудь опенсорсные решения — не смогут.
Но выглядит это всё довольно хрупко.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>То есть мат ставится в три хода: S>* Пишем нормальное, добронравное приложение, которое пользуется JIT. Подписываем официальным сертификатом благонадёжного разработчика. В приложении имеется дырка в стиле log4j, которая позволяет исполнять сторонний код (а способов такое сделать — много; тут и плагины, и уязвимости сторонних библиотек) S>*Засовываем через эту дырку сторонний код. Сам по себе этот код написан на IL, который обрабатывается всё ещё православным JIT. S>*Засунутый сторонний код порождает нативный код, который уже не является безопасным, и делает всякие нехорошести с приложением и его окружением.
Хороший вопрос как различать.
Это надо как-то системе сообщать кто может менять страницу и дать права запуска кода.
И чувствуется, что и это можно обойти