#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).
Комментариев нет:
Отправить комментарий