3

Linux 用の非常に単純なプロセス ローダーを作成しています。ロードしている実行可能ファイルは既にコンパイルされており、それぞれがメモリ内のどこにあると予想されるかを知っています。私が試した最初のアプローチは、次mmap()のように、各コードまたはデータ セクションを正しい場所に手動で配置することでした。

mmap(addr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)

MAP_FIXED フラグを削除しない限り、セグメンテーション違反が発生します。これは、1 つのブロックのアドレスが既にメモリ内にある何か、おそらくローダー自体と競合しているように思われるためです。アドレス0x401000が問題のようです。

私はこれをどこから始めるべきかさえよくわかりません。友人は、メモリアクセス操作を仮想化することを提案しました。そのためにどのようなパフォーマンス ヒットが発生するかはわかりません。また、それがどのように行われるかもわかりませんが、オプションになる可能性があります。私が本当にやりたいのは、「空の」プロセスを作成することです。これは、それに関する限り、メモリを完全に実行するため、必要になるまでユーザー空間には何もロードされません。「空の」プロセスの概念全体は無意味かもしれませんが、それは私が望むものを説明する最良の方法です. 私は、私を助けるかもしれないいくつかの参照や例を切望しています。

4

1 に答える 1

0

プロセスを実行した状態で (「sleep(1000);」でスヌーズしている可能性があります)、/proc/pid/maps を確認します。これにより、0x401000 が何に使用されているかがわかります。

~$ sleep 1h &
[3] 2033
~$ cat /proc/2033/maps
00110000-002af000 r-xp 00000000 08:01 1313056    /lib/i386-linux-gnu/libc-2.15.so
...

私のボックスでは、 /bin/sleep はそのブロックを使用しておらず、私の小さなワンライナー プログラムも使用していません。

おそらく、そこに着陸したいライブラリにリンクしていますか?

したがって、1 つの方法は、必要なブロックを早期に割り当てることです (main() が実行されるずっと前に、その情報を他の場所で探してください)。

もう 1 つの方法は、使用されていないことが「わかっている」アドレスにコードをリンクすることです (おそらく、x86 オペコードを自分で生成しているか、そうでなければ「リンク」しているため、無理をする必要はありません)。

別のより良いオプションは、コードを再配置可能にすることです。プロセス全体のアドレス空間 (正確には exec が行うこと) を置き換えたくないという事実は、多かれ少なかれ、コードがまさにそれであるべきであることを示しています。

したがって、使用可能なアドレスを見つけ、そこにビットをロードし、必要に応じて再配置を実行します (ELF でない場合は、ディスク上のファイル形式に再配置情報を含める必要があります)。それはハイロードであり、ローダーから次に望むであろうことは明らかです。

もちろん、これは dlopen() を自分で再実装することを意味します。あなたはそれがどのように機能するかを学ぼうとしているだけだと思います-そうでない場合は、man dlopen. Stephane のルール ゼロ: 既にあります ;-)

コードからの他のライブラリへのリンク (重複なし)、dlclose()、初期化子、さまざまな RTLD_* モード、MYCUSTOMLD_LIBRARY_PATH、GCC の __thread 指定子などを尊重することを忘れないでください。;-)

于 2012-08-18T23:08:06.900 に答える