Одинаковый двоичный код в Windows и Linux (x86) - PullRequest
2 голосов
/ 18 ноября 2010

Я хочу скомпилировать кучу файлов C ++ в необработанный машинный код и запустить его с зависимым от платформы стартером, написанным на C.(*) (int)) буфер) (b);)

Как мне сказать g ++ для вывода необработанного кода?

Будут ли работать вызовы функций?Как я могу заставить это работать?

Я думаю, что соглашения о вызовах Linux и Windows отличаются.Это проблема?Как я могу решить это?

РЕДАКТИРОВАТЬ: Я знаю, что PE и ELF предотвращают ПРЯМОЙ запуск исполняемого файла.Но для этого у меня есть стартер.

Ответы [ 6 ]

6 голосов
/ 18 ноября 2010

Существует один (относительно) простой способ достижения этого, который называется «код, независимый от позиции».См. Документацию к вашему компилятору.

Это означает, что вы можете скомпилировать некоторые источники в двоичный файл, который будет выполняться независимо от того, где в адресном пространстве вы его разместите.Если у вас есть такой кусок двоичного кода x86 в файле и mmap (), то он (или эквивалент Windows) может быть вызван как из Linux, так и из Windows.

Уже упомянутые ограничения, конечно, все еще присутствуют- а именно, двоичный код должен ограничиваться использованием соглашения о вызовах, идентичного на обеих платформах / может быть представлено на обеих платформах (для 32-битной x86, которая будет передавать аргументы в стеке и возвращать значения в EAX), и, конечно,код должен быть полностью самодостаточным - никакие вызовы функций DLL не разрешаются, поскольку их решение зависит от системы.

Т.е.:

  1. Вам необходим независимый от позиции код
  2. Вы должны создать автономный код без каких-либо внешних зависимостей
  3. Вы должны извлечь машинный код из объектного файла.

Затем mmap () этот файл инициализироватьуказатель на функцию, и (* myblob) (someArgs) могут это сделать.

Если вы используете gcc, опции "-ffreestanding -nostdinc -fPIC" sдолжен дать вам большую часть того, что вы хотите в отношении первых двух, а затем использовать objdump для извлечения двоичного двоичного объекта из объектного файла ELF.

2 голосов
/ 18 ноября 2010

Теоретически, часть этого достижима.Однако на этом пути так много ошибок, что на самом деле это ни для чего не практичное решение.

  • Форматы системных вызовов абсолютно несовместимы
  • DEP не позволит выполнять данные в виде кода
  • Схемы памяти различаются
  • Вам необходимо эффективно динамически «перекомпоновать» код, прежде чем вы сможете его запустить.
  • .. и т. Д. *
1 голос
/ 18 ноября 2010

Почему бы тебе не взглянуть на вино? Это для использования исполняемых файлов Windows в Linux. Другое решение для этого - использование байт-кода Java или .NET.

Вы можете запускать исполняемые файлы .NET в Linux (требуется моно время выполнения)

Также взгляните на objconv Агнера (разборка, преобразование исполняемого файла PE в ELF и т. Д.) http://www.agner.org/optimize/#objconv

1 голос
/ 18 ноября 2010

Один и тот же исполняемый файл не может быть запущен как в Windows, так и в Linux.

Вы пишете свою кодовую платформу независимо (STL, Boost & Qt может помочь с этим), затем компилируете в G ++ в Linux для выводадвоичный файл и аналогично компилятору на платформе Windows.

РЕДАКТИРОВАТЬ: Кроме того, возможно, эти два сообщения могут помочь вам:

One

Два

0 голосов
/ 18 ноября 2010

Это достижимо, только если в вашей системе Linux доступно WINE .В противном случае разница в формате исполняемого файла не позволит запустить код Windows в Linux.

0 голосов
/ 18 ноября 2010

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

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

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

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

Гораздо лучше было бы перекомпилировать на каждой платформе.

...