Как правильно вывести функцию в формате байтов?

Я хотел бы реализовать следующий код: <br/> <br/> <pre><code class="cpp">#include &lt;stdio.h&gt;
#include &lt;stdint.h&gt;

typedef unsigned char uchar;

int f(int a, int b) {
    return a + b;
}
void _end(void) {};

int main(void) {
    uchar* start = f, *end = _end;
    int size = (int)(end - start);
    printf("size = %i\n", size);
    for (int i = 0; i &lt; size; ++i) {
        printf("%02X ", *(start + i));
    }

    return 0;
}</code></pre> <br/> <br/> Однако, программа либо не выводит ничего (size < 0), либо отображает байты, не относящиеся к функции. <br/> <br/> Мне нужно сделать так, чтобы это работало на ЛЮБОМ компиляторе. Как можно это реализовать?
  • 9 января 2025 г. 14:04
Ответы на вопрос 3
Выводить машинный код функции в формате байтов может быть проблематично, так как некоторые компиляторы могут оптимизировать код, в результате чего некоторые функции могут быть полностью удалены, изменены или объединены с другими. Однако, если вы хотите вывести байты функции, вам стоит сделать несколько изменений и учитывать некоторые аспекты. 

Вот один из способов, как это можно попробовать реализовать с использованием функции в C:

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

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

Вот пример программы, которая может помочь вам получить байты функции:

```cpp
#include <stdio.h>
#include <stdint.h>

typedef unsigned char uchar;

// Пример функции
int f(int a, int b) {
    return a + b;
}

// Разделитель для обозначения конца функции
void _end(void) {}

// Определите границы для вывода функции
extern "C" void print_function_bytes() {
    uchar* start = (uchar*)f; // Адрес начала функции
    uchar* end = (uchar*)_end; // Адрес конца функции
    size_t size = (size_t)(end - start); // Размер функции в байтах

    printf("size = %zu\n", size);
    
    for (size_t i = 0; i < size; ++i) {
        printf("%02X ", *(start + i));
    }
    printf("\n");
}

int main(void) {
    print_function_bytes(); // Вызываем функцию, которая выводит байты
    return 0;
}
```

### Замечания:
1. **Непредсказуемый размер**: Заметьте, что размер вашей функции может варьироваться в зависимости от компилятора и используемых оптимизаций. Оптимизации могут привести к тому, что содержимое функции окажется изменённым или несуществующим.

2. **Проблемы с безопасностью**: Вывод байтов кода может представлять собой риск безопасности, особенно если вы работаете с современными операционными системами, которые имеют множество механизмов защиты, таких как ASLR (Address Space Layout Randomization).

3. **Платформонезависимость**: Код выше может не работать на всех платформах. Например, Windows может требовать специфических для системы API вызовов для извлечения байтового кода.

Такая реализация, как правило, не является стандартной практикой и может дать вам неполные или неожиданные результаты в зависимости от используемого компилятора и настроек компиляции.
Переписать всё на ассемблер. 
Компилятор C/C++ может использовать оптимизацию, менять порядок функций, делать функции инлайновыми.
Ну почему же ничего не выдает, size < 0 означает, что функция _end расположена перед функцией f, и это нормально, потому что часто компилятор соблюдает алфавитный порядок. 
Назовите их func_a и func_b и попробуйте ещё раз. Обязательно используйте в коде эти функции, чтобы они не оказались вырезанными
Похожие вопросы