2017-12-16 14 views
1

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バージョンが機能しません(余分なポインタ間接参照があるため)。

gccGOTOFFバージョンを生成させるにはどうすればよいですか?私は-fPIC-fpic-fPIE-fpie-pie-fno-pltのさまざまな組み合わせを試みました。それらのどれも働かなかった、それらのすべてはgccGOT版を作りました。

私はここにhttps://gcc.gnu.org/onlinedocs/gcc/x86-Options.htmlまたは任意の汎用フラグにするi386固有のフラグを見つけることができませんでした。実際にはhttps://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

を、私は"..."文字列リテラルのためGOTOFF再配置を得ている、と私はまたexternのためにそれらを取得したいです変数。

最終出力は、カスタムバイナリ形式(GNU ldリンカスクリプトを作成したもの)で静的にリンクされた実行可能ファイルです。ダイナミックリンクはなく、共有ライブラリはありません。アドレスのランダム化は、任意のアドレスに実行可能ファイルを自由にロードできるカスタムローダによって実行されます。だから、私は位置に依存しないコードが必要です。セグメントごとのメモリマッピングはありません。実行ファイル全体がそのままロードされます。

私がオンラインで見つけることができたすべてのドキュメントは、位置に依存しない実行可能ファイルが動的にリンクされていることを話していました。そこに役立つものは何も見つかりませんでした。

答えて

0

gcc -fPIEで解決できませんでしたので、出力ファイルを処理して手動で解決しました。

私はgcc -Wl,-qを使用し、再配置を含む出力ELF実行可能ファイルを使用します。I後処理このELF実行可能ファイル、および私が先頭に次のアセンブリ命令を追加します。

R0、R1、R2は... ELF実行可能でR_386_32移転のアドレスです
call next 
next: 
pop ebx 
add [ebx + R0 + (after_add - next)], ebx 
add [ebx + R1 + (after_add - next)], ebx 
add [ebx + R2 + (after_add - next)], ebx 
... 
after_add: 

、。 In use objdump -O binary prog.elf prog.bin', and now prog.bin 'には位置非依存コードが含まれています。コードが実行を開始するときにコードに必要な再配置を行う `add [ebx + ...]、ebx'命令で始まるからです。

.textセクションを書き込み可能にするには、実行環境によってはgccフラグ-Wl,-Nが必要です( `add [ebx + ...]、ebx '命令で必要です)。

関連する問題