Как увидеть полные строки в выводе dtruss?

Я использую dtruss в MacOS X 10.8.5, пытаясь увидеть диалог между запущенным приложением и SSL-сервером, с которым оно взаимодействует. В отличие от strace в Linux, я не вижу в выводе полных строк данных, как я ожидал найти, поскольку программа делает send и recv в файловом дескрипторе.

Как я могу заставить dtruss показывать мне данные, которые приложение отправляет и получает с помощью SSL-сервера?

Прежде чем кто-нибудь скажет мне проксировать соединения с SSL-сервером, которым я управляю, да, я знаю этот трюк, и нет, это конкретное приложение слишком умно, чтобы попасться на него.


person ruief    schedule 09.11.2013    source источник


Ответы (1)


dtruss — это элегантный пример сценария, написанного для DTrace, и демонстрация возможностей DTrace. Однако, хотя его сходство с truss или strace очень приветствуется в относительно бесплодной OS X, я подозреваю, что dtruss никогда не предназначался для полной замены ни того, ни другого.

В любом случае, ваш вопрос немного двусмыслен: я не уверен, обеспокоены ли вы тем, что строки, которые вы видите, усечены или что вы вообще не видите никаких строк для sendto() или recvfrom() (базовые интерфейсы, обнаруженные DTrace ). Я обращусь к обоим.

Во-первых, DTrace собирает данные в ядре; пользовательские буферы получаются с помощью copyin() или copyinstr() языка D перед записью и передачей обратно потребителю — обычно это команда dtrace(1). DTrace требует, чтобы размер буфера ядра был известен во время компиляции, и поэтому налагает ограничение на непредсказуемую длину строки. По умолчанию это ограничение составляет 256 байт; если вы видите усечение, вы можете изменить ограничение, добавив, например,

#pragma D option strsize=512

ниже существующего pragma dtruss.

Во-вторых, 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(); если у вас более современная реализация DTrace, чем моя OS X 10.6.8, вы можете обнаружить, что можете написать

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

где второй аргумент по-прежнему жестко ограничивает количество записываемых байтов, но количество отображаемых байтов ограничено необязательным третьим аргументом.

Наконец, обратите внимание, что адрес пользователя записывается при входе в системный вызов, но используется только при выходе. Это распространенная идиома, которая позволяет системному вызову при необходимости вводить данные с ошибкой --- DTrace не будет делать этого сам и выдаст ошибку во время выполнения, если его попросят отследить нерезидентный адрес.

person Robert Harris    schedule 10.11.2013