web-dev-qa-db-ja.com

OS XでASLRを無効にする文書化された方法?

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ベース メモリマネージャーなどのオブジェクトのアドレスに動作が依存するコードの再現性を確保するためです。 。)

27
Gareth Rees

実際には、まだ-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.hMH_PIEとして定義され、文書化されています。

インターネット全体に、既存のバイナリからPIEフラグをクリアするためのツールがあります。 http://src.chromium.org/svn/trunk/src/build/mac/change_mach_o_flags.py

ASLRなしでPIEフラグ付きバイナリを開始するための文書化された方法を提供することはできませんが、おそらく独自のコードをテストするため、テストプログラムを-no_pieにリンクするか、後でテストバイナリからPIEフラグを削除します。十分ですか?

37
nmaier