3

私はdtrussMacOS X 10.8.5 を使用して、実行中のアプリケーションとそれが通信する SSL サーバーとの間の会話を確認しようとしています。Linuxとは異なりstrace、出力に完全なデータの文字列が表示されません。これは、プログラムと同じようにsendrecvファイル記述子で検出されると予想されるものです。

dtrussアプリが SSL サーバーで送受信しているデータを表示するにはどうすればよいですか?

私が制御する SSL サーバーへの接続をプロキシするよう誰かに言われる前に、はい、私はこのトリックを知っています。

4

1 に答える 1

6

dtrussは、DTrace 用に作成されたスクリプトの洗練された例であると同時に、DTrace で実現できることのデモンストレーションでもあります。ただし、その類似性trussstrace比較的不毛な OS X に非常に歓迎されていdtrussますが、いずれかの完全な代替を意図したものではなかったと思います。

いずれにせよ、あなたの質問は少しあいまいです: 表示される文字列が切り捨てられていることを懸念しているのか、 or の文字列がまったく表示されていないことを懸念しているのsendto()recvfrom()(DTrace によって明らかにされる基になるインターフェイス) はわかりません。私は両方に対処します。

まず、DTrace はカーネルでデータを収集します。ユーザーランドバッファーは、D 言語で取得されるcopyin()copyinstr()、記録されてコンシューマー (通常はdtrace(1)コマンド) に送信される前に取得されます。DTrace では、カーネル バッファ サイズがコンパイル時にわかっている必要があるため、そうでなければ予測できない文字列の長さに制限を課します。この制限はデフォルトで 256 バイトです。切り捨てが発生している場合は、次のように追加して制限を変更できます。

#pragma D option strsize=512

以下はdtruss既存のものpragmaです。

第 2 にdtruss、さまざまなシステム コールのフォーマット要件を把握するためにハードコードされています。ソースで明示的に処理されないため、sendto()またはその出力にバッファーの解釈は表示されません。recvfrom()それらを追加するのに適した場所を見つけるのを止めるものは何もありませんが、代わりに独自のスクリプトを書くことができます:

bash-3.2# cat sr.d
#pragma D option rawbytes

syscall::sendto:entry,
syscall::recvfrom:entry
/pid == $target/
{
    self->bufp = arg1;
    self->size = arg2;
}

syscall::sendto:return,
syscall::recvfrom:return
/pid == $target && self->bufp && self->size/
{
    printf("%s():\n", probefunc);
    tracemem(copyin(self->bufp, self->size), 64);
    printf("\n");
    self->bufp = self->size = NULL;
}
bash-3.2# dtrace -qs ./sr.d -p 16988
sendto():

             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
         0: 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00  hello...........
        10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

^C

bash-3.2#

tracemem()文字列に関しては、による DTrace のデータ記録バッファの使用に厳しい制限を設ける義務があることに注意してください。制限にほとんど近づかない場合、出力が圧倒され、ほとんどが冗長になるという苛立たしい結果が生じます。文字列を探していることがわかっている場合は、copyinstr()代わりに単純に使用できます。私の OS X 10.6.8 よりも最新の DTrace 実装を使用している場合は、次のように記述できることがわかります。

tracemem(copyin(self->bufp, self->size), 64, self->size);

ここで、2 番目の引数は記録されるバイト数のハード リミットですが、表示されるバイト数はオプションの 3 番目の引数によって制限されます。

最後に、ユーザーランドアドレスはシステムコールへの入り口で記録されますが、出口でのみ使用されることに注意してください。これは、システム コールが必要に応じてデータをフォルトインできるようにする一般的なイディオムです --- DTrace 自体はそうしません。非常駐アドレスをトレースするように要求された場合、実行時にエラーが発生します。

于 2013-11-10T22:54:07.800 に答える