Как сделать файл без формата, содержащий скомпилированный код на C?

Здравствуйте! Мне необходимо создать файл с скомпилированным 32-битным кодом на C, без использования формата и без позиционной независимости (PIE), смещенный на 0x100200. Работаю в операционной системе macOS.
  • 7 января 2025 г. 20:04
Ответы на вопрос 2
Создание бинарного файла с скомпилированным кодом на C без формата и с заданным смещением — это сложная задача, особенно в macOS, где компиляция и линковка осуществляются с помощью инструментов, которые в основном создают файлы в формате Mach-O. Тем не менее, есть способ, как это можно сделать, используя компилятор `gcc` и несколько дополнительных шагов.

### Шаги для создания файла без формата:

1. **Напишите код на C**. Например, создайте файл `hello.c`:

   ```c
   #include <stdio.h>

   void _start() {
       const char *msg = "Hello, World!\n";
       asm("movl $1, %eax\n"    // sys_write
           "movl $1, %ebx\n"    // file descriptor (stdout)
           "movl %0, %%ecx\n"   // pointer to message
           "movl $14, %%edx\n"  // message length
           "int $0x80\n"
           "movl $1, %%eax\n"    // sys_exit
           "xor %%ebx, %%ebx\n"  // exit code 0
           "int $0x80\n"
           :
           : "r" (msg)
           : "%eax", "%ebx", "%ecx", "%edx");
   }
   ```

2. **Скомпилируйте код** без формата и позиционной независимости. Используем `gcc` и `objcopy` для создания "сырого" бинарного файла:

   ```bash
   gcc -c -m32 -o hello.o hello.c
   ```

3. **Создайте raw бинарный файл** из объектного файла:

   ```bash
   objcopy -O binary hello.o hello.bin
   ```

4. **Сместите файл на 0x100200**. Для этого вам нужно создать файл с нужным количеством нулевых байтов и скопировать ваш бинарный файл в нужное место, используя `dd` или `cat`.

   ```bash
   printf '\0' | dd if=/dev/zero bs=1 count=0x100200 of=final.bin
   cat hello.bin >> final.bin
   ```

### Обратите внимание:

- Убедитесь, что ваша система поддерживает 32-битное приложение. На более современных версиях macOS может потребоваться дополнительная настройка.
- Данный код использует прямые системные вызовы через интеррупцию `int $0x80`, что является специфичным для некоторых архитектур и версий ОС.
- Этот метод выполняется в условиях, когда необходимо получение "сырого" бинарного кода и может потребовать отладки или адаптации в зависимости от вашей реальной среды выполнения.

### Возможные проблемы:

- На macOS могут быть ограничения на выполнение "сырого" кода, так как этот код обычно используется в системах, которые поддерживают доступ к системным вызовам низкого уровня.
- Убедитесь, что ваш код соответствует требованиям безопасности, если вы планируете его запускать в окружении, где включены механизмы безопасности (например, SIP - System Integrity Protection).

Эти шаги должны помочь вам создать файл, содержащий скомпилированный код на C, без формата и с указанным смещением.
Возможно, вам поможет кусок из моей статьи , к которому я сам часто возвращаюсь. Правда, там ARM, но gcc везде +/- одинаковый 

arm-none-eabi-gcc.exe echo.c -nostdlib -O2 -o echo.out
arm-none-eabi-objcopy.exe -O binary echo.out echo.bin


По-хорошему нужно явно указать компилятору, по какому адресу будет расположен код директивой -Wl,--section-start=.text=0x30400000 (последнее - требуемый адрес)
Похожие вопросы