LINUX.ORG.RU

Кросс-платформенный исполняемый бинарь

 , ,


0

2

Приветствую

Вот получил задачку набыдлокодить приложение. В требованиях - кроссплатофрменость, а именно: Windows и Linux. И что-бы жизнь медом не казалась добавили: бинарь один, а не ELF отдельно, MZ+PE отдельно.
Вот и думаю чего бы придумать. Точно знаю что Windows ни легально, ни нелегально не заставить запускать не PE-шки(мне не под силу точно). А Linux можно?
Читал о binfmt_misc. Похоже то что нужно.
Только вот встал вопрос: как лучше запаковать ELF в PE? Как, выковыряв ELF из PE, правильно положить в память(и прыгнуть на него) что-бы он(ELF) не понял что его распаковали с конверта. Что-то типа exec памяти.
Ищутся подобные проекты: любые начатые, законченные, брошенные - любые где можно почерпнуть опыт по данному вопросу.

Спасибо.

ЗЫ: к Java, .NET и прочим подобным делам не посылать, допустим исключительно натив.
ЗЗЫ: спасибо анонимусу что напомнил уточнить - Wine посылается по тому же адресу что и Java и .NET. Уродство гуя никого не устроит.

★★★★

Ответ на: комментарий от anonymous

wine /thread

Лучше я на ncurses напишу отдельно - красивше будет, чем если позволить Wine-у пропустить через себя.

FeyFre ★★★★ ()

Предполагаю, что набыдлокодить логику приложения будет проще, чем сделать PE+ELF в одном файле...

proud_anon ★★★★★ ()

Вот получил задачку набыдлокодить приложение. В требованиях - кроссплатофрменость, а именно: Windows и Linux. И что-бы жизнь медом не казалась добавили: бинарь один, а не ELF отдельно, MZ+PE отдельно.

Рекомендую предложить заказчику убиться головой апстену. ЗЫ интересно и чем заказчик мотивировал сии идиотские требования?!

erfea ★★★★★ ()

Мне на много интереснее не то, как ты это делать будешь, а что за клиент, на сколько он серьезен и что за программу тебе писать нужно.

sphericalhorse ★★★★ ()

uberprogram.py

А интерпретаторы уже пусть отдельно ставят. :)

strangeman ★★★★ ()
mv myprogram.py myprogram.exe
chmod +x myprogram.exe
schizoid ★★★ ()

В тегах должно присутствовать [хочется странного], тогда вопрос «Зачем???» не будет так рваться наружу.

По теме. В чистом виде не получится, так как запускаемые файлы Windows и Linux имеют разный формат. Но можно сделать интересный хак.

Во-первых файл должен быть с расширением .exe, чтобы винда его понимала. Далее, в Линуксе используем Kernel support for MISC binaries . Это фича ядра, которая позволяет «запускать» любой файл. То есть я могу в консоли написать ./picture.jpg и у меня запуститься графический просмотрщик и выведет эту картинку. Про это можно почитать, например, здесь: http://lindev.blogspot.com/2009/04/linux-exe.html

А дальше фантазируем.

Например, exe файл может быть самораспаковывающимся архивом rar с двумя файлами - один для винды, второй для никсов. Под виндой архив сам себя распакует и запустит то, что нужно (а потом подчистит), а в Линуксе он будет скормлен скриптику, который посредством rar его распакует (не пробовал, но думаю, что никсовый rar проглотит exe-архив), а потом запустит никсовый ELF.

Второй вариант изящнее. Мы берем exe файл, а вконец его дописываем ELF файл. Тогда наш скриптик просто будет под никсами вырезать последние XXX байт, ложить во временный каталог и запускать оттуда.

По деталям. Kernel support for MISC binaries определяет тип файла по какой-то чсати его содержимого, что есть мы укажем смещение (в байтах) и что там должно находиться. Для первого варианта можно указать MZ вначале файла, но это не интересно, так как тогда это правило будет работать для всех exe-шников. Лучше найти какую-то сигнатуру посредине, чтобы указывало не только на exe-шник, а именно на наш хитрый архив. Для второго варианта можно сделать «прослойку» между первым и вторым файлом, например, написать «This is super-puper universal mega executable file». Но придется делать такие сигнатуры для каждого конкретного файла, ведь они будут разными.

Можно сделать интересней. Виндовый файл имеет секцию для DOS, назовем это заглушкой. Обычно она состоит в том, что выводится что-то типа «Этот файл может быть запущен только в MS Windows». Вот в нее можно поместить какую-то хитрую последовательность, которая потом будет идентифицироват наш хитрый формат. Это делается как-то просто на этапе компиляции виндового файла (когда-то делал в Visual C). Достоинство в том, что теперь для всех таких хитрых файлов оно будет одинаково, то есть одинаково смещение и сама сигнатура. Более того, в эту заглушку можно запаковать размер исходного exe файла файла чтобы наш распаковывающий скриптик знал откуда нужно начинать отрезать ELF файл.

Минусы: оба этих случая предполагают включенную опцию Kernel support for MISC binaries для ядра, соответствующую настройку и скриптик, который будет распаковывать наш архив. А по-другому никак. Но это только для Линукс, в Windows никаких настроек не нужно будет.

Kroz ★★★★★ ()

ну если решать задачу прямо и буквально, нужно запилить в ядро Линукс поддержку формата PE :)

Harald ★★★★★ ()

бинарь один

допустим исключительно натив

Поделил на ноль. А без макоси не интересно.

Без вспомогательных утилит, которые будут резать бинарь, извлекая из него исполняемые файлы для разных ОС, не обойтись.

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

unfo ★★★★★ ()
Ответ на: комментарий от Harald

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

Reset ★★★★★ ()

как лучше запаковать ELF в PE?

На компьютере заказчика антивирус есть?

backbone ★★★★★ ()
Ответ на: комментарий от proud_anon

Предполагаю, что набыдлокодить логику приложения будет проще, чем сделать PE+ELF в одном файле...

Думаю примерно одинаково(просто для логики у меня нету подобной наработки).
Да и после «переспал с идеей» задача PE+ELF кажется не такой уж тяжелой. Например, готовый ELF всунуть в ресурс.

FeyFre ★★★★ ()
Ответ на: комментарий от Kroz

По теме. В чистом виде не получится, так как запускаемые файлы Windows и Linux имеют разный формат. Но можно сделать интересный хак.

Во-первых файл должен быть с расширением .exe, чтобы винда его понимала. Далее, в Линуксе используем Kernel support for MISC binaries .

Спасибо, К.О. А теперь внимательно прочитай заглавное сообщение и скажи какого ты мне объясняешь то, до чего я сам допер.
Что такое MZ-stub, как он работает, для чего он вообще нужен я тоже знаю.
Вариант распаковки в временную папку - не совсем подходящий. Не исключено что софтине(этой либо ещё какой) захочется пошуршать по соседству.

FeyFre ★★★★ ()
Ответ на: комментарий от backbone

На компьютере заказчика антивирус есть?

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

FeyFre ★★★★ ()
Ответ на: комментарий от unfo

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

Да, да. Но вырезать ELF, положить его в отдельный файл и запустить - я уже говорил, может вылезти откуда не ждали. Вот бы пустить бинарь из памяти. Что-то типа exec-fom-memory. Порылся в syscall-ах - подобного вроде-бы не нашел.

FeyFre ★★★★ ()

И что-бы жизнь медом не казалась добавили: бинарь один, а не ELF отдельно, MZ+PE отдельно.

Посылай такого заказчика-идиота

</thread>

derlafff ★★★★★ ()
Ответ на: комментарий от FeyFre

exec-from-memory

Это же просто JMP. Грузишь в свое адресное пространство этот ELF. Но нужно ко всем адресам в нем добавить offset (от начала до места, куда ты его загрузил). Для этого нужен встроенный дизассемблер. Но это уже явно перебор :)

unfo ★★★★★ ()
Ответ на: комментарий от FeyFre

Вариант распаковки в временную папку - не совсем подходящий. Не исключено что софтине(этой либо ещё какой) захочется пошуршать по соседству.

И что? Чем мешает?

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

А если и это не угодило - расковыривай исходники функции exec, благо Линукс - open source.

Ваш К. О.

Kroz ★★★★★ ()
Ответ на: комментарий от unfo

Это же просто JMP. Грузишь в свое адресное пространство этот ELF. Но нужно ко всем адресам в нем добавить offset (от начала до места, куда ты его загрузил). Для этого нужен встроенный дизассемблер. Но это уже явно перебор :)

Вот я и думаю, поможет ли dlopen в таком случае? Ну достану я ELF с конверта, сохраню во временный файл. Потом сделаю на него dlopen. По-идее он должен всё разрулить, вместе с зависимостями. Вопрос в том, можно ли dlopen-у скармливать выполняемые модули? Не полезет ли он искать инициализации и запускать точки инициализации раньше времени(я честно не знаю в чем разница исполняемого и .so, разницу между .EXE и .DLL знаю и знаю что хоть и формат тот же, но наполнение не позволяет ни запустить .DLL ни догрузить .EXE. Подозреваю что у .so подобные ограничения).
И тоже важно, как систему обмануть и подменить argv ? Можно ли? Чревато ли? Ибо не исключено что софтина захочет посмотреть на argv ожидая там увидеть что-то типа {«/usr/local/bin/soft.exe»,«argument»,NULL} а увидит {«/usr/sbin/peloader»,«/usr/local/bin/soft.exe»,«argument»,NULL} - и ей это не понравиться.

FeyFre ★★★★ ()

А если таки сделать этот бинарь скриптом, причем таким, чтобы там была и секция с батником и секция с sh скриптом. А сами скрипты будут распаковывать нужный файл из хвоста скрипта закодированного в base64 в tmp и кидать на него chmod+x и пускать уже. ЗЫ А нельзя ли винде или линуксу прост сказать, что вот в этом массиве байт находится бинарник и попробуй его запустить? ЗЗЫ Я бы послал заказчика в пешее за такие предложения.

Gorthauer ★★★★★ ()

Я не спец, просто предлагаю мысль:
Сделать 2 отдельных бинарника (PE и ELF) и переключатель в виде PE, который или загружается нативно в винде или с помощью wine в linux'е, определяет в какой он ОС, извлекает из себя нужный вариант и выполняет

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

German_B ()
Ответ на: комментарий от FeyFre

На компьютере заказчика антивирус есть?

Это уже будет его проблема.

Странный ты. И заказчик странный. Подавай вам кроссплатформенный бинарь... Антивирус не важен...

sphericalhorse ★★★★ ()

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

Рекомендую инновационную запускалку делать отдельной программой. которая будет запускать уже нормальные для каждой системы бинарники.

kernel ★★☆ ()

Своими глазами видел исполняемый файл, запускаемый как на DOS, так и на Linux. file определяет его, как «ELF 32-bit».

Находится он в http://sourceforge.net/projects/grub4dos/files/GRUB4DOS/grub4dos 0.4.4/grub4d... (файл bootlace.com). Написан на ассемблере. Не факт, что получится сделать так же с Windows.

AITap ★★★★★ ()
Ответ на: комментарий от AITap

Какое интересное явление. Я его не запускал, но похоже, они воспользовались тем, что первые два байта магического числа ELF (7F 45) являются командой jg 47h. Интересно.

proud_anon ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.