Вопрос

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

Я хотел бы убрать требование о том, чтобы система была настроена описанным выше образом.

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

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

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

Библиотека разрабатывается на C / C ++ для кроссплатформенного использования в Windows и Linux.

Это было полезно?

Решение

Вы можете использовать xxd чтобы преобразовать двоичный файл в файл заголовка C.

$ echo -en "\001\002\005" > x.binary

$ xxd -i x.binary 
unsigned char x_binary[] = {
  0x01, 0x02, 0x05
};
unsigned int x_binary_len = 3;

xxd является довольно стандартным в системах * nix, и он доступен в Windows с Cygwin или MinGW, или Vim также включает его в стандартный установщик.Это чрезвычайно кроссплатформенный способ включения двоичных данных в скомпилированный код.

Другой подход заключается в использовании objcopy чтобы добавить данные в конец исполняемого файла - IIRC вы может получить objcopy и используйте его для PEs в Windows.

Один из подходов, который мне нравится немного больше, чем этот, заключается в простом добавлении необработанных данных прямо в конец вашего исполняемого файла.В исполняемом файле вы обращаетесь к концу файла и считываете число, указывающее размер вложенных двоичных данных.Затем вы выполняете поиск в обратном направлении на такое количество байтов, и fread эти данные и скопируйте их в файловую систему, где вы могли бы обрабатывать их как исполняемый файл.Это случайно способ создания многих, если не всех, самораспаковывающихся исполняемых файлов.

Если вы добавляете двоичные данные, это работает как с файлами Windows PE, так и с файлами * nix ELF - ни один из них не читается сверх "предела" исполняемого файла.

Конечно, если вам нужно добавить несколько файлов, вы можете либо добавить tar / zip-файл к вашему exe-файлу, либо вам понадобится немного более продвинутая структура данных, чтобы прочитать то, что было добавлено.

Вы также, вероятно, захотите UPX ваши исполняемые файлы перед тем, как вы их добавите.

Вас также может заинтересовать Библиотека LZO, которая, как сообщается, является одной из библиотек сжатия с самой быстрой распаковкой.У них есть библиотека MiniLZO, которую вы можете использовать для очень легкого декомпрессора.Однако библиотеки LZO лицензированы по GPL, так что мог бы это означает, что вы не можете включить это в свой исходный код, если ваш код также не является GPLed.С другой стороны, существуют доступные коммерческие лицензии.

Другие советы

"Умный человек решает проблему. Мудрый человек избегает этого". — Альберт Эйнштейн

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

Только мои 2 цента.

Подход, немного отличающийся от использования массива без знака char *, заключается в том, чтобы поместить весь исполняемый двоичный файл в качестве ресурса библиотеки dll.Во время выполнения вы можете сохранить двоичные данные в виде локального временного файла и запустить приложение.Однако я не уверен, есть ли способ выполнить исполняемый файл в памяти.

Для правильной работы библиотеки вспомогательное приложение должно находиться в правильном Расположение

В Windows это будет каталог Program Files или System32?

Это может быть проблемой.Когда приложение устанавливается, особенно в корпоративной среде, это обычно происходит в контексте с правами администратора.В Vista и более поздних версиях с включенным UAC (по умолчанию) это необходимо для записи в определенные каталоги.И большинство версий Unix имели разумные ограничения, подобные этому, с тех пор, как кто-либо себя помнит.

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

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

Сказав все это, вы говорите, что рассматриваете возможность распаковки помощников во временный каталог, так что, возможно, это все спорно.

У Qt есть отличный метод достижения этой цели: Qресурс

"Система ресурсов Qt - это независимый от платформы механизм для хранения двоичных файлов в исполняемом файле приложения".

Вы не говорите, используете ли вы в данный момент Qt, но вы говорите "C ++ для кроссплатформенного использования в Windows и Linux", так что даже если вы его не используете, вы можете рассмотреть возможность запуска.

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

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

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

Но что касается самого вопроса...Если ваша "библиотека" на самом деле объединена в виде dll (или даже exe), то, по крайней мере, Windows имеет относительно простую поддержку для встраивания файлов в вашу библиотеку.

Механизм ресурсов, который позволяет встраивать в исполняемые файлы такие вещи, как информация о версии и значки, также может разрешать использование произвольных фрагментов данных.Поскольку я не знаю, какую среду разработки вы используете, я не могу точно сказать, как это сделать.Но, грубо говоря, вам нужно было бы создать пользовательский ресурс с типом "FILE" или что-то разумное в этом роде и указать его на exe, который вы хотите внедрить.

Затем, когда вы захотите извлечь его, вы бы написали что-то вроде

HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_MY_EMBEDDED_FILE), "FILE");
HGLOBAL hResourceData = LoadResource(NULL, hResource);
LPVOID pData = LockResource(hResourceData);
HANDLE hFile = CreateFile("DestinationPath\\Helper.exe", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwBytesWritten = 0;
WriteFile(hFile, pData, SizeofResource(NULL, hResource), &dwBytesWritten, NULL);
CloseHandle(hFile);

(конечно, укажите свой собственный желаемый путь, имя файла и любую соответствующую проверку ошибок)

После этого вспомогательный exe-файл существует как обычный exe-файл, и поэтому вы можете выполнить его любым обычным способом.

Для удаления файла после использования вам следует изучить флаги для CreateFile, в частности FILE_FLAG_DELETE_ON_CLOSE.Вы также могли бы рассмотреть возможность использования MoveFileEx при объединении MOVEFILE_DELAY_UNTIL_REBOOT флаг с нулевым значением, передаваемый для нового имени файла.И, конечно, вы всегда можете удалить его в своем собственном коде, если вы можете определить, когда исполняемый файл закончился.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top