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

Недавно мне попалась на глаза новость об обновлении деинсталлятора "Yank - Your Mac's Uninstaller". Он отрабатывает самые сложные случаи - когда программа устанавливается не только перетаскиванием в Applications, но и с помощью инсталлятора, когда достаточно много файлов записывается в разные каталоги. Краткое описание программы есть на DeepApple. Yank следит за файловой активностью инсталлятора и записывает в отдельный файл перечень устанавливаемых файлов, а далее, используя этот файл, может всё чисто деинсталлировать. Также есть онлайн-сервис, который содержит файлы для удаления более 150 программ, т.е. можно удалять программы, которые были установлены до начала использования Yank.

Yank - это пример программы, которая выстроена вокруг нескольких команд в shell. Я хочу продемонстрировать принцип, по которому она работает, а заодно продемонстрировать очень мощную технику отладки - DTrace.

Вольно процитирую Wikipedia (прошу прощения за перевод, читать по английски намного проще, чем переводить на русский, особенно возникают проблемы с терминами):

DTrace - это мощный фреймворк, предназначенный для динамического трейсинга. Он был создан Sun Microsystems для поиска ошибок ядра и приложений на продуктивных системах в реальном времени. Разработанный для Solaris, он был выпущен под лицензией CDDL и был портирован на несколько других Unix-систем.

DTrace может использоваться для получения разнообразной глобальной информации по работающей системе, такой, как количество памяти, использование процессора, файловой системы и сетевых ресурсов, используемых активными процессами. Он также может предоставить гораздо детальную информацию, например, аргументы, с которыми вызываются конкретные функции, или перечень процессов, доступающихся к конкретному файлу.

С детальной информацией по DTrace можно ознакомиться на таких ресурсах (или поискать в Интернет):

Прототип программы

Наша задача - запустить сбор информации файловой активности всех процессов в системе, записать её в файл, а затем проанализировать, какие файлы создавались интересующим нас процессом.

Будем экспериментировать с ProteMac (системой сбора информации по сетевому трафику) - она использует инсталлятор, который ставит много чего, включая драйвер.

Примечание. Рекомендуется закрыть iTunes, QuickTime Player, DVD Player, так как по заявлению Apple они блокируют работу DTrace для защиты лицензионного контента. Возможно они блокируют отладку себя же, так как информация по интересующим меня процессам фиксируется.

Запускаем DTrace

$ sudo dtrace -n \
'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }' \
> protemac.log

В файле видим строки, вида:

Запускаем инсталлятор

Запускаем, убеждаемся, что данные по этому процессу фиксируются, и запускаем установку.

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

Анализируем

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

$ cat protemac.log | grep pkgExtractor | cut -c 58- | sort

Получаем вывод (фрагмент):

///Applications/ProteMac Meter.app/Contents/.BC.50Myi7
///Applications/ProteMac Meter.app/Contents/.BC.XLbB01
///Applications/ProteMac Meter.app/Contents/Autolauncher/.BC.Spuh6S
///Applications/ProteMac Meter.app/Contents/Frameworks/CocoaEx.framework/Versions/A/.BC.JQH5kN
///Applications/ProteMac Meter.app/Contents/Frameworks/CocoaEx.framework/Versions/A/Resources/.BC.EcX4rG
///Applications/ProteMac Meter.app/Contents/Frameworks/CocoaEx.framework/Versions/A/Resources/.BC.M3gUoL
///Applications/ProteMac Meter.app/Contents/Frameworks/CocoaEx.framework/Versions/A/Resources/.BC.PGgSvo
///Applications/ProteMac Meter.app/Contents/Frameworks/CocoaProtector.framework/Versions/A/.BC.pbZPB2

После недолгих размышлений получаем перечень файлов и каталогов, которые нужно удалить при деинсталляции:

/Applications/ProteMac Meter.app/
/Library/LaunchAgents/com.protemac.MeterAutolauncher
/Library/ProteMac/
/System/Library/Extensions/AirGrabFirewallModule.kext/
/System/Library/LaunchDaemons/com.protemac.Daemon

Что нам и требовалось.

Проверка правильности

Для проверки посмотрим, что делает деинсталлятор, поставляющийся с программой. Делаем "Second Click" на деинсталляторе, смотрим скрипт uninstall.sh в каталоге "Contents/Resources":

Обратите, кстати, внимание на комментарии разработчиков :-) Наш анализ был верен - мы вычислили все файлы.

#!/bin/sh

rm -Rf "/Applications/ProteMac Meter.app"
rm -Rf "/Library/LaunchAgents/com.protemac.MeterAutolauncher"

# Наследие от старых версий
rm -Rf "/System/Library/LaunchDaemons/com.protemac.MeterDaemon"

# А это уже новые прибабахи :)
rm -Rf "/Library/Receipts/install.pkg"

cd "/Library/ProteMac/ProteMac NetServices.bundle/Contents/tools"

./removeAppFromList.sh "ProteMac Meter"
./isCanBeRemoved.sh

if [ $? -ne 0 ]; then
	exit 0
fi

cd /

rm -Rf "/System/Library/LaunchDaemons/com.protemac.Daemon"
rm -Rf "/System/Library/Extensions/AirGrabFirewallModule.kext"
rm -Rf "/Library/ProteMac/ProteMac NetServices.bundle"

Замечание по усовершенствованию

Также необходимо удалить системные файлы, генерируемые системой, такие, как кеши и т.п.

А для быстрого просмотра содержимого инсталлятора рекомендую удобную программу Pacifist.

Более правильно было бы отслеживать не обращение к файлам, а именно запросы на создание файлов и каталогов. Причём записывать не весь лог, а только активность исталлятора и его дочерних процессов. Но цель статьи была демонстрация метода, и этот метод можно развивать до достижения совершенства. Немного исследования, работы, тестирования, и можно выпускать свою программу.

Disclaimer

Dear ProteMac! In my article I have analyzed only common questions about your installer program. It is not a reverse engineering of your software. I respect your work. Однако судя по комментариям в деинсталляторе, идущем в комплекте с ProteMac, можно было эту фразу написать по-русски ;-)