子プロセスのスタックを読み取ろうとしていますが、うまくいきません。 ptrace
を使用してそれが可能であることはわかっていますが、ptrace
のインターフェイスでは一度に1ワードのみを読み取ることができ、スタックの大部分をスキャンしようとしています。
スタックの境界から/proc/$pid/mem
を読み取ってみましたが、最初にptraceを使用してそれにアタッチした後(推奨 here )、スタックの/proc/$pid/maps
ファイルから抽出されましたが、プロセスの異なる部分(ヒープなど)から読み取ろうとすると、同じコードは成功しますが、読み取りは(rootとして実行している場合でも)失敗し続けます。
私は何が間違っているのですか?他に選択肢はありますか?
ptrace
のインターフェイスでは、一度に1ワードしか読み取ることができません。スタックの大部分をスキャンしようとしています
それでは、ループを使用してください。正直に言って、それがptrace
の問題を構成する方法がわからないので、リモートアクセスプロセスに常に使用しています。
私はこのようなものを使用します:
static int memcpy_from_target(pid_t pid, char *dest, long src, size_t n)
{
static int const align = sizeof(long) - 1;
while (n)
{
size_t todo = MIN(n, sizeof(long) - (src & align));
long data = ptrace(PTRACE_PEEKTEXT, pid, src - (src & align), 0);
if (errno)
{
perror("ptrace_peektext (memcpy_from_target)");
return -1;
}
memcpy(dest, (char *)&data + (src & align), todo);
dest += todo; src += todo; n -= todo;
}
return 0;
}
Procファイルシステムを使用して別のプロセスのスタックを簡単に読み取ることができます(これにはrootアクセスが必要です)。/proc/pid/memから任意に読み取る前に、/ proc/pid/mapsを参照する必要があります。このファイルを読み取るだけで、多数のエントリが表示されます。スタックとしてマークされたエントリに関心があります。これを取得したら、スタックの下限と上限を読み取る必要があります。次に、/ proc/pid/memファイルを開き、スタックの下限を探し、正しいサイズのデータを読み取ります。
別の提案。
メインのLinuxカーネルツリーで受け入れられると、Christopher Yeohの Cross Memory Attach パッチを使用できるようになります。たとえば process_vm_readv のドキュメントを参照してください。
これは、微調整が必要かもしれないが、データの大きなチャンクでより効率的になるはずの別の戦略です。スタックの内容を取得するために、リモートプロセスでsyscallsを実行するという考え方です。特定のアーキテクチャコードが必要ですが、x86/x86_64のみを対象とする場合は、それほど面倒ではありません。
"/tmp/fifo"
などの名前付きパイプを作成します。PTRACE_SYSCALL
を使用してステップし、waitpid()
を使用して待機し、PTRACE_GETREGS
/PTRACE_PEEKTEXT
を使用して現在実行されているオペコードを確認します。open("/tmp/fifo")
、write()
スタックの内容、close()
記述子でオーバーライドして、リモートプロセスでシステムコールを実行します。名前付きパイプに代わるよりエレガントな方法があるかもしれませんが、今は考えられません。私がsyscallsだけを使用する理由は、リモートコードインジェクションは、さまざまなセキュリティ保護のため、最新のシステムではかなり信頼できないためです。欠点は、リモートプロセスがsyscallを実行するまでハングすることです(これは、主に計算を実行する一部のプログラムでは問題になる可能性があります)。
ほとんどの作業を実装している無料のコードが このソースファイル にあります。コードに関するフィードバックは大歓迎です!
lsstack を試すことができます。他のすべての成功した「別のプロセスのスタックの読み取り」プログラムと同様に、ptraceを使用します。/proc/$ pid/mem読み取りを使用してプログラムを動作させることができませんでした。論理的にはそうすべきですが、そうすることはできないと思います。