Вопрос по executable, memorystream, embedded-resource, unmanaged – Как запустить неуправляемый исполняемый файл из памяти, а не с диска

8

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

Я не могу найти метод для запуска исполняемого файла только из его потока байтов. Windows требует, чтобы это было на диске, или есть способ запустить это из памяти? Если Windows требует, чтобы он был на диске, есть ли в .NET Framework простой способ создать виртуальный диск / файл какого-либо вида и сопоставить файл с исполняемым файлом?поток памяти?

Вы можете использовать утилиту, такую как Imdisk Martin

Ваш Ответ

4   ответа
11

Вы запрашиваете очень низкоуровневую специфичную для платформы функцию, которая будет реализована в управляемой среде высокого уровня. Что-нибудь'возможно ... но никто не сказал, что это будет легко ...

(Кстати, я нене знаю, почему вы думаете, временное управление файлами является обременительным. BCL делает это для вас:http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx)

Выделите достаточно памяти для хранения исполняемого файла. Оно может'Конечно, вы не должны находиться в управляемой куче, поэтому, как и почти все в этом упражнении, вынадо будет пинвоить. (На самом деле я рекомендую C ++ / CLI, чтобы не загонять себятоже псих). Обратите особое внимание на биты атрибутов, которые вы применяете к выделенным страницам памяти: ошибитесь, и вылибо откроет дыру в безопасности, либо ваш процесс будет остановлен DEP (т. е. выпрорвусь). Увидетьhttp://msdn.microsoft.com/en-us/library/aa366553(VS.85).aspx

Найдите исполняемый файл в вашей сборкес библиотекой ресурсов и приобрелзакрепленная ручка к этому.

Memcpy () код из закрепленной области управляемой кучи в собственный блок.

Освободите GCHandle.

ВызовVirtualProtect чтобы предотвратить дальнейшую запись в исполняемый блок памяти.

Рассчитать адрес исполняемого файлаs Основная функция в вашем процессе виртуальное адресное пространство, основанное на дескрипторе, полученном из VirtualAlloc, и смещении в файле, как показано DUMPBIN или аналогичными инструментами.

Поместите нужные аргументы командной строки в стек. (Соглашение Windows Stdcall). Конечно, любые указатели должны указывать на родные или закрепленные регионы.

Перейти к рассчитанному адресу. Вероятно, проще всего использовать _call (встроенный язык ассемблера).

Молись Богу, чтобы исполняемый образ нене может быть никаких абсолютных скачков,Я был исправлен путем вызова LoadLibrary обычным способом. (Если, конечно, вы не захотите повторно реализовать мозг LoadLibrary во время шага № 3).

Получить возвращаемое значение из регистра @eax.

Позвоните в VirtualFree.

Шаги № 5 и № 11 должны быть выполнены в блоке finally и / или использовать шаблон IDisposable.

Другой основной вариант - создать RAM-диск, записать в него исполняемый файл, запустить его и очистить. Это может быть немного безопаснее, так как ты непытаться написать самоизменяющийся код (что сложно в любом случае, но особенно когда код недаже твой). Но я'Я вполне уверен, что для этого потребуется еще больше вызовов API платформы, чем для динамического внедрения кода - все они, естественно, требуют C ++ или PInvoke.

Я понимаю чтоучаствует в загрузке EXEсмешно, что нетФункция наподобие CreateProcessWithLogonW, которая принимает адрес памяти в качестве указателя вместо имени файла и получает его оттуда. Вы'Я все еще буду указывать рабочий каталог и другие параметры, но почему он так хладнокровен, зависит от того, поддерживается ли он диском, когда он 'В любом случае, он просто собирается отобразить это в памяти? Triynko
Я просто неЯ думаю, что разрешения на доступ к файлам вообще не должны входить в микс, и, к сожалению, с временными файлами они это делают. См. Комментарий к MSDN для Path.GetTempFilename: в средах с низким уровнем прав, например в некоторых конфигурациях ASP.NET эта функция завершится с ошибкой безопасности ... потому что ей нужно найти временный каталог и это 'с чтениемСреда"... для неограниченного доступа к переменным среды требуется EnvironmentPermission. Связанное перечисление: PermissionState.Unrestricted Triynko
Оглядываясь назад на все эти шаги и молитвы, я надеюсь, что этоочевидно почемукод должен быть на диске " Правило так обременительно. Поскольку исполняемый код в конечном итоге загружается в память, я должен иметь возможность запускать его непосредственно из памяти или загружать с диска в память, а затем запускать его. Текущий .NET API потребовал бы, чтобы я взял код в памяти, записал его на диск, работал с системой временного управления файлами, только чтобы прочитать его обратно в память, где он уже был на первом месте! Это просто демонстрация того, что происходит, когда вы оборачиваете старую технологию в новую одежду и даете ей новое имя. Triynko
Нет. Вызов Process.Start очень сильно отличается от простого задания CS: IP случайного смещения в области исполняемой памяти и перехода туда. ОСОБЕННО из управляемого кода. Даже в родных приложениях Win32 загрузка произвольных модулей .exe / .dll занимает гораздо больше, чем вы думаете. То, что вы видите в моем ответе выше, не должно быть обременительным; Это'на самом деле драматическое чрезмерное упрощение. Вот's статья, которая [начинает] царапать поверхность всего, что обрабатывает LoadLibrary для вас:msdn.microsoft.com/en-us/magazine/cc301727.aspx Richard Berg
2

Посмотрите на "В памяти" раздел этой статьи. Пойми, что этос точки зрения удаленного внедрения DLL, но концепция должна быть такой же.

Инъекция удаленной библиотеки

Интересно, но яЯ ищу способ использовать что-то вроде Process.Start, передавая байтовый массив, а не имя файла. Я нене нравится их оправдание не запускать процессы из памяти какантивирусный сканерможетсканировать программы, которые никогда не существуют на диске "... что за полицейский. Если они'Для начала, я собираю операционную систему для безопасного запуска программ:должен происходить на диске " Правило было бы ненужным. Triynko
.NET Framework применяет подразумеваемое правило, которое "исполняемый код должен происходить на диске " предоставляя перегрузки Process.Start, которые в конечном итоге будут принимать только имя файла в качестве указателя на исполняемый код. Он не будет принимать ни управляемый массив байтов, ни указатель на неуправляемые байты, которые содержат исполняемый код. Triynko
Каждая другая основная ОС также основывает свою модель безопасности на учетных записях пользователей. И для этого есть очень веские причины. В комментариях недостаточно места, чтобы перечислить все причины, по которым выя не правПозвольте Раймонду поговорить:blogs.msdn.com/oldnewthing/archive/2006/08/18/705957.aspx Richard Berg
И этоПочему каждая крупная ОС страдает от вирусов и предупреждений безопасности. Я прочитал этот блог, и он неЯ не могу опровергнуть мою точку зрения. Фактически, один из комментариев там говорит то же самое, что я сказал: «Проблема заключается в том, что модели безопасности Windows и UNIX задом наперед. Операционные системы идут на многое, чтобы защитить себя от меня, но ничего не делают для защиты моих данных от программ, которые я запускаю. Реорганизация Windows с использованием модели безопасности возможностей была бы неосуществимой, но .Net - отличный шаг в правильном направлении ». Triynko
1

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

Это должен быть исполняемый файл? Если вы упакуете его как сборку, вы можете использовать Assembly.Load () из потока памяти - пару тривиальных строк кода.

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

Даже не "потому что вы могли бы сделать это 2 месяца назад и перейти к другой проблеме "? Или же "потому что это'Это стандартный подход, и он будет работать только для любого исполняемого файла (управляемого или неуправляемого и т. д.), потому что он 'специально поддерживается .net "? Jason Williams
Нет, потому что это включает в себя запись на диск, а это именно то, что яЯ избегаю В системе без записываемых дисков, RAM-диск является единственным вариантом, и, называя это чрезвычайно сложным, вы 'Мы только что подтвердили мое утверждение о том, что требование выполнения исполняемого кода на диске является обременительным и бессмысленным требованием, но, к сожалению, это 'Все операционные системы и их древние библиотеки были написаны для обработки. Triynko
Я с тобой согласен. Я просто думаю, что тыТрудно будет найти что-нибудь столь же простое в реализации и тестировании, как и написание временного файла. Jason Williams
Я согласен тамНет ничего проще, этотолько то, что яя пытаюсь избежать, потому что я неЯ не хочу писать на диск по любой причине. Triynko
-1

Это явно запрещено в Vista +. Вы можете использовать недокументированные вызовы Win32 API в XP, чтобы сделать это, но в Vista + это было сломано, потому что это была огромная дыра в безопасности, и единственными, кто использовал ее, были авторы вредоносных программ.

РЕГ ДОБАВИТЬ "HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Параметры выполнения файла образа \ sethc.exe " / v Отладчик / t REG_SZ / d "C: \ WINDOWS \ system32 \ cmd.exe»  Ущерб, который можно нанести этим (например, стереть файловую систему), учитывая, как часто люди случайно активируют липкие ключи, смеется. Triynko
Проверьте подпись, читая байты из блока памяти вместо блоков диска! Там не должноне будет разницы; Это'плохой дизайн. Драйверы фильтров не имеют значения, так как мыговорим о коде, которыйон уже выполняется, запрашивая запуск какого-то другого конкретного кода, и никакие фильтры не должны мешать этому коду. Если вам действительно нужны фильтры, ОС может предоставить низкоуровневые перехватчики, позволяющие фильтрам сканировать память непосредственно перед этим »s защищены и исполнение начинается. ОпятьНичего особенного в том, что данные находятся на диске,Все это плохая архитектура. Triynko
IFEO - это эксплойт, ожидающий своего появления, и не более чем ленивое удобство для запуска процессов с определенной конфигурацией. Это'небрежный дизайн. Я вижу, что в реестре есть записи типа "HKLM \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Параметры выполнения файла изображения \ SearchIndexer.exe ", Так что теперь, если я запускаю файл с именем SearchIndexer.exe,Будет ли это скрытое, спровоцированное системой, особое поведение, которое происходит без ведома пользователя? Это'Подвиг, ожидающий случиться, ИМО. Отладка, опять же, в аналогичной лодке. Triynko
Ну это таксмешно. Поток байтов - это поток байтов, независимо от того, как вы на него смотрите или откуда он исходит. Принудительное выполнение этих байтов из FILE, а не из MEMORY, бесполезно. Malware? Шутки в сторону? Дайте мне перерыв ... поэтому им просто нужно сначала записать его в файл, чтобы запустить его. Вы говорите, что в API была дыра в безопасности (хорошо, я полагаю), или вы там говорите:s дыра в безопасности в идее запуска кода из потока байтов памяти, а не из потока байтов файла (определенно НЕТ). Triynko

Похожие вопросы