Документированный способ отключить ASLR в OS X?

в OS X 10.9 (Mavericks) можно отключить рандомизация адресного пространства для одного процесса, если вы запустите процесс, вызвав posix_spawn() и передача недокументированного атрибута 0x100. Вот так:

extern char **environ;
pid_t pid;
posix_spawnattr_t attr;

posix_spawnattr_init(&attr);
posix_spawnattr_setflags(&attr, 0x100);
posix_spawn(&pid, argv[0], NULL, &attr, argv, environ);

(это реверс-инжиниринг от источники GDB от Apple.)

проблема с недокументированными функциями, как это, что они, как правило, исчезают без уведомления. Согласно этот Ответ переполнения стека динамический компоновщик dyld обращались к переменной среды DYLD_NO_PIE, но это не работает в 10.9; аналогично статический компоновщик, по-видимому, использовал , но это уже не так.

Итак, есть ли документированный способ отключить ASLR?

(причина, по которой мне нужно отключить ASLR, заключается в обеспечении повторяемости при тестировании и отладке кода, поведение которого зависит от адресов объектов, например, хэш-таблицы на основе адресов и бибоп на основе менеджеры памяти.)

1 ответов


на самом деле, есть еще -no_pie флаг компоновщика, но вы могли бы подумать, что он на самом деле называется --no-pie.

позволяет иметь небольшую тестовую программу:

#include <stdio.h>

const char *test = "test";

int main() {
  printf("%p\n", (void*)test);
  return 0;
}

и сначала скомпилируйте как обычно:

cc -o test-pie test-pie.c

и проверьте флаги

$ otool -hv test-pie
test-pie:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    16       1376   NOUNDEFS DYLDLINK TWOLEVEL PIE

хорошо есть PIE флаг там, давайте проверим

$ for x in $(seq 1 5); do echo -n "$x "; ./test-pie; done
1 0x10a447f96
2 0x10e3cbf96
3 0x1005daf96
4 0x10df50f96
5 0x104e63f96

это выглядит достаточно случайным.

теперь, давайте скажем компоновщику, что мы не хотим PIE используя -Wl,-no_pie:

cc -o test-nopie test-pie.c -Wl,-no_pie

конечно же PIE флаг исчез:

$ otool -hv test-nopie
test-pie:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    16       1376   NOUNDEFS DYLDLINK TWOLEVEL

и тест:

$ for x in $(seq 1 5); do echo -n "$x "; ./test-nopie; done
1 0x100000f96
2 0x100000f96
3 0x100000f96
4 0x100000f96
5 0x100000f96

поэтому мы делаем компоновщик не добавлять PIE флаг, и моя система Mavericks, похоже, все еще соблюдает его.

FWIW,PIE флаг определен и документирован в /usr/include/mach-o/loader.h as MH_PIE.

есть инструменты по всему Интернету, чтобы очистить флаг пирога от существующих двоичных файлов, например http://src.chromium.org/svn/trunk/src/build/mac/change_mach_o_flags.py

пока я не могу предложить вам документированный способ начать PIE-помеченный двоичный файл без ASLR, так как вы хотите проверить код, предположительно свой собственный, просто связывая свои тестовые программы с -no_pie или удалить PIE флаг из двоичных файлов теста должно хватить?