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);
(これは AppleのGDBソース からリバースエンジニアリングされています。)
このような文書化されていない機能の問題は、それらが予告なしに消える傾向があることです。 このStack Overflowの回答 動的リンカー dyld
によると、環境変数DYLD_NO_PIE
を参照するために使用されますが、これは10.9では機能しません。同様に、静的リンカーは明らかに--no-pie
オプションを使用するために使用されていましたが、現在はそうではありません。
では、ASLRを無効にする文書化された方法はありますか?
(ASLRを無効にする必要がある理由は、テストおよびデバッグ時に、アドレスベースのハッシュテーブルや BIBOPベース メモリマネージャーなどのオブジェクトのアドレスに動作が依存するコードの再現性を確保するためです。 。)
実際には、まだ-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
それは十分にランダムに見えます。
次に、-Wl,-no_pie
を使用して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
にMH_PIE
として定義され、文書化されています。
インターネット全体に、既存のバイナリからPIEフラグをクリアするためのツールがあります。 http://src.chromium.org/svn/trunk/src/build/mac/change_mach_o_flags.py
ASLRなしでPIE
フラグ付きバイナリを開始するための文書化された方法を提供することはできませんが、おそらく独自のコードをテストするため、テストプログラムを-no_pie
にリンクするか、後でテストバイナリからPIE
フラグを削除します。十分ですか?