だから私がしなければならないのは、物理メモリから直接カーネルシンボルを読むことです。次の行を使用して変数(記号)をエクスポートするカーネルモジュールを作成しました。
int test_var = 5;
EXPORT_SYMBOL(test_var);
cat /proc/kallsyms | grep test_var
私が使って
ffffffffc04d6064 r __kstrtab_test_var [smigenerator]
ffffffffc04d606d r __kstrtabns_test_var [smigenerator]
ffffffffc04d6054 r __ksymtab_test_var [smigenerator]
ffffffffc04d7000 D test_var [smigenerator]
したがって、私のシンボルはに保存されます0xc04d7000
。実行すると、sudo devmem2 0xc04d7000
その値(= 5)が得られます。そうですか?
間違った!このアドレスを読み取るとが返されます0xFF300A24
。変数が保存されるメモリアドレスを読み取るときに変数値を取得できないのはなぜですか?
カーネルベースアドレスの内容を読み取り、kallsymsから取得したこのアドレスは、カーネルベースアドレスに追加する必要があるオフセットです。これが本当かどうかはわかりませんが、もしそうなら、このカーネルベースアドレスをどのように取得できますか? ?
これは愚かな質問かもしれませんが、私はカーネルとその概念に完全に初めて触れ、私に役立つ答えを見つけることができませんでした。
記録上、私はUbuntu 22、カーネル5.15.0-52-genericを使用しています。
ベストアンサー1
シンボルはffffffffc04d7000
カーネルメモリの仮想アドレスに保存され(レイアウトのランダム化を無視しますが、最終的には重要ではありません)、ユーザー空間からアクセスできません。
ユーザー空間で変数にアクセスできるようにする(読み取り専用)には、vDSOを介して有効にする必要があります。gettimeofday
実装されました。また、見ることができますvvar.hで新しい変数を宣言する方法Linuxでvdsoを作成する。