第7章実行可能プログラムの動作
まず、研究ノート
1.ELF
2.コンパイルプログラム
ライブラリとの接続3.
第二に、試験記録
1.カーネルを更新することにより、その後、test_exec.cはtest.cのが上書きされます
2.test.c文書は正しくカーネル関数を起動してEXECVを確認し、execシステムコールが追加されます
3.最後に、GDBデバッガを起動
4.他の場所でsys_execveセットブレークポイント、シングルステップ
5.ハローハロー-h readelfが最後の出口のデバッグモードを入力して、EIF頭を表示することができます
可視ELFヘッダのサイズは52バイトであり、16進ダンプコマンドで最初の52のバイトを読み出す分析します
6.コマンド:hexdumpに対して-xこんにちは-n 52
分析:
最初のライン:
固定エルフ7f454c46の初めに最初の4バイト(0x45,0x4c、0x46のは、「E」、「L」であり、 「F」 ELFオブジェクトを表し、符号化されたASCII文字に対応します)。次のバイト01は、次の表現は、リトルエンディアンのバイト01はその後、次のバイト01は、ファイルヘッダのバージョンを示し、法律を表す、32ビットのオブジェクトを表します。残りのデフォルト値は0に設定されている
第二ライン:
0×0002のe_type値は、実行可能ファイルを示します。e_machine値0x0003はintel80386プロセッサアーキテクチャを表します。e_version値0x00000001のは、現在のバージョンを示します。e_entryの0x04080a8d値は、エントリポイントを表します。0x00000034のe_phoffオフセット値は、プログラムヘッダテーブルが0x34の又は52正確ELFヘッダのサイズをバイトであることを示しています。
第三行:
e_shoff 0x000a20f0値は、セクションヘッダテーブルのオフセットアドレスを表します。0x00000000には、未知の値のプロセッサe_flags特定のマーカーを示しています。e_ehsize値0x0034は、ELFファイルヘッダのサイズを52のバイトを表します。e_phentsizeエントリは、プログラムヘッダテーブル(塗布ヘッド)の長さを示し、すなわち0x0020にの値は32バイトです。e_phnumは値0x0006は、プログラム・ヘッダ・テーブルのエントリの数を与えます。0x0028のe_shentsize値は、セクション・ヘッダ・テーブル・エントリ(ヘッダ部)サイズは40バイトであることを示します。
4行目:
入り口31を示すセクションヘッダテーブルのe_shnumを0x001f値。0x001cのe_shstrndx値は、テーブル内のインデックスセクション名文字列テーブルセクションを表します。
7.exec()関数の構造
int do_execve(struct filename *filename,
const char __user *const __user *__argv,
const char __user *const __user *__envp)
{
return do_execve_common(filename, argv, envp);
}
static int do_execve_common(struct filename *filename,
struct user_arg_ptr argv,
struct user_arg_ptr envp)
{
// 检查进程的数量限制
// 选择最小负载的CPU,以执行新程序
sched_exec();
// 填充 linux_binprm结构体
retval = prepare_binprm(bprm);
// 拷贝文件名、命令行参数、环境变量
retval = copy_strings_kernel(1, &bprm->filename, bprm);
retval = copy_strings(bprm->envc, envp, bprm);
retval = copy_strings(bprm->argc, argv, bprm);
// 调用里面的 search_binary_handler
retval = exec_binprm(bprm);
// exec执行成功
}
static int exec_binprm(struct linux_binprm *bprm)
{
// 扫描formats链表,根据不同的文本格式,选择不同的load函数
ret = search_binary_handler(bprm);
// ...
return ret;
}
第三に、要約
上記のコードから、execve_共通DO_ DO_ execveの呼び出しが、execve_共通のDO_、主にexec_ binprmに依存している、search_binary_ハンドラーと呼ばれるexec_ binprmで重要な機能を持っています。これは、内部sys_execve処理です。
今週の学習の焦点は、文書処理のプロセスは、次のとおりです。
- 前処理:gccを-E -o HELLO.CPPのhello.c -m32(の責任は、ファイルが来る含まれているマクロ置換が含まれます)
- コンパイル:GCC -x CPP-出力-S hello.s -o HELLO.CPP -m32(GCCが-S CCL、コンパイルA大要コール
-Sアセンブリコードにコンパイルされ、CCLをコール) - コンパイル:gccの-xアセンブラ-c hello.s -o hello.o;(としてのgcc -c呼び出し、バイナリを入手)
- リンク:gccの-oこんにちはhello.o;(ターゲットの実行可能ファイル形式のgcc -o LDコール)
リンクは静的リンクと動的リンクに分かれています。静的にリンクされたELFオブジェクトファイルには、三つの主要な生成しました:
- 再配置可能ファイル:コードと適切なデータ、およびその他のオブジェクトの保存は、一緒に実行可能ファイルまたは共有ファイルを作成するために使用されます。主の.oファイル。
- 実行可能ファイル:プログラムの保存は、それが幹部(BA_OS)がどのようにプログラムのプロセスマッピング、文書を作成する方法を開始する場所をロードするためにあることを指摘し、実行します。
- 共有ファイル:次の二つのリンカーリンクされ使用されるコードとデータを保持し
、一方のリンクコンパイラ、あなたが他のオブジェクトファイルや他の再配置可能と共有ファイルを作成することができます
第二には、ダイナミックリンカで、関節の実行可能ファイルをプロセスイメージを作成するには、ファイルやその他のファイルを共有します。主の.soファイル。
EIP呼ぶそれは静的実行可能ファイルがリンクされている場合も、EIP ELFファイルヘッダe_entryポイントEIPアドレスエントリのための重要な概念であり、それが動的にリンクされている場合、EIP動的リンカーを指します。execveのは、静的にリンクされたプログラムの実行のために、EIPの値を変更することで、新たな方法の出発点として、カーネルスタックを救いました。