vmlinux ヘッダーにはカーネル イメージの長さが含まれていますか?

vmlinux ヘッダーにはカーネル イメージの長さが含まれていますか?

私は、複数の部分から構成される複合ファイルを逆アセンブルしようとしています。その 1 つは、他の複数のファイルの間に挟まれた非圧縮カーネルです。カーネル部分の正確な長さを見つけようとしていますが、これは困難です。

vmlinux ヘッダーには、ブートローダが実行前に読み取るデータの量に関する指示がありますか、それとも、vmlinux ファイルのすべての内容がブートローダからのハンドオフ時にロードされることが想定されていますか?

答え1

簡単に答えると「いいえ」ですが、これが ELF イメージであれば、多少のハッキングでカーネルを見つけられる可能性があります。readelf以下のハックを参照してください。

ブートローダは、カーネルとルート ファイル システムが存在するファイルの形式を認識する役割を担っています。これには、カーネル ファイルのサイズ (形式は問いません) を認識することも含まれます。PowePC と Blackfin では、ブートローダはカーネルが圧縮されている場合はそれを解凍し、それを RAM の最終的な場所に書き込む役割を担っています。ARM では、カーネルは自己解凍型であるため、ブートローダは生のカーネル ファイルを RAM の適切な場所にコピーして実行を開始するだけで済みます。

カーネルが自己解凍型の場合、圧縮されたカーネル ファイルのサイズを示すシンボルは、使用される解凍アルゴリズムに応じて、ファイルの先頭の解凍コードのどこかにある場合とない場合があります。ただし、特定のカーネル ビルドのリンカー マップがなければ、その場所を知る方法はありません。もちろん、ブートローダには知る方法はありません。

圧縮されていないカーネル コード自体は、2 つのシンボルとで囲まれています。これらのシンボルの_stextアドレス_endはカーネル自体の開始と終了ですが、initramfs がカーネル バイナリにリンクされている場合、インクルードされた initramfs の範囲は含まれません。initramfs の範囲は、リンカーによって 2 つのカーネル シンボルとに設定されます__initramfs_start__initramfs_endブートローダには通常、カーネル シンボル テーブル (ファイル内) を読み取る機能がなく、この機能がなければ、カーネル ファイル内のおよびシンボルのSystem.map位置を知る方法がありません。つまり、シンボルの位置は、バイナリ ファイルの先頭からの固定オフセットではありません。これはリンク時に決定され、カーネルのビルド構成によって変わる可能性があります。_end__initrams_end

ELF 形式の非圧縮カーネルの場合、ELF ヘッダー (複合ファイルのダンプ177 E L F内) を探すことで、vmlinux ファイルの開始を特定できる可能性があります。その後、この時点からファイルの残りの部分でまたは を実行して、ファイル オフセットが最も高いセクション ( ) を見つけることができます。このオフセットにセクション サイズを追加すると、vmlinux の末尾に到達します。この方法をスト​​リップされていない PPC vmlinux を使用してテストしたところ、スタンドアロンの vnlinux ファイル サイズと正確に一致するサイズが得られました。カーネルをストリップした後、この方法では、ストリップされたイメージ サイズより 1283 バイト短い結果になりました。od -creadelf -eobjdump -h.shstrtab

組み込みシステムでは通常、カーネル、rootfs、デバイス ツリー、その他のコンポーネントをパックするためにファイル形式を使用しますmkimage。たとえば、U-boot は mkimage に対応しているため、mkimage ファイル内でカーネル バイナリがどこで始まりどこで終わるかを認識し、カーネルが圧縮されているかどうか、カーネル ファイルを書き込む RAM アドレスを認識します。

関連情報