Страницы

Поиск по вопросам

среда, 10 октября 2018 г.

Как в Linux запускать программу с одними и теми же виртуальными адресами?

Допустим, есть некий ./a.out (получен из Си), который выводит адрес, возвращаемый первым же malloc (естественно, на пути к нему всегда выполняются одни и те же действия).
При каждом запуске мы видим разные числа - это особенность Linux (м.б. и в других системах тоже реализовано) запускать программу так, чтобы стек, куча и область для mapping-а файлов размещались по случайным адресам).
А вот если смотреть в gdb или запустить этот ./a.out в valgrind, то увидим один и тот же адрес.
Вопрос, как запускать (без apt-get install valgrind) ./a.out, чтобы печатаемый адрес всегда был тем же самым?


Ответ

Как верно замечено в комментариях, то, с чем вы столкнулись, называется ASLR - рандомизация адресного пространства. Технология поддерживается во всех современных ОС.
Но, помимо поддержки в ОС, бинарники так же должны быть скомпилированы специальным образом. К примеру, у GCC есть опции для компиляции с поддержкой ASLR: -fPIC/-fpic и -fPIE/-fpie
В Linux, поддержу ASLR на уровне ОС можно отключить руками
sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'
и включить назад:
sudo bash -c 'echo 2 > /proc/sys/kernel/randomize_va_space'
И наконец, в Linux есть утилита hardening-check, которая определяет, скомпилирован бинарник с поддержкой рандомизации или нет.
UPD:
Оказывается, есть целых 5 типов рандомизаций:
Stack ASLR Libs/mmap ASLR Exec ASLR - вот этот тип задаётся флагами fPIE при компиляции brk ASLR VDSO ASLR
И в доках пишут, что для рандомизации malloc-ов используется brk ASLR
Т.е. получается, что для каких-то рандомизаций нужно указывать специальные флаги при компиляции программы, а какие-то работают по-умолчанию "из коробки". Так что, чтобы полностью исключить всякие рандомизации, нужно отключать ASLR на уровне ОС / в рамках сессии (setarch $(uname -m) -RL bash).

Комментариев нет:

Отправить комментарий