Почему символ _size связанного двоичного файла не работает правильно? - PullRequest
0 голосов
/ 23 февраля 2019

Я использую 'ld -r -b binary -o binary.o foo.jpeg' для встраивания ресурсов в мою программу.Работает потрясающе.Мне просто интересно, почему символ int _binary_size никогда не читает правильно, отрицательное или слишком большое число, но остается неизменным между запусками программы.Я всегда должен делать _binary_end - _binary_start, который работает безупречно.Кажется, это ни для кого не работает ... как здесь .... почему это так?

Нет причин не использовать end-start, поскольку он заменяет символ размера, ноэто все еще оставляет меня любопытным.

edit: пример кода.

extern const unsigned char _binary_scna4_jpg_start;
extern const unsigned char _binary_scna4_jpg_end;
extern const int _binary_scna4_jpg_size;

int size = &_binary_scna4_jpg_end - &_binary_scna4_jpg_start;
printf("Size is %d vs %d \n", size, _binary_scna4_jpg_size);

это печатает:

Size is 1192071 vs -385906356 

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

Вывод нм для хорошей меры:

0000000000123087 D _binary_scna4_jpg_end
0000000000123087 A _binary_scna4_jpg_size
0000000000000000 D _binary_scna4_jpg_start

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Ваш символ _binary_scna4_jpg_size не является целым числом.Это абсолютный адрес символ.Чтобы получить размер, вам нужно взять адрес и привести его к соответствующему целочисленному типу:

printf("The real size is %td\n", (ptrdiff_t) &_binary_scna4_jpg_size);

Однако это работает только при отключении PIE (gcc -fPIC-no-pie) или статическое связывание (gcc -static).

0 голосов
/ 23 февраля 2019

Проблема возникает из-за Независимых от позиции исполняемых файлов (PIE).Ранее исполняемые файлы загружались по тем же адресам памяти (которые были определены во время компиляции / компоновки), что приводило к возможным атакам, потому что злоумышленник знал, по какому адресу были определенные части программ.Поэтому Рандомизация макета адресного пространства была реализована.Это имеет побочный эффект: символы размера, определяемые как абсолютные адреса (_binary_scna4_jpg_size это , а не целочисленное значение, это «указатель», как _start и _end), также перемещаются при их загрузке.

Если вы компилируете свой код с опцией -no-pie, вы можете отключить независимость от позиции, и _binary_scna4_jpg_size выведет правильное значение, поскольку оно не будет перемещено.Поскольку в настоящее время PIE включен по умолчанию, значение указателя в основном является мусором.Вы также можете использовать его, если знаете начало перемещенной памяти, но поскольку у вас уже есть _binary_scna4_jpg_start и _binary_scna4_jpg_end, использовать их тоже самое.

...