2010-01-17 5 views
14

Я хотел бы симулировать файл, не записывая его на диск. У меня есть файл в конце моего исполняемого файла, и я хотел бы указать его путь к dll. Конечно, поскольку у него нет реального пути, я должен подделать его.Как создать виртуальный файл?

Сначала я попытался использовать именованные каналы под Windows, чтобы сделать это. Это позволит использовать такой путь, как \\. \ Pipe \ mymemoryfile, но я не могу заставить его работать, и я не уверен, что dll будет поддерживать такой путь.

Во-вторых, я нашел CreateFileMapping и GetMappedFileName. Могут ли они использоваться для имитации файла в фрагменте другого? Я не уверен, что это то, что делает этот API.

То, что я пытаюсь сделать, похоже на boxedapp. Любые идеи о том, как они это делают? Я предполагаю, что это что-то вроде перехвата API (вроде Detour), но это будет очень много. Есть ли другой способ сделать это?

Почему? Я заинтересован в этом конкретном решении, потому что я хотел бы скрыть данные и в интересах распространения только одного файла, но также и для вызывающих причин для его работы таким образом;) Согласен, что копирование данных во временный файл работать и быть намного проще.

ответ

4

Данные можно хранить в потоке NTFS. Таким образом, вы можете получить реальный путь, указывающий на ваши данные, которые вы можете дать вашему DLL в виде

x:\myfile.exe:mystreamname 

Это работает точно как обычный файл, однако он работает только если файловая система используется NTFS. В настоящее время это стандартно для Windows, но, конечно, это не вариант, если вы хотите поддерживать старые системы или хотите, чтобы это можно было запустить с USB-накопителя или аналогичного. Обратите внимание, что любые потоки, присутствующие в файле, будут потеряны, если файл будет отправлен в виде вложения в почте или просто скопирован из раздела NTFS в раздел FAT32.

Я бы сказал, что наиболее совместимым способом было бы записать ваши данные в фактический файл, но вы, конечно, можете сделать это одним из способов в системах NTFS, а другой - в FAT-системах. Я рекомендую против этого из-за дополнительной сложности. Соответствующим способом было бы распределить ваши файлы отдельно, но, поскольку вы указали, что не хотите этого, вы должны в этом случае записать его во временный файл и предоставить DLL путь к этому файлу. Убедитесь, что вы записываете временный файл в каталог временных файлов пользователей (вы можете найти путь, используя GetTempPath в C/C++).

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

Кроме того, если вы хотите использовать только один файл для распространения, как использовать zip-файл или установщик?

+0

И как именно вы распространяете файл? Я бы сказал, что zipping или копирование exe приведет к исчезновению потока NTFS? –

+0

@ Григорий: Да. Вариант использования на самом деле не совсем ясен в вопросе, но я согласен с тем, что использование потоков может быть очень хорошим вариантом для OP - мы надеемся, это также четко указано в моем ответе. Главное, что я пытаюсь забить домой в ответ, заключается в том, что использование фактического файла - лучший вариант. – villintehaspam

+0

Это очень интересная идея. Жаль, что он работает только на ntfs. Поскольку нет идеального ответа, этот лучший. –

4

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

Если вы после файлового поведения, лучшим вариантом будет всегда использовать файл. В Windows вы можете передать FILE_ATTRIBUTE_TEMPORARY в CreateFile в качестве подсказки системе, чтобы избежать промывки данных на диск, если имеется достаточная память.

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

Если вы пытаетесь избежать записи на диск по какой-то другой причине, можете ли вы объяснить, почему? В общем, довольно сложно остановить данные из когда-либо попавших на диск - пользователь может, например, всегда спячки на машине.

+0

Файлы будут вставляться непосредственно в .exe, но dll принимает только путь в качестве входа (он не может загрузить из istream или что-то вроде этого) –

3

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

Простейшим решением является создание временного файла в каталоге temp, запись данных из EXE в временный файл, а затем удаление временного файла.

Есть ли причина, по которой вы вставляете этот «псевдофайл» в конец вашего EXE, а не просто распространяете его с помощью нашего приложения? Вы, очевидно, уже распространяете эту стороннюю DLL с вашим приложением, чтобы еще один файл не казался вам больным?

Другой вопрос: будут ли эти данные изменяться? То есть вы ожидаете записать данные «псевдофайла» в своем EXE? Я не думаю, что это будет хорошо работать. У стандартных пользователей может не быть доступа на запись к EXE, и это, вероятно, будет управлять антивирусными орехами.

И никакие CreateFileMapping и GetMappedFileName определенно не будут работать, поскольку они не дают вам имя файла, которое может быть передано CreateFile. Если бы вы могли каким-то образом получить эту DLL, чтобы принять HANDLE, тогда это сработает.

И я бы даже не потрудился с перехватом API. Просто передайте DLL путь к acutal файлу.

1

Чтение вашего вопроса заставило меня подумать: если вы можете притвориться, что область памяти является файлом и имеет для нее «виртуальный путь», то это позволит загружать DLL непосредственно из памяти, что запрещает по дизайну запросив имя пути. И вот почему люди пишут свой собственный загрузчик PE, когда хотят этого достичь.

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

Использование Detours подразумевает, что вам нужно будет реплицировать все, что перехватила функция DLL, кроме как получить данные из реального файла; следовательно, он не является общим. Или, еще более запутанно, давайте притвориться, что DLL использует fopen; то вы предоставляете свой собственный fopen, который обнаруживает специальный шаблон на пути, и вы мнимаете внутренние среды C ... Хм, действительно ли это стоит всей боли? : D

+0

, так как c runtime - это фасад для w32-функций, я бы Не нужно переопределять каждую функцию, использующую файл, но низкий уровень. –

0

Как насчет использования какого-то RamDisk и записи файла на этот диск? Я сам пробовал какие-то ramdisks, хотя и не нашел хорошего, скажите мне, успешны ли вы.

0

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

Это единственное решение, о котором я могу думать без ввода/вывода на диск (даже если вы не пишете в файл).

Если вам нужно сохранить файл как синтаксис пути, просто напишите класс, который имитирует это поведение, и вместо записи в файл запишитесь в буфер памяти. Это так же просто, как и получается. Помните KISS.

Приветствия

0

Пожалуйста, объясните, почему вы не можете извлечь данные из EXE и записывает его во временный файл. Многие приложения делают это - это классическое решение этой проблемы.

Если вы действительно должны предоставить «виртуальный файл», самым чистым решением, вероятно, является драйвер фильтра файловой системы. «clean» не означает «хороший» - фильтр является полностью документированным и поддерживаемым решением, поэтому он чище, чем API-соединение, инъекция и т. д. Однако фильтры файловой системы непросты.

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

0

Откройте файл с именем «NUL:» для записи. Он доступен для записи, но данные молча отбрасываются. Kinda нравится/dev/null of * nix fame.

Вы не можете его отобразить на карте. Memory-mapping подразумевает доступ для чтения/записи, а NUL - только для записи.

0

Я предполагаю, что эта dll не может взять поток? Его почти просто спросить, НО, возможно, вы могли бы просто использовать это.

+0

Это DLL, которой я не являюсь, и у меня нет исходного кода для нее, она имеет только loadfile api с контуром. Поэтому я не могу это изменить. –

0

Вы пытались использовать префикс \? \ При использовании именованных каналов? Многие API поддерживают с помощью \? \, Чтобы передать оставшуюся часть пути напрямую без каких-либо синтаксических разборов/модификаций.

http://msdn.microsoft.com/en-us/library/aa365247(VS.85,lightweight).aspx

3

Используйте BoxedApp и не волнуйтесь.

+2

Прохладный приложение! Он даже работает с виртуальным реестром! –

Смежные вопросы