Страницы

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

среда, 4 декабря 2019 г.

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

#cpp #linux #c


Допустим, есть некий ./a.out (получен из Си), который выводит адрес, возвращаемый
первым же malloc (естественно, на пути к нему всегда выполняются одни и те же действия).

При каждом запуске мы видим разные числа
 - это особенность Linux (м.б. и в других системах тоже реализовано) запускать программу
так, чтобы стек, куча и область для mapping-а файлов размещались по случайным адресам).

А вот если смотреть в gdb или запустить этот ./a.out в valgrind, то увидим один и
тот же адрес.

Вопрос, как запускать (без apt-get install valgrind) ./a.out, чтобы печатаемый адрес
всегда был тем же самым?
    


Ответы

Ответ 1



Как верно замечено в комментариях, то, с чем вы столкнулись, называется 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).

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

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