gcc
コマンドラインフラグまたはその他の設定をGOTOFF
に置き換えて、静的にリンクされた位置非依存のi386実行ファイルをGOT
に再配置します。私が以下で試していたことの詳細。GCCを使用した位置に依存しない実行ファイルのグローバル変数の再配置を修正しました
私のソースファイルg1.s
は次のようになります。
extern int answer;
int get_answer1() { return answer; }
私の他のソースファイルg2.s
は次のようになります。
extern int answer;
int get_answer2() { return answer; }
私はi386用gcc -m32 -fPIE -Os -static -S -ffreestanding -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables g1.c
でそれらをコンパイルします。
私は、次のアセンブリ出力を得る:ここで
.file "g1.c"
.text
.globl get_answer1
.type get_answer1, @function
get_answer1:
call __x86.get_pc_thunk.cx
addl $_GLOBAL_OFFSET_TABLE_, %ecx
movl [email protected](%ecx), %eax
movl (%eax), %eax
ret
.size get_answer1, .-get_answer1
.section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
.globl __x86.get_pc_thunk.cx
.hidden __x86.get_pc_thunk.cx
.type __x86.get_pc_thunk.cx, @function
__x86.get_pc_thunk.cx:
movl (%esp), %ecx
ret
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits
は、GCC 7.2とオンラインこの現象を再現する方法です:https://godbolt.org/g/XXkxJh
の代わりに上記GOT
、私はGOTOFF
を取得したい、と思いますmovl %(eax), %eax
が消えるはずですので、関数のアセンブリコードは次のようになります。
get_answer1:
call __x86.get_pc_thunk.cx
addl $_GLOBAL_OFFSET_TABLE_, %ecx
movl [email protected](%ecx), %eax
ret
このGOTOFF
アセンブリバージョンが何であるかを確認しました。GOT
バージョンが機能しません(余分なポインタ間接参照があるため)。
gcc
にGOTOFF
バージョンを生成させるにはどうすればよいですか?私は-fPIC
、-fpic
、-fPIE
、-fpie
、-pie
、-fno-plt
のさまざまな組み合わせを試みました。それらのどれも働かなかった、それらのすべてはgcc
をGOT
版を作りました。
私はここにhttps://gcc.gnu.org/onlinedocs/gcc/x86-Options.htmlまたは任意の汎用フラグにするi386固有のフラグを見つけることができませんでした。実際にはhttps://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
を、私は"..."
文字列リテラルのためGOTOFF
再配置を得ている、と私はまたextern
のためにそれらを取得したいです変数。
最終出力は、カスタムバイナリ形式(GNU ldリンカスクリプトを作成したもの)で静的にリンクされた実行可能ファイルです。ダイナミックリンクはなく、共有ライブラリはありません。アドレスのランダム化は、任意のアドレスに実行可能ファイルを自由にロードできるカスタムローダによって実行されます。だから、私は位置に依存しないコードが必要です。セグメントごとのメモリマッピングはありません。実行ファイル全体がそのままロードされます。
私がオンラインで見つけることができたすべてのドキュメントは、位置に依存しない実行可能ファイルが動的にリンクされていることを話していました。そこに役立つものは何も見つかりませんでした。