問題タブ [mprotect]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - mprotect は、/proc/pid/maps 内の隣接する行を常に折りたたむわけではありません
しばらくすると、 への呼び出しが でmprotect()
失敗するプロセスがありますENOMEM
。このエラーは、「内部カーネル構造を割り当てることができませんでした」が原因で発生します。この時点で、ファイル/proc/<pid>/maps
には 65531 行が含まれており、これはもちろん疑わしいほど 2^16 に近いものです。
プロセスは、mmap (1280MB、MAP_PRIVATE | MAP_ANONYMOUS) でメモリのチャンクを取得することから始まり、mprotect()
単一ページ (または少数のページ) を呼び出して、デバッグのためにそれらへのアクセスを有効または無効にします。1280MB の mmaped 領域は、最初は では 1 行として表示されます/proc/<pid>/maps
が、 を呼び出すたびに、mprotect()
この領域が 3 つに「分割」される可能性があります。前のメモリ、変更されたページ、後のメモリです。いくつかの変更の後、2 つの隣接する (ただし個別に変更された) メモリ領域が同じアクセス フラグで終わると、通常は再びマージされるため、行の総数は適切に保たれます。
ただし「通常」のみ。失敗した場合/proc/<pid>/maps
、同じ保護を持つ多数の連続したメモリ領域が作成され、それらがマージされない理由がわかりません。1 ページの例では、それらは適切にマージされます。動作が異なるのはいつで、その理由は?
参考までに、失敗したプログラムはマルチスレッドですが、影響はありません (各スレッドの/proc/<tid>/maps
ファイルは同一です)。Linux カーネル「2.6.35-30-generic #56-Ubuntu SMP」および「3.2.0-37-generic #58-Ubuntu SMP」で見られます。
編集:再現方法:
で失敗するはずですerr = mprotect(..); assert(err == 0);
c - mmap された共有メモリ セグメントの mprotect
2 つのプロセスが shm_open および mmap-ed で開かれたメモリのセグメントを共有している場合、一方のプロセスの共有メモリの一部で mprotect を実行すると、この同じ部分で他方のプロセスから見たパーミッションに影響しますか? つまり、あるプロセスが共有メモリ セグメントの一部を読み取り専用にすると、他のプロセスも読み取り専用になりますか?
c++ - mprotect: 保護違反を引き起こす命令を取得する方法は?
mprotect を使用して、一部のメモリ ページを書き込み禁止に設定しています。そのメモリ領域に何らかの書き込みが試行されると、プログラムは SIGSEGV シグナルを受け取ります。シグナル ハンドラから、どのメモリ アドレスで書き込みが試行されたかがわかりますが、どの命令が書き込み保護違反を引き起こしているかを調べる方法がわかりません。そのため、シグナルハンドラー内で、プログラムカウンター(PC)レジスターを読み取って、障害のある命令を取得することを考えています。これを行う簡単な方法はありますか?
linux - mprotect ハンドラ内の現在のプログラム カウンタを取得して更新する方法
mprotect ハンドラ内の現在のプログラム カウンタ(PC)の値を取得したい。そこから、プログラムがいくつかの命令をスキップするように、PC の値を「n」個の命令で増やしたいと考えています。Linux カーネル バージョン 3.0.1 に対してすべてを実行したいと考えています。PC の値を取得できるデータ構造と、その値を更新する方法について何か助けはありますか? サンプルコードをいただければ幸いです。前もって感謝します。
私の考えは、メモリアドレスが書き込まれているときに何らかのタスクを使用することです。したがって、私の考えは、 mprotect を使用してアドレスを書き込み禁止にすることです。コードがそのメモリ アドレスに何かを書き込もうとすると、mprotect ハンドラを使用して何らかの操作を実行します。ハンドラーの世話をした後、書き込み操作を成功させたいと思います。したがって、私の考えは、メモリアドレスをハンドラー内で保護されないようにしてから、書き込み操作を再度実行することでした。コードがハンドラー関数から戻ると、PC は元の書き込み命令を指しますが、私は次の命令を指すようにしたいと考えています。したがって、命令の長さに関係なく、PCを1命令増やしたいと思います。
以下の流れを確認
メイン関数内:
c - mprotect は常に無効な引数を返します
書き込みアクセスを許可するために、protect を使用して .text セグメントの値を変更しようとしています。
mprotect は機能しません。常にmprotect failed with error:: Invalid argument
エラーを返します。
foo は、関数の 5 バイト後に格納される int を返すメソッドです (これが foo+5 の理由です)。
c++ - これらのアライメント関数の違いは何ですか?
私は自己変更プログラムを書いています。すでに機能しています。これらの 2 つの関数を見つけましたが、正確に何をするかわからないので、コードに適切なコメントを付けたいと思います。
ページサイズは getpagesize を使用して取得されます
オフセットの関数がメモリ アラインメント チェックに使用されていることがわかりました。私は彼らが何をしているのか漠然と知っていますが、違いはありませんか?
ありがとう。