ここにいくつかのコードがあります:
#include <stdio.h>
#include <string.h>
char globalbuf[256];
void function(char *argv) {
char localbuf[256];
strcpy(localbuf, argv);
strcpy(globalbuf, localbuf);
printf("localbuf addr: %p globalbuf addr: %p\n", localbuf, globalbuf);
}
int main(int argc, char **argv) {
function(argv[1]);
return 0;
}
ASLRとその仕組みを調べていました。 OSとコンパイラについての詳細
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Linux 3.5.0-32-generic #53-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux
そのため、このコードを実行すると、常に変化するlocalbufアドレスが表示されます。 ASLRが有効になっていてFull Randomizedモードに設定されているので、これは完全に問題ありません。ただし、globalbufアドレスは常に同じままです。初期化されていないグローバル変数と静的変数がBSSセクションの一部であることを知っています。したがって、私は、BSS、テキスト、およびデータセクションがASLRによってランダム化されていないことを想定しています。
これは正しいです?そうでない場合、私は paper にリンクします。 2ページ目の最後の段落は、私がここで提案していることを示しています。
私が理解しているように、すべてのプロセスには独自のスタック、ヒープ、テキスト、bss、およびデータセクション/エリアがあるため、プロセスが生成されるたびに、ランダムアドレスがベースポインターに割り当てられ、それ以外はすべてそれからのオフセットです。その場合、globalbufに対して何が出力されますか、それはオフセットですか? globalbufの実際のアドレスを見つけるにはどうすればよいですか?
globalbuf
変数は初期化されていない静的変数であるため、その仮想アドレスはnotランダム化されています。
初期化されていないグローバル変数と静的変数がBSSセクションの一部であることを知っています。したがって、私は、BSS、テキスト、およびデータセクションがASLRによってランダム化されていないことを想定しています。
BSSセクションは、初期化されていないデータとしてマークされているため、ランダム化されません。これは、実行可能ファイルのセクションヘッダーに設定されるフラグです。このセクションのデータは静的であり、アプリケーションを実行するたびに常に同じアドレスになります。表示される不変のポインター値は、globalbuf
変数の仮想アドレスです。
テキストセクションとデータセクションareはランダム化されます(アプリケーションが-fPIE
で位置独立としてコンパイルされている場合)。これらはそれぞれコードセグメント(CS)およびデータセグメント(DS)としてマークされているためです。コードとデータセグメントはx86で特別な意味を持ち、それらのベースアドレスはCSとDSセグメントレジスタに入力されます。これがdword ptr ds:[05012340]
のような参照を頻繁に見る理由です。およびアセンブリのdword ptr cs:[00410000]
-前者はデータセグメント(DS)内のアドレス、後者はコードセグメント(CS)内のアドレスです。これらは重要なセクションであるため、ベースアドレスはランダム化されています(つまり、等しくベースアドレスからのオフセット)。