【C/C++】macOS + Clang 環境でASLRを無効にしてコンパイルする
MacOSではLeopard以降、ASLRによりメモリ空間がランダム化されているため、gdbでスタックトレースする際に、実行毎にスタックのアドレスが変わり内容を追いにくい場合があります。
ここではASLRを無効にしてコンパイルする方法を記載します。
【確認環境】
・macOS High Sierra
・LLVM-9.0 / Clang-900.0
-
ASLRが有効なモジュールか確認する
実行バイナリのMach-OヘッダにあるflagsにMH_PIE(下記参照)が立っている場合、モジュールロード時のアドレスがランダム化されます。
※PIE(Position Independent Executable)
#define MH_PIE 0x200000 /* When this bit is set, the OS will
load the main executable at a
random address. Only used in
MH_EXECUTE filetypes. */
load the main executable at a
random address. Only used in
MH_EXECUTE filetypes. */
(mach-o/loader.hで定義)
otoolコマンドで実行バイナリのMachヘッダを参照すると、MH_PIEが立っているか確認する事ができます。
$ otool -h aslr_enable_mod
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777223 3 0x80 2 16 1248 0x00200085
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777223 3 0x80 2 16 1248 0x00200085
上記例ではflags列に0x200000が立っているため、ASLRが有効なモジュールである事が解ります。
なお、otool "-hv"を指定する事で、 フラグ値を定義名で表示可能です。
(PIEが表示されます)
-
モジュールのASLRを無効化する
コンパイル時に"-no_pie"オプションを指定する事で、モジュールロード時のASLRを無効化できます。
これにより、自モジュールやリンクしている共有ライブラリが固定アドレスでロードされるようになります。
なお、ASLRを無効化した状態はセキュリティ上危険なため、リリースモジュールでは必ずASLRを有効化してコンパイルしてください。