пятница, 17 июня 2016 г.

MSSQL: подслушать обмен клиентского приложения с сервером

На самом деле иногда бывает сильно интересно, какие sql-запросы посылает клиентское приложение. Если дело происходит под линуксом, через unixodbc, то там легко - приписываем в odbcinst.ini (который находится где-то то ли в /etc, то ли в /usr/local/etc) пару строк:
[ODBC]
Trace=Yes
TraceFile=/home/huh-muh/sql.log
и в своем домашнем каталоге лицезреем весь обмен. Под windows, думалось, должны быть аналогичные механизмы, но всё оказалось чуть-чуть сложнее.

Во-первых, есть хорошая статья о том, как включить трассировку для клиентов SQL Servera. Вкратце:

1. Стаскиваем и разворачиваем самораспаковывающийся архив по этой ссылке.

2. В реестре находим (или создаём) ветку
HKEY_LOCAL_MACHINE\Software\Microsoft\BidInterface\Loader
в которой создаём ключ с именем ":Path" (двоеточие тут вроде как существенно) и значением:
"%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.50727\ADONETDiag.dll", если хотим трассировать ADO.NET
или
"%SYSTEMROOT%\SYSTEM32\msdaDiag.dll", если хотим трассировать прочих клиентов (mdac, dao и т.п.)

3. в кучке каталогов из п.1 находим MOF_Files и в нем выполняем команду:
mofcomp all.mof (а чего мелочиться-то)
эта команда компилирует и регистрирует трассировочные схемы (без понятия, что это такое). Результат этой регистрации можно проверить командой:
Logman query providers

4. Затем забираемся в корневой каталог этого распакованного архива и в нем выполняем команду:
Logman start MyTrace -pf "control_GUID_files/ctrl.guid.all" -o Out.etl -ets
в результате чего в этом каталоге создастся файл Out.etl, содержащий интересующую нас трассировку.
Тут есть маленькая тонкость. Если эта команда файл ctrl.guid.all не увидит (ну там, путь неправильно указали, или ещё что-то), она сильно не огорчится, но ничего ловить не будет. Поэтому надо внимательно присмотреться, пишет ли она в момент запуска раздел "Поставщики:" , в котором перечисляет guid-ы механизмов, которые будет отслеживать.

5. Запускаем приложение, которое хотим отследить, и пока мы там работаем, в файле из п.4 копится инфа в неудобоваримом виде.

6. Когда по нашему мнению наловится достаточно информации, завершаем трассировку командой:
Logman stop MyTrace -ets

7. Наконец, перегоняем информацию из этого Out.etl во что-то более текстовое командой:
TraceRPT /y Out.etl

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

Этот огорчительный момент вернул меня к старому доброму подслушиванию сети. Обычно я использую Packetyzer, а тут наткнулся на Microsoft Network Monitor 3.4 и решил попробовать его. Там, правда, было написано, что нужно ещё установить дополнительно NMDecrypt, но, по-моему, он ловит всё и так.(*) Для более новых систем есть Microsoft Message Analyzer, но у меня WinXP, так что тут без вариантов. Правда, результатом подслушивания является мешанина данных в кодировке ANSI и UCS-2e, но с этим приходится мириться, главное, что хоть какие-то обрывки получаются в читабельном виде.

* на одной машине потребовалось ещё доустановить Network Monitor Parsers и выбрать в меню Tools - пунт Options - вкладка Parser profiles профиль Default, чтобы программа перестала жаловаться "unable to build conversation"