пятница, 28 января 2011 г.

APTITUDE vs. APT-GET

При работе с операционными системами, базирующимися на Debian и использующими apt (например, Ubuntu), вы познакомитесь с некоторыми инструментами управления:

apt-get: устанавливает и удаляет пакеты из системы, а также может обновлять список пакетов и установленное программное обеспечение.
apt-cache: поиск необходимого пакета по списку пакетов apt, находящегося на локальной машине.
dpkg - используется для различных административных задач, например, для переконфигурирования Xorg.

Если вы планируете администрировать свою систему и дальше, то должны знать ещё некоторые инструменты, которые рано или поздно пригодятся:

apt-listbugs: ищет ошибки в пакете программы ещё до установки самой программы.
apt-listchanges: то же самое, что и apt-listbugs, но для безошибочных изменений.
apt-rdepends: для показа дерева зависимости пакета.
deborphan - ищет обособленные зависимости в системе, оставленные после удаления родительских пакетов.
debfoster - помогает deborphan идентифицировать, в каких зависимостях пакета система больше не нуждается.
dselect - интерфейс для просмотра, выбора и поиска пакетов в вашей системе.

Ещё: apt-cdrom, apt-config, apt-extracttemplates, apt-ftparchive, apt-key, apt-mark and apt-sortpkgs.

Как вы заметили, это 16 различных инструментов, с которыми вы познакомитесь, когда приступите к изучению вашего дистрибутива.

Дальше - больше, apt-get имеет большую проблему с удалением пакетов. Сначала он  определяет зависимости, которые должны быть установлены для выбранного пакета, но не определяет их, когда вы удаляете этот пакет. Если зависимости удовлетворены, ‘apt-get remove’ удалит выбранные пакеты, но оставит обособленные зависимости. Альтернатива? Aptitude.

Перед тем, как продолжить, хотелось бы сказать, что ‘apt-get autoremove’ уже в состоянии обращаться к обособленным зависимостям. Это, конечно, шаг в правильном направлении. Однако, apt-get удобен, если вам захочется изучить 16 дополнительных инструментов к нему. Aptitude, как будет показано, заменит их всех.

Aptitude — это превосходный способ для установки, удаления, обновления, иначе говоря, для управления вашей системой совместно с apt. Во-первых, aptitude может решить проблемы обособленных зависимостей. Во-вторых, у него блокирующий ошибки dselect интерфейс. Последнее, и самое важное, здесь используется один инструмент для выполнения многих функций. Давайте посмотрим:
aptitude: при запуске без аргументов появляется графический интерфейс (правда, в консоли, прям как mc) для поиска, установки, обновления и других административных действий над пакетами.

aptitude install: установка программного обеспечения, а также построение необходимых зависимостей.
aptitude remove: удаление пакетов, а также обособленных зависимостей.
aptitude purge: удаление пакетов и обособленных зависимостей, а также ненужных конфигурационных файлов.
aptitude search: поиск пакетов по локальному списку apt.
aptitude update: обновление локального списка пакетов.
aptitude upgrade: обновление уже установленных пакетов по обновленному списку пакетов.
aptitude clean: удаление установочных файлов.
aptitude dist-upgrade: обновление пакетов, даже если некоторые из них не будут использованы для установки.
aptitude show: подробная информация о пакете.
aptitude autoclean: удаление устаревших пакетов, но сохранение текущих.
aptitude hold: исправление ошибок в пакете текущей версии, но не его обновление.

Сразу видно, что используется одна команда с разными удобночитаемыми вариантами (нет флагов). И это только верхушка айсберга. Например, используем aptitude при поиске пакета, результат — сортировка найденного в алфавитном порядке и краткое описание каждого пакета. Эта команда даже скажет вам, какие пакеты уже установлены в системе, в отличии от apt-cache, который выводит список пакетов в случайном и неудобно читаемом порядке.

Aptitude превосходит apt-get: лучшая обработка зависимостей, удобный интерфейс, ОДИН инструмент и др.

среда, 26 января 2011 г.

Системная информация
arch отобразить архитектуру компьютера
uname -m
uname -r отобразить используемую версию ядра
dmidecode -q показать аппаратные системные компоненты - (SMBIOS / DMI)
hdparm -i /dev/hda вывести характеристики жесткого диска
hdparm -tT /dev/sda протестировать производительность чтения данных с жесткого диска
cat /proc/cpuinfo отобразить информацию о процессоре
cat /proc/interrupts показать прерывания
cat /proc/meminfo проверить использование памяти
cat /proc/swaps показать файл(ы) подкачки
cat /proc/version вывести версию ядра
cat /proc/net/dev показать сетевые интерфейсы и статистику по ним
cat /proc/mounts отобразить смонтированные файловые системы
lspci -tv показать в виде дерева PCI устройства
lsusb -tv показать в виде дерева USB устройства
date вывести системную дату
cal 2007 вывести таблицу-календарь 2007-го года
date 041217002007.00 установить системные дату и время ММДДЧЧммГГГГ.СС (МесяцДеньЧасМинутыГод.Секунды)
clock -w
сохранить системное время в BIOS

прозрачность заголовка окон в Gnome

Код:
gconf-editor
/apps/gwd/metacity_theme_active_opacity 0.5
/apps/gwd/metacity_theme_active_shade_opacity false
/apps/gwd/metacity_theme_opacity 0.5
/apps/gwd/metacity_theme_shade_opacity false

Расширения для eclipse


Многие ругают Eclipse за то, что там нет многого из того, что есть в коробке у Jetbrains Intellij IDEA. Мне всегда казалось это не очень корректным, так как Eclipse в первую очередь платформа, а уже потом - среда для Java разработки.
Решил собрать воедино весь список используемых мною расширений для Eclipse.
  1. Subclipse - без этого никуда. Это расширение позволяет работать с системой контроля версий Subversion не выходя из Eclipse.
  2. m2eclipse - Расширение для работы с maven. Графический редактор pom.xml позволяет избавиться от редактирования pom.xml вручную. В качестве приятного дополнения - возможность посмотреть графически список зависимостей проекта (вместе с транзитивными), а так же увидеть ситуации, когда 2 разные библиотеки зависят от разных версий одной и той же библиотеки.
  3. Google Plugin for Eclipse - официальное расширение от Google для работы с Google Web Toolkit и Google Application Engine.
  4. Eclipse-CS - Нет, это не запускалка Counter Strike, а всего лишь расширение, интегрирующее статический анализатор исходного кода Checkstyle в Eclipse. Проверяет правильность форматирования кода согласно заданным правилам. Обязательное расширение при работе в команде.
  5. Spring IDE - расширение от команды SpringSource для работы с проектами, использующими Spring, в том числе Spring AOP и Spring Webflow.
  6. XMind - отличное расширение, предоставляющее mind-mapping возможности в Eclipse.
  7. JBoss Tools - наборо расширений для работы с продуктами JBoss - Hibernate, JBoss AS, Drools, jBPM, JSF, (X)HTML, Seam, Smooks, JBoss ESB, JBoss Portal...
  8. EclEmma - интеграция отличной библиотеки EMMA в Eclipse. EMMA - приложение для подсчёта покрытия кода тестами. Must-have расширение.
  9. TPTP - Под этой странной аббревиатурой скрывается Test & Performance Tools Platform. Набор расширений для тестирования и профилирования приложений.
  10. PMD - Интеграция библиотеки PMD, которая выполняет статический анализ кода на предмет возможных ошибок в коде.
  11. WTP - Web Tools Platform - официальный набор расширений для разработки Web и Java EE приложений.
  12. Groovy & Grails - расширение для работы с языком Groovy и фреймворком Grails.
  13. eGit - расширение предоставляет возможность работы с распределенной системой контроля версий git.
  14. Eclipse SQL Explorer - тонкий SQL-клиент, который позволяет просматривать различные JDBC-совместимые базы данных.
Очень много расширений есть на Eclipse Plugin Central

Read more: http://atamanenko.blogspot.com/2009/05/eclipse.html#ixzz1C90jWgTn

Eclipse для веб-разработчиков

Несмотря на огромное количество редакторов и IDE, мне всегда в них чего-нибудь не хватало. Перепробовав, наверно, несколько десятков различного ПО для разработчиков, решил взяться за Eclipse.

Существуют уже готовые сборки Eclipse для различных языков программирования и типов разработки (программирование, моделирование, проектирование БД и т.д.). Но я рекомендую начать с базовой среды Eclipse Platform Runtime и дополнить её нужными вам расширениями.

  • Установите JRE (Java Runtime Environment), если у вас все ещё его нет.
  • СкачайтеEclipse Platform Runtime Binary (eclipse-platform-3.5-win32.zip — 47 Мб).Распакуйте в любой каталог и сделайте ярлык на eclipse.exe. Всё, установка базовой платформы завершена.Совет для пользователей Vista: ни в коем случаене устанавливайте Eclipse в Program Files и прочие защищенные системные каталоги. В противном случае могут возникнуть проблемы с обновлениями. Устанавливайте или в свой пользовательский каталог, или туда, где у вас лежат файлы, связанные с веб-разработкой (что предпочтительнее).

Первым делом необходимо поставить базовые расширения для работы с основными веб-файлами: HTML, CSS, Javascript и XML. Начнем с установки расширений, которые будут использоваться другими расширениями.
  1. EMF Runtime (Eclipse Modeling Framework) emf-runtime-2.5.0.zip — 4,5 Мб
  2. GEF SDK (Graphical Editing Framework) GEF-SDK-3.5.0.zip – 6,4 Мб
  3. DTP (Data Tools Platform) dtp_1.7.0.zip – 13 Мб
  4. RSE Runtime (Remote System Explorer для FTP, SSH и прочего) RSE-runtime-3.1.zip – 4,3 Мб
  5. CVS Client eclipse-CVS-Client-3.5 – 2 Мб
  6. DLTK (Dynamic Languages Toolkit)
    1. DLTK Core dltk-core-R-1.0-200906171219.zip – 6,2 Мб
    2. DLTK Tests dltk-core-Automated_Tests-R-1.0-200906171219.zip – 0,4 Мб
    3. ANTLR Runtime
    4. JDT (Java Development Tools, используется JSDT) eclipse-JDT-3.5.zip – 25 Мб
    5. DLTK Remote Projects via DSDP TM dltk-rse-R-1.0-200906171219.zip – 0,2 Мб (на странице с DLTK Core)
    6. DLTK Mylyn Intergation dltk-mylyn-R-1.0-200906171219.zip – 0,4 Мб (на странице с DLTK Core)
  7. WTP (Web Tools Platform) wtp-wst-sdk-R-3.1-20090616035105.zip – 60 Мб
  8. XSD Runtime xsd-runtime-2.5.0.zip – 1 Мб

Эти расширения можно установить вручную, копируя файлы и каталоги (с сохранением структуры) из архивов прямо в каталог Eclipse.

Затем начинается установка необходимых вам расширений. Эти расширения лучше устанавливать прямо в Eclipse через меню Help – Install New Software. Далее добавляется нужный сайт (Add… Add Site, выбираем этот сайт в списке, и после загрузки списка пакетов отметьте нужные), с которого будет загружаться и устанавливаться расширение.

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

Совет: после установки всех нужных расширений можно также увеличить объем памяти для комфортной работы с Eclipse. Для этого откройте файл eclipse.ini и отредактируйте параметры –Xm примерно так:

-Xms128m (минимальный объём)
-Xmx512m (максимальный)

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

ОСИ КАК РАЗНЫЕ ГОРОДА

Windows — это мегаполис. Со своими обычными проблемами. Экология, пробки... преступность, наконец. Живя на первом этаже, не забудь нацепить решётки на окна. Не стоит также шляться ночью по тёмным подворотням — наверняка ограбят.
С другой стороны, для активной жизни — самое подходящее место. Вести ли бизнес, зарабатывать ли наёмным работником — здесь больше всего возможностей и денег. Для людей с самыми экзотическим запросами найдутся какие-нибудь клубы, секции, курсы, периодические издания и так далее. А разнообразием перверсий, девиаций и половых извращений здесь и вовсе никого не удивить.

Mac OS X — cонный немецкий городок с размеренной жизнью. Жители хором утверждают, что в мегаполисе жить плохо, что там экология, пробки и преступность, а живущие там только за баблом и гоняются. И ещё они бездуховные извращенцы и «у нас никогда такого не будет». С «духовностью» в городке и правда неплохо — порнографии особой не завозят (мэр города не одобрил), из развлечений — наиболее прозаические, просмотр футбола в баре да парочка гольф-клубов для эстетов.
Правда, в последнее время в городок провели от мегаполиса скоростной поезд, поэтому некоторые жители втайне от соседей укатывают на выходные в мегаполис, покутить и потрахаться. С другой стороны, многие жители мегаполиса, из поведённых на экологии, подумывают о переселении в городок (тем более — поезд же есть), а некоторые уже и переселились и работают удалённо.

Linux — соцлагерь как он есть. Обилие декларируемых лозунгов о «пролетариях всех стран». Уверяют, что только у них человеку дадут всё необходимое для жизни бесплатно — еду, квартиру, медицину и образование. На поверку еда окажется колбасой за 2.20, квартира — прохудившейся хрущёвкой, а в медицинской и образовательной сферах будут заседать исключительно лопатомордые бюрократы. Тех, кто посмеет заикнуться о недостатках такого образа жизни, обзовут наймитом и буржуазным прихвостнем, пропесочив на товарищеском суде — «да разве за то наши деды воевали, чтобы ты тут буржуазную икру требовал?».
Выбор из десятков сортов колбас в зарубежных супермаркетах решительно осуждают. «One task — one program». Колбаса должна быть одна, сыр должен быть один, хлеб тоже должен быть один, еду каждый сам себе готовит из перечисленных компонент. Готовые блюда — излишество, недостойное идеологически подкованного гражданина. Рестораны — вообще отвратительно, ведь блюда там проприетарные и состав их плохо известен.
Тем не менее, многие тайком дома содержат видеомагнитофон и коллекцию плейбоев, а также время от времени любят кататься в «ближнее зарубежье». Впрочем, это не мешает им предаваться на работе любимому занятию — выяснять, кто из них больше всего предан делу партии, а также ругать «капиталистических леммингов» и мечтать о пролетарской революции во всём мире. Каждая новость о создании новой, самой мощной в мире ядерной боеголовки, с радостью воспринимается ими как весть о приближающемся конце буржуазного мира. И так уже двадцать лет.

понедельник, 24 января 2011 г.

Магазин на СПО

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

http://dnc-soft.ru/

Установка GoogleEarth в UBUNTU


Код:
sudo apt-get install googleearth-package
sudo make-googleearth-package  --force
sudo dpkg -i ./googleearth_имя_получившегося_архива.deb

воскресенье, 23 января 2011 г.

Удаление старых ядер Ubuntu


Наверное вы заметили, что каждый раз, когда при обновлении Ubuntu устанавливается новое ядро, старое не удаляется. Таким образом, с каждым установленным новым ядром системы загрузочное GRUB меню разрастается. Это сделано для того, чтобы вы могли загрузиться со старым ядром если у вас возникли проблемы с новым, свежеустановленным после обновления. Но если проблем с новым ядром не возникло, и вы можете загрузиться с ним, то надобность в старом ядре отпадает. В этом случае его можно удалить.
Кроме того, исходники старых ядер хранятся в разделе /boot на вашем жестком диске и занимают место. К примеру, у меня под раздел /boot было выделено 100 мегабайт, и я думал, что этого будет достаточно, но при обновлении ядра место закончилось, так как в разделе /boot у меня уже хранилось несколько старых ядер системы, оставшихся после предыдущих обновлений.
Поэтому я рекомендую удалить старые ядра. Сделать это можно следующим образом:
1. Для начала выясним текущую версию вашего ядра, для этого наберите в терминале:
uname -r
Вы увидите что-нибудь типа этого:
2.6.24-19-generic
2. Откройте Менеджер пакетов Synaptic из меню Система -> Администрирование, нажмите кнопку «Найти» и в поле поиска наберите:
linux-image-2
После поиска отобразится полный список всех имеющихся ядер. Зеленое поле слева от названия показывает, что пакет установлен. Только одно ядро требуется для правильной работы системы. Теперь вы можете удалить все старые неиспользуемые ядра, выбрав их и отметив для полного удаления.

Как устроить DoS атаку на сервер баз данных одной строчкой

40 МБит / сек — неплохой трафик для DoS атаки. Именно на столько внезапно вырос входящий трафик до одного из наших серверов. Сайт мужественно держался. Время начала всплеска аномально высокого трафика подозрительно точно совпадало с временем выкладывания одного крупного релиза, что и навело на мысль о том что мы DoS`им себя сами.

Ситуацию осложняло то, что в релиз попали изменения порядка сотни разных php-файлов и просмотреть весь список изменений было очень трудоёмко. tcpdump помог выяснить что трафик вырос до сервера баз данных PostgreSQL. Круг сужался.

Первым предположение было то что в одном из SQL-запросов забыли limit и он выбирает весь набор данных вместо одной строки. Но как узнать что это за запрос? На помощь пришёл pgFouine. Анализ лога работы сервера баз данных за две минуты и вот он — источник зла!

select oid,typname from pg_type

Вот он — запрос без limit`а, который выполнялся тысячи раз. Но в наших исходниках не было этого запроса! Нигде, ни в одном файле он не встречался.

Источник проблемы скрывался в php-функции pg_field_type, которая всего навсего возвращала символьное имя типа колонки результата выборки.

Проблема уходит своими корнями как минимум в 2005 год но до сих пор в официальной документации не добавлено замечание о то, что библиотека php-pgsql для доступа к PostgreSQL делает дополнительный запрос к СУБД выбирая полный список из более чем 1000 типов данных.

Возможно на редко посещаемом сайте это совсем не сказывается на быстродействии, но на нагруженном проекте это может создать серьёзную проблему. Мы обошли проблему, использовав вместо функции pg_field_type её аналог pg_field_type_oid, которая возвращает внутренний oid типа данных вместо его символьного имени. Да, это немного ухудшило читабельность кода, но разгрузило канал до сервера баз данных на 40 МБит.

Возможно если бы мы использовали True FastCGI, то у нас бы не было это проблемы, но php стал готов к этому всего несколько месяцев назад, а проблема существует уже около 6 лет.

Поищите в ваших исходниках по ключевому слову pg_field_type — возможно вы сможете очень облегчить тяжёлую жизнь вашего сервера PostgreSQL.

Мой подход к проектированию веб-сайтов

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

В рамках данной статьи я поделюсь своим опытом проектирования сайтов средней сложности. Данный подход зарекомендовал себя понятным как разработчикам, так и клиентам. Я не собираюсь открывать Америку, представленные ниже инструменты всем прекрасно знакомы. Суть данной статьи как раз в том, что бы продемонстрировать насколько просто можно представить достаточно сложные задачи.




Всё начинается с…


Существует два варианта начала работы над проектом: идеальный и неидеальный.

картинка тут, да1) Идеальный вариант подразумевает, что заказчик представляет контору, которая знает, чего хочет достичь, и имеет на руках подготовленное ТЗ. Изучить, внести незначительные коррективы и благополучно реализовать всегда намного проще, чем вытягивать у клиента эту информацию.

2) «Неидеальный вариант» обычно хочет, что бы всё летало, в каждом углу были анимированные часики, но при этом никак не может определиться что же за информацию необходимо разместить на сайте. А нам ведь совсем не нужен вариант, что в середине работы мы вдруг узнаем, что подробный каталог продукции, который мы обсуждали и уже практически реализовали технически, на самом деле будет статической страничкой с прайс-листами, а всё, что нам так усердно рассказывал заказчик — это внутренняя структура прайс-листов, которую мы и не увидим никогда! Для того, что бы избежать данных трений, с такими заказчиками приходится совместно заниматься разработкой технического задания.
Но текст является не лучшим способом преподнесения информации, а главное не самым интуитивным. Поэтому прежде, чем задокументировать в строчках будущий проект бывает неплохо его доступно проиллюстрировать и обсудить.

… И тут на помощь приходят они!

Mindmap, создаем структуру сайта


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

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

Пример 1:
image

На данной схеме приведена структура неповторимого сайта DevSite, который отличается от всех своей уникальностью и новаторской структурой.

Описание схемы:
  • элементы желтого цвета — это сущности, физические разделы сайта
  • элементы серого цвета — условные разделы для группировки в нем элементов (раздел Пользователи)
  • черные прямоугольники — функциональные элементы страницы, которые несут за собой некоторую логики или действия
  • восстановление пароля в разделе пользователи является всплывающим окном или вы уже догадались?


Пример 2:
image

Использование таких иконок довольно полезно для изображения среза, текущего состояния проекта или постановки задачи, отображая текущее состояние дел.
Кстати для построения карт я использую XMind, которая предоставляет все вышеперечисленные плюшки, рекомендую посмотреть.

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

БД


Проектирование базы данных – тот этап, куда заказчик не суется, но это не значит, что стоит относиться к этапу со словами “мы 100 раз это делали, нам и так всё ясно”. Когда ведешь проект красиво, работа над ним приносит намного больше положительных эмоций и не превращается в рутину.

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

Ну и конечно же не малую роль играет удобство, лично мне намного приятнее слепить БД в софте типа MySQL Workbench и экспортировать результат в SQL, предварительно проставив связи, ключи свойства и визуально проверив результат. В любом случае это намного удобнее, чем самый распространенный способ заполнения БД в phpMyAdmin

Скрин таблицы из MySQL Workbench
image

Прототипирование, создание wireframe’ов


Этот этап довольно накладен и прибегать к нему стоит тогда, когда это действительно нужно. В основном имеет смысл на сайтах и сообществах с большими объемами информации, а так же на страницах с большим количеством управляющих элементов. Часто имеет смысл прибегнуть к созданию wirefram’ов для отдельных элементов системы, как например системы фильтрации и гибкого поиска или наоборот для очень общих элементов, таких как расположение больших блоков на сайте (меню, контент, столбцы, думаю понятно).

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

image
Скриншот с tarekshalaby.com по наводке google image search

В качестве инструмента не буду советовать какой-то конкретный, так как сам ещё окончательно не определился. Лично приходилось работать с настольным приложение Balsamic Mockups и веб-сервисом Hotgloo. Hotgloo конечно интересен тем, что можно сделать макеты с переходом по ссылкам и пародиями на такие действия как “положить товар в корзину”, но мне не очень нравится его ценовая политика, а иногда просто удобнее использовать настольное приложение.

image
Скриншот с оффсайта Balsamic Mockups

В Заключение


Данная статья ориентирована в первую очередь на небольшие веб-студии, менеджеров и руководителей проектов, отдельных фрилансеров, занимающихся веб разработкой или участвующих в цепочке разработки. Как видно простой подход с использованием mindmap’ов позволяет не просто разложить структуру, а сделать постановку задачи более наглядной для её исполнителей, отразив как текущее состояние, так и свойства, представленных в структуре сущностей. Но, как ни странно, этот стандартный заложенный в софт функционал зачастую остается незамеченным и невостребованным. Обидно!

Способы «защиты» flash-приложений

Здравствуйте. Я попытаюсь рассказать о нескольких способах защиты от исследования кода, мошенничества и воровства, используемых при разработке flash-приложений, а также о том, как можно обойти некоторые из них.
Стоит заметить, что сейчас существует немало отличных презентаций и работ на эту тему (см. ссылки в конце статьи), однако, я бы хотел немного подробней расписать некоторые нюансы, и объединить множество информации по теме в одном месте. По крайней мере, я постараюсь это сделать.


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


— введение


В мире flash (речь, конечно, о клиенте) не существует гарантированной защиты от злоумышленников, можно лишь отсеять совсем незадачливых и усложнить работу тем, кто решит идти до конца. Стремиться стоит к тому, чтобы стоимость и время работы недоброжелателя были как можно выше, а Ваши затраты — как можно меньше. В идеале старайтесь добиться того, чтобы злоумышленнику было проще, быстрее и дешевле купить или написать с нуля, чем обходить Ваши препятствия.

Борьба между системами защиты и системами обхода\снятия защит ведётся постоянно. Это связано с тем, что любому желающему доступна спецификация формата SWF и байткода (тут, здесь и ещё тут), в который компилируется ActionScript3 (далее AS3) код. Это позволяет свободно писать собственные библиотеки и приложения для разбора SWF файлов на составляющие (графику, звуки, байткод и т.д.), и делать что угодно с байткодом, например:
  • писать анализаторы байткода для декомпиляции ABC (ActionScript ByteСode) файлов, которые можно найти в тэгах "DoABC" в скомпилированном AS3 SWF файле (а в AS2 код обычно находится в тэгах "DoAction" и "DoInitAction");
  • писать приложения, модифицирующие байткод, например, для его обфускации с помощью различных приёмов, которые могут использовать специфику декомпиляции в своих целях;
  • писать приложения, позволяющие изменять (патчить) байткод в уже скомпилированных SWF файлах;
  • модифицировать FP для вывода (трейса) исполняющегося байткода;
В области защиты бывают разные цели и средства. Выбирайте только то, что подходит для Вашего проекта, не занимайтесь лишней работой.


— содержание


Мы рассмотрим несколько способов (они разные не только по своей реализации, но и по целевому назначению) с примерами обхода некоторых из них, а также ряд инструментов, которыми можно пользоваться при исследовании (своего) кода:
  1. URL-Lock (привязка к одному или нескольким доменам), защита от локального запуска
  2. Переменные, ресурсы и классы
  3. Водяные знаки (watermarks)
  4. "Упаковывание" SWF
  5. Динамическая генерация кода и редактирование SWF
  6. Запутывание кода (obfuscation) и скрытие данных
  7. Защита от сохранения SWF файла из памяти
  8. Инструментарий исследователя flash

— 1. URL-Lock, защита от локального запуска


Цель – заставить SWF файл работать в определенных условиях, например, только под одним или несколькими доменами, либо запретить локальный запуск.
После определения того факта, что SWF запущен не там, где должен бы, можно запрограммировать его поведение как угодно. Вы можете отправлять на сервер неугодные домены\URL (если это не localhost) и заносить в какой-нибудь лог.
Подлинные домены (под которыми должен работать SWF файл) лучше держать в зашифрованном виде или не держать в клиенте вообще (принимать от сервера также в зашифрованном виде).
Рассмотрим несколько способов привязки к доменам и определения локального запуска.

Привязка к доменам с помощью получения текущего URL\домена


Это самый распространённый способ привязки к домену. Для получения текущего URL или домена обычно используют:

а) loaderInfo:
  • root.loaderInfo.url (_root._url – для AS2) – содержит путь до самого SWF файла, если SWF загружен с помощью другого SWF, то root.loaderInfo.url у загруженного SWF останется прежним
  • root.loaderInfo.loaderURL – содержит путь до самого SWF файла, либо до его загрузчика, если он был загружен с помощью другого SWF файла
  • root.loaderInfo.loader — содержит ссылку на экземпляр класса Loader, либо null, если SWF не был загружен внешним загрузчиком (заметьте, что root.loaderInfo.loader == root.parent, а root.parent == stage, если SWF не имеет загрузчика). Причём, если загрузчик не находится в доверенной зоне (находится в другом SecurityDomain), то при обращении к root.loaderInfo.loader или к root.parent из загружаемого SWF, будет возникать исключение SecurityError, в сообщении которого также будет содержаться ссылка до загрузчика
Пути не изменятся, если SWF встроить в HTML страницу на "неродном" домене без перемещения самого SWF файла.

б) LocalConnection: позволяет получить имя домена, под которым в данный момент запущен SWF файл с помощью LocalConnection.domain.
Если чужой SWF находится в домене, отличном от домена Вашего SWF, и Вы загрузили тот SWF в текущий домен безопасности так:
var context:LoaderContext = new LoaderContext(true);
context.securityDomain = SecurityDomain.currentDomain;
loader.load(new URLRequest(url), context);
или с помощью Loader.loadBytes, то LocalConnection.domain загруженного SWF будет содержать домен Вашего SWF.
Пути не изменятся, если SWF встроить в HTML страницу на "неродном" домене без перемещения самого SWF файла.

в) ExternalInterface: позволяет использовать JavaScript (далее JS). Например, путь до текущей страницы, в которую встроен SWF, можно получить с помощью window.location.href. Для вызова JS используйте ExternalInterface.call. Т.к. call в качестве первого параметра принимает название метода, а window.location.href – свойство, то следует использовать toString():
var myHTMLUrl:String = ExternalInterface.call("window.location.href.toString");
Кстати, домен тоже можно получить через ExternalInterface.call:
var domain:String = ExternalInterface.call ("eval", "document.domain");

ExternalInterface можно использовать и для вызова своих JS функций на той странице, где находится SWF – как изначально существующих, так и созданных Вами с помощью eval:
var customJavaScriptCode:String = "function customJS(){alert('Yes, this is a custom JS');}";
ExternalInterface.call("eval", customJavaScriptCode);
ExternalInterface.call("customJS");
И не стоит забывать, что этот способ требует выполнения JS, что не всегда возможно.
При попытке обойти с помощью встраивания в HTML страницу на "неродном" домене без перемещения самого SWF файла, выполнение ExternalInterface.call будет генерировать SecurityError.

г) FlashVars: иногда, при размещении SWF в HTML страничке или при загрузке из другого SWF, передают путь до домена и\или иные данные через FlashVars (что на самом деле – плохо, т.к. это явная "дыра" для отвязки от доменов):

FlashVars можно передать в качестве параметра:

<object ...>
 <param name="FlashVars" value="var1=value1&var2=value2" />
</object>
или через имя файла:
<object ...>
 <param name="movie" value="somecoolmovie.swf? var1=value1&var2=value2" />
</object>
Дотянуться до FlashVars можно так:
— в AS3 – root.loaderInfo.parameters.var1
— в AS2 – _root.var1

Привязка к доменам без получения текущего URL или домена


Этот способ основан на кроссдоменной политике безопасности. Привязываемый SWF при запуске пытается загрузить по прямому пути "специальный" файл-пустышку с определённого хоста, на котором находится файл crossdomain.xml с разрешением загрузки ресурсов только с доверенных доменов, на одном из которых и должен находиться SWF. Соответственно, если "ворованный" SWF файл будет обращаться к "специальному" файлу с домена, не прописанного в crossdomain.xml, произойдет нарушение изолированной среды (sandbox security violation) и "специальный" файл не загрузится. Также при этом сгенерируется исключение и сработает событие SecurityErrorEvent.SECURITY_ERROR у экземпляра класса LoaderInfo (Loader.contentLoaderInfo). Это позволит определить то, что SWF находится не там, где должен бы.
К "специальному" файлу следует обращаться по прямому пути, чтобы предотвратить его подмену.

Определение локального запуска


Локальный запуск SWF можно определить с помощью получения ссылки на SWF или HTML и проверки её на наличие подстроки "file://".
Если SWF запущен вне HTML, то метод ExternalInterface.call вернёт null.
Также можно проверить тип FP, в котором работает SWF, с помощью Capabilities.playerType:
  • "ActiveX" – при проигрывании через ActiveX FP, который, например, используется в IE
  • "Desktop" – для среды выполнения Adobe AIR (кроме SWF-содержимого, загруженного HTML страницей, со свойством Capabilities.playerType имеющим значение "PlugIn")
  • "External" – при проигрывании через внешний FP или при запуске из-под Flash Professional IDE
  • "PlugIn" – при проигрывании через браузерный плагин (и для SWF-содержимого, загруженного HTML страницей в AIR приложении)
  • "StandAlone" – при проигрывании через автономный FP (при запуске локального SWF файла в браузерах, значение Capabilities.playerType != "StandAlone")
Ещё один способ – с помощью сравнения Security.sandboxType с Security.REMOTE.

Все эти приёмы имеют свои преимущества и недостатки — некоторые не требуют сервера, но требуют перекомпиляции SWF файла при изменении доменов, к которым должна осуществляться привязка, а некоторые — наоборот.
В кодах к статье (ссылка на архив есть в конце статьи), в папке "1-URL Lock", вы найдёте пример с реализацией некоторых из описанных методов и пару примеров патчей одного из методов.
Внимание! Большинство приёмов URL-Lock можно обойти, работая из-под локального сервера, такого, как Denwer или XAMPP.


— 2. Переменные, ресурсы и классы


Обычно о переменных и ресурсах заботятся при написании игр. Конечно, лучше держать важную логику, данные и переменные вне клиента, но, увы, такая возможность есть не всегда, поэтому, иногда следует думать о том, как сократить количество лазеек для жульничества.
Подменой ресурсов и классов пользуются не так часто, как редактированием переменных, но всё-таки пользуются, поэтому, я попробую рассказать, как это делают и как этому можно помешать (защититься от этого невозможно).

Защита переменных


Переменные надо прятать и защищать от изменений. Наиболее простой способ скрытия – написание своих "обёрток" вокруг базовых классов.
Например, CryptInt, CryptString и т.д. В самих классах можно написать методы для получения и отдачи значения, шифруя или расшифровывая его, что спрячет переменную в памяти. Взгляните на реализацию классов CryptInt и CryptString в кодах к статье, в папке "2-Memory&Domain\MemoryExample".
Также, для сокрытия значений переменных, можно разбивать их на составляющие, перемешивать, сдвигать и т.д. Можно даже попробовать написать некий конвейер, который будет перемещать скрываемое значение из одних переменных в другие, освобождая использованные переменные для GC (Garbage Collector). В качестве "временных хранилищ" для таких вот перерабатываемых переменных, можно использовать ByteArray, возможно, с привлечением "Алхимии" (fastmem из Azoth, Memory из Apparat).
А чтобы переменные не смогли поменять, даже если их найдут, то можно использовать, например, сравнение значения переменной с эталоном. Причём сравнение можно производить как при изменении переменной или обращении к ней, так и через заданные промежутки времени.

Подмена ресурсов


Подменить SWF целиком, либо подгружаемые внешние файлы можно в кэше браузера. В фальшивом SWF файле, или в подменённом ресурсе могут быть произведены любые изменения графики (размеры, прозрачность, сдвиг, частота кадров и т.д.) и кода (который делает то, чего бы вам меньше всего хотелось).
Чтобы усложнить задачу недоброжелателю (гарантированно защититься от подмены нельзя), следует проверять подлинность загружаемых данных и самого себя – можно, например, хранить MD5 и сравнивать при загрузке, причем MD5 хранить где-нибудь подальше и в зашифрованном виде.
Если SWF общается с сервером – производить скрытые проверки – отсылать на сервер MD5 загружаемых ресурсов, например.

Если есть возможность, то, для предотвращения подмены, внешние SWF и иные ресурсы можно хранить в теле основного SWF в зашифрованном виде и загружать их с помощью Loader.loadBytes, предварительно достав их из себя. Loader.loadBytes не сохраняет загружаемые данные в кэш браузера, но, в то же время, Ваш главный SWF будет закэширован. Подробнее об использовании Loader.loadBytes в таких случаях написано в одном из следующих разделов статьи.
Также можно запрашивать ресурсы и другие SWF файлы с сервера, лежащие в зашифрованном виде, далее расшифровывать их и загружать через Loader.loadBytes.

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


Скажу сразу, что гарантированно от этого защититься также не получится.
Подменять классы можно с помощью загрузки целевого SWF в ApplicationDomain загрузчика. Чтобы это сделать, можно написать загрузчик, содержащий класс с таким же именем, что и у подменяемого, и загрузить SWF в свой домен:
var appDomain:ApplicationDomain = ApplicationDomain.currentDomain;
var swfLoader:Loader = new Loader();
swfLoader.load(new URLRequest('original.swf'), new LoaderContext(false, appDomain));
Таким образом, загружаемый SWF вынужден будет "общаться" с классом из своего загрузчика. Примеры реализации Вы сможете посмотреть в кодах к статье, в папке "2-Memory&Domain\applicationDomain". Вы встретите там примеры подмены классов с помощью загрузки в дочерний и в свой домен. В "жертве" Вы сможете найти несколько вариантов проверки на загруженность (которые обходятся заменой класса, в котором они содержатся).
Можно попытаться воспрепятствовать этому, загружая основной SWF через собственный загрузчик в новый ApplicationDomain:
var appDomain:ApplicationDomain = new ApplicationDomain(null);
var swfLoader:Loader = new Loader();
swfLoader.load(new URLRequest('original.swf'), new LoaderContext(false, appDomain));
и установив прочную связь между загрузчиком и основным SWF так, чтобы их было очень трудно "разлучить". Однако, если подменят загрузчик и сумеют эту связь сохранить, то эти усилия будут напрасны.

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


— 3. Водяные знаки (watermarks)


Могут использоваться для защиты от копирования, нелегального использования, а также в рекламных целях.

Вот некоторые их типы:

  1. Хорошо заметные элементы: текст, логотип, изображение и т.д.
    Если метка "впаяна" (относится как просто к изображениям, так и к графике в SWF), то её удаление придётся осуществлять вручную, редактируя данные, которые подверглись применению метки, что может оказаться очень сложной или вовсе невыполнимой задачей.
    Если же метка лежит отдельно (либо добавляется программно), например, на самом верхнем "слое" в SWF, то шансы аккуратно её удалить гораздо выше.
  2. Скрытые элементы. Они могут быть где угодно. От таких водяных знаков зачастую невозможно избавиться, т.к. никто кроме их создателей не будет знать, где искать. Такие метки должны быть уникальными, дабы была возможность доказать в суде, что это действительно метки, и что их невозможно повторить.
Этот пункт получился весьма ущербным, однако, сказать тут больше особо нечего, просто не забывайте, что такие средства защиты тоже существуют.


— 4. "Упаковывание" SWF


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

Вы можете добавить SWF в свой flex или flash проект с помощью тэга Embed, например, так:
[Embed(source = "./dummy.swf", mimeType = "application/octet-stream")]
private var _content:Class;
Добавленный таким образом файл (это может быть любой двоичный файл или несколько файлов, если тэгов Embed будет несколько) помещается в тэг DefineBinaryData.
Далее можно загрузить "упакованный" таким образом файл с помощью Loader.loadBytes примерно так:
var someFile:ByteArray = new _content();
loader.loadBytes(someFile);
Существует масса инструментов для разбора SWF файлов и манипуляции с тэгами, благодаря которым существует возможность заменять или добавлять тэг DefineBinaryData.
Зная всё это, можно набросать свой простой "упаковщик" для автоматизации процесса. Перед оборачиванием, SWF можно как-нибудь преобразовать, например, обработав простым и быстрым симметричным xor’ом, а в загрузчике (который будет содержать "упакованный" SWF) написать код, который будет расшифровывать хранящийся в нём SWF, и уже затем его загружать. Простое "шифрование" с помощью xor нужно лишь для защиты от автоматической обработки декомпиляторами, чтобы SWF файл не находился внутри загрузчика в "чистом виде", более сложное шифрование бессмысленно.
Бывает, файлы "внедряют" и другими способами, например, в виде BitmapData, а также, создают несколько уровней вложенности.

Пример реализации простейшего упаковщика Вы сможете найти в кодах к статье, в папке "3-SWFPacker". Также там лежат два файла: orig.swf и packed.swf – можете попробовать их декомпилировать и сравнить.
Этот способ обходится, как минимум, двумя путями:
— исследование алгоритма расшифровщика в загрузчике и написание собственного расшифровщика (трудоёмко, особенно при большой вложенности загрузчиков)
— сохранение участка памяти, в котором находится уже распакованный и загруженный в FP SWF файл (просто и быстро, особенно, если не использованы средства защиты от сохранения из памяти, о которых написано ниже)



— 5. Динамическая генерация кода и редактирование SWF


Меня уже неоднократно спрашивали – возможно ли во flash в реальном времени генерировать код или создавать и редактировать другие SWF файлы? Ответ – да, это возможно!
Что касается кода, попробуйте AS3Commons ByteCode. Этот проект позволит Вам собирать и выполнять в реальном времени байткод.
Вы можете создавать классы с различными методами и свойствами с нуля, или наследуясь от других классов. Тела методов, например, могут описываются с помощью байткода линейно — methodBuilder.addOpcode(Opcode.getlocal_0), или сразу блоками:
var source:String = (<![CDATA[
    getlocal_0
    pushscope
 ...
    getlocal_1
    returnvalue]]>).toString();
methodBuilder.addAsmSource(source);
Вы можете загрузить сгенерированный код в AVM с помощью abcBuilder.buildAndLoad().
Также для манипуляций с байткодом Вы можете попробовать as3abc, который, по словам автора, является частичным портом замечательного framework’а Apparat от небезызвестного Joa Ebert’а.
Если же Вы мечтаете о динамическом исполнении скрипта, а не байткода, то посмотрите на as3scriptinglib. Используя этот проект, Вы сможете в реальном времени компилировать и выполнять ActionScript 3/ECMAScript скрипты, включая JavaScript. Посмотреть на то, как это работает можно во flex демо-приложении. К сожалению, проект давно не обновляется.

Для экспериментов с самим SWF файлом и его структурой, попробуйте as3swf или swfassist.

Возможность генерации кода на лету, а также возможности редактирования и создания SWF в реальном времени, позволяют создавать различные сложные сценарии и приёмы для запутывания злоумышленника и скрытия Вашего кода. Вот, например первые 3 приёма, что пришли мне на ум:
  1. Генерировать и исполнять код\байткод на клиентской стороне по частям, приходящим от сервера, оставляя недоброжелателям в оригинальном SWF из всего кода, лишь то, что Вам не жалко им оставить (код свободных библиотек, кнопок и т.д.) + код расшифровщика и "строителя" уже финального кода.
  2. Собирать SWF по частям на клиентской стороне, аналогично трюку с кодом – можно собирать по тэгам, получая их от сервера, или, распаковывая поодиночке из зашифрованных данных, упакованных в загрузчике.
  3. Создавать самомодифицирующийся в процессе исполнения код, который, например, будет по определённым правилам или шаблонам генерировать одни и те же методы разными способами. Например, i++ можно реализовать как i+=1 (и это будет разный байткод, по крайней мере, он сейчас разный, в FP 10.1), также циклы могут быть реализованы по-разному, и т.д.
    Возможно, удастся так исхитриться, чтобы сгенерированный код изменял те методы, которые его сгенерировали. Например, чтобы в следующей итерации их выполнения сгенерировались уже другие классы и методы, тем самым значительно усложняя и запутывая код, чтобы, в случае его получения злоумышленником, последнему пришлось потратить как можно больше времени на разбор всей этой "каши".
    Предполагаю, что это довольно сложный (или даже невозможный во flash) трюк. Реально работающей реализации этой идеи на flash я пока не встречал. Если Вы встречали – то подскажите где посмотреть, буду рад изучить.

— 6. Запутывание кода (obfuscation) и скрытие данных


Сначала об обфускации. Ей могут подвергаться как исходный так и скомпилированный в байткод код. Обфускация исходного кода не так удобна и эффективна, запутывание байткода выглядит куда как привлекательней, т.к. исходный код должен удовлетворять требованиям компилятора, чего не скажешь о байткоде, в котором, к тому же, есть куда больший простор для проявления фантазии и смекалки.
Байткод обфускация может включать в себя переименование элементов в бессмысленные и недопустимые для компилятора имена, использование некоторых анти-декомпиляторских трюков, скрытие и "замусоривание" кода и др.

Переименование — это, пожалуй, единственный необратимый и 100% работающий способ хоть что-то спрятать во flash. Суть метода заключается в изменении у методов, свойств, пакетов и других элементов имён, которые сохраняются после компиляции, но не используются при выполнении кода. Автоматически восстановить оригинальные имена невозможно, придётся это делать вручную, догадываясь о них по смыслу во время исследования кода. После обфускации новые имена могут содержать недопустимые символы или зарезервированные слова, что не позволит с лёгкостью перекомпилировать и использовать код, полученный после декомпиляции.

Иногда при обфускации байткода расставляют "ловушки" для декомпиляторов, основанные на том, что декомпиляторы анализируют код комплексно, блоками, в отличие от FP, который исполняет его линейно, например:
  • Некорректный "мёртвый код" — создаётся искусственный условный переход, который всегда отрабатывает только одну ветку. Таким образом, во второй ветке мы имеем код, который никогда не выполнится, но будет обрабатываться декомпиляторами. И если там что-то непредсказуемое (а мы можем сделать там что угодно, т.к. FP до туда никогда не доберётся), то некоторые декомпиляторы могут повести себя необычно – например, аварийно завершиться.
  • Непредсказуемые байты в тех областях, которые игнорирует FP, но которые не всегда игнорируют и корректно обрабатывают декомпиляторы.
Кроме того, код можно просто "замусорить", увеличив его в объёмах и снизив его читабельность. Это может негативно сказаться на производительности.

Скрытие данных можно осуществлять разными способами, например:
  • Скрытие в SWF тэгах. Как я уже говорил, можно использовать flex-тэг Embed для встраивания любых файлов в SWF тэг DefineBinaryData, однако, можно создать и SWF тэг своего типа (FP такие тэги просто пропускает) с любыми данными, и затем извлекать их во время выполнения с помощью самораспарсивания.
    Пример есть в файлах к статье, в папке "4-CustomTag" — там находится проект на основе уже упомянутой библиотеки as3swf (изменён класс com.codeazur.as3swf.factories.SWFTagFactory и добавлен com.codeazur.as3swf.tags.TagCustom). При запуске, SWF проверит — нет ли уже в нём нового тэга, и если есть — то выведет текст из него в текстовое поле, а если тэг не найдётся, то создаст сам в своей копии новый тэг со строкой, загрузит получившийся SWF в себя же с помощью Loader.loadBytes() и ещё предложит сохранить его в новый SWF файл.
  • Пользовательские мета данные. Для внедрения своих метаданных, сначала их необходимо объявить в коде (можно перед объявлением класса, метода, переменной):
    package
    {
        [FocusMeta(name="secret", data="123")]
        public class Dummy
        {
            [Cool(key="another secret")]
            public var dummyInt:int;
            public var dummyStr:String;
        }
    }
    А затем добавить их названия в "Additional compiler arguments" таким образом: -keep-as3-metadata+=FocusMeta,Cool. После этого, Вы сможете обращаться к своим мета данным через XML, который можно получить с помощью describeType():
    var typeXML: XML = describeType(Dummy);
    var myMeta: XMLList = typeXML.factory.metadata.(@name == "FocusMeta");
Некоторые декомпиляторы и дизассемблеры позволяют с лёгкостью находить и исследовать пользовательские тэги и метаданные.

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


— 7. Защита от сохранения SWF файла из памяти


Гарантированно защититься от дампа из памяти нельзя. Однако, есть несложный приём, который может усложнить процесс – можно создать множество фальшивых SWF-заголовков (именно по ним обычно ищут SWF файлы в памяти), которые помогут оригинальному SWF затеряться среди них. Чтобы Ваш SWF файл не выделялся на фоне других, можно создать массу фальшивых заголовков с размерами = размерам Вашего SWF файла.
Чтобы заголовки были видны в памяти, достаточно записать их в ByteArray. Вот пример реализации этого способа, вытянутый из загрузчика одного из протекторов:
private function spamMemory(swfBytes:ByteArray):void
{
    var allLen:uint = swfBytes.readUnsignedInt();
    var swfLen:uint = swfBytes.readUnsignedInt();
    var spamMemorySWFLen:uint = swfBytes.readUnsignedInt();
    var spamMemorySWFBytes:ByteArray = new ByteArray();
    spamMemorySWFBytes.endian = Endian.LITTLE_ENDIAN;
    swfBytes.readBytes(spamMemorySWFBytes, 0, spamMemorySWFLen);
    var allBytes:ByteArray = new ByteArray();
    while (allBytes.length < allLen) 
    {
        spamMemorySWFBytes.position = 4;
        spamMemorySWFBytes.writeUnsignedInt((((swfLen * 3) / 4) + ((Math.random() * swfLen) / 2)));
        allBytes.writeBytes(spamMemorySWFBytes);
    };
    Sprite.prototype["__spam_"] = allBytes;
}
Как Вы могли догадаться, swfBytes – это массив байт с началом "шаблонного" заголовка и "настройками" для создания "фальшивых" заголовков, а в цикле длина у "шаблонных" заголовков заполняется случайным значением в заданном диапазоне.


— 8. Инструментарий исследователя flash


Основываясь на собственном опыте, я бы порекомендовал эти инструменты (цены указаны на конец 2010 года):

Декомпиляторы:
  • Action Script Viewer (ASV) – умно анализирует код, строит timeline, видит все тэги, очень многое умеет. Стоимость лицензии на одного пользователя – $80.
  • AS3 Sorcerer (от разработчика ASV) – декомпилирует только код, для анализа кода используется движок ASV, работает быстро и очень качественно. Если Вы приобретали ASV в 2010 году, то лицензию на AS3 Sorcerer Вам предоставят бесплатно. Стоимость лицензии с бесплатными обновлениями на 3 месяца — $22.
  • Sothink SWF Decompiler – можно пользоваться на незащищённых проектах, если под рукой не оказалось ASV. Стоимость лицензии — $79.99.
Дизассемблеры (для работы с байткодом):
  • ASV и Sothink умеют показывать байткод, но этого не всегда достаточно.
  • Nemo440 – "Advanced ActionScript 3/ABC2/Flex 2/Flex 3/Flex 4/AIR disassembler". Бесплатен.
  • Yogda – "AVM2 bytecode workbench" – позволяет ассемблировать, патчить байткод, есть встроенная документация по байткоду, иногда падает при анализе защищённых SWF, однако периодически обновляется и обрастает функционалом. Бесплатен.
  • RABCDAsm – "Robust ABC (ActionScript Bytecode) [Dis-]Assembler" – замечательный консольный ассемблер\дизассемблер байткода. Бесплатен (+доступен исходный код).
Протекторы\обфускаторы:
  • secureSWF — из всей массы продуктов этой категории, что мне удалось попробовать, он единственный сумел качественно позаботиться о целостности и работоспособности всех подопытных приложений и при этом качественно выполнить свою основную задачу. Конечно же, не бывает идеальных продуктов в этой области, но secureSWF даёт очень хороший контроль над всем процессом защиты и позволяет тонко настроить различные параметры. Например, Вы можете настроить переопределяющие правила для переименования, установить уровень "замусоривания" кода и т.д. В самой дорогой редакции, Вы получаете также возможность "упаковывать" SWF или привязать её к домену. К сожалению, цена на этот продукт весьма высока: стоимость Standard редакции составляет $199.
  • irrFuscator — может Вам приглянуться за его возможности по обфускации исходного кода перед компиляцией, однако, я считаю, что такой подход значительно хуже по своему качеству, чем байткод обфускация, т.к. не позволяет использовать запрещённые компилятором символы и различные трюки с байткодом. Этот продукт также умеет работать на уровне байткода, но проекты, которые я пробовал им "накрывать" довольно часто оставались неработоспособными. Стоимость Standard редакции составляет 79 евро.
  • OBFU – пожалуй, это самый дорогой обфускатор для flash, который мне доводилось видеть (стоимость – 1500 евро). Автор обфускатора — Николя Канасье, создатель haXe. Не ясно – поддерживает ли он AS3, т.к. примеры, выложенные на сайте проекта, написаны на as2 и датированы 2005 годом. К сожалению, попробовать его в действии мне пока не довелось, поэтому если вдруг Вы его когда-то пробовали, то не поленитесь, напишите отзыв о нём в комментариях.
Также прошу обратить внимание, что Amayeta SWF Encrypt, DComSoft SWF Protector, Mochi Encryption – это не то, чем Вам стоило бы "защищать" свои проекты (на данный момент), вы потратите Ваши деньги на бесполезную защиту.
Более того, Вы можете и самостоятельно реализовать простейшую обфускацию, как, например, это сделано в примере от makc3d.

Депротекторы\декрипторы и т.д.:
  • SWF Reader – проект одного польского умельца — многофункциональный редактор, позволяет работать со структурами, тэгами и т.д. Также имеет встроенные декрипторы\депротекторы для некоторых известных продуктов (в частности, распаковщики для doSWF, secureSWF). Cтоимость лицензии – 10 евро.
  • SWF Decrypt – поможет Вам избавиться от Amayeta SWF Encrypt и DComSoft SWF Protector (Mochi Encryption также в планах разработчика). Бесплатен.
Разное:
  • SWiX – отличная утилита для редактирования тэгов SWF файла в удобном XML представлении. Бесплатна.
Если Вы знаете иные, действительно заслуживающие внимания инструменты, и готовы о них рассказать, то рассказывайте в комментариях или пишите лично, буду рад с ними познакомиться.


— эпилог


Резюмируя, можно сказать, что, умело пользуясь подручными средствами для защиты своих проектов, Вы сможете отсеять некоторую аудиторию злоумышленников. Однако, если за исследование вашего SWF файла возьмётся профессионал, то, вероятно, он не остановится перед препятствиями и доведёт дело до конца, особенно, если он мотивирован интересной задачей или достаточным денежным вознаграждением. Поэтому всегда здраво оценивайте свой вклад в защиту своих проектов – не тратьте на это слишком много времени и средств, если это того не стоит.
И ещё — не компилируйте SWF с отладочной информацией, т.к. она содержит множество полезных потенциальному взломщику данных, не говоря уже о снижении производительности.

Спасибо, что прочитали этот нелёгкий для восприятия материал. Надеюсь, Вы нашли что-то новое для себя. Любые пожелания, замечания и конструктивные предложения Вы можете оставить в комментариях, буду Вам весьма благодарен.

Материалы для изучения и источники информации для этой статьи (беспорядочно):
  1. Презентация Claus Wahlers "Hacking SWF" с FITC Amsterdam 2010.
  2. Доклад Симонова Валентина (valyard) "Кто и как взламывает наши игры" с FlashGAMM 2010
  3. Статья Никиты Лещенко на английском о том, как по-простому защитить ресурсы и код, используя шифрование.
  4. Статья от romamik "Защита своими руками".
  5. Статья от Nautilus "Как защитить вашу игру от ребрендинга".
  6. Статья от puzzlesea "Robolander, 25 days later. Защита, борьба с китайцами".
  7. Статья от flashco "Обфускаторы: от бесплатного до €1500".
  8. Alexis' SWF Reference — описание тэгов всех версий формата, описание заголовка SWF файла и многое другое.
  9. OWASP – в некотором роде вики по вопросам безопасности, относящихся к flash (ссылки на статьи, инструменты и т.д.).
  10. Очень впечатляющая статья о модели безопасности во flash от senocular под названием "Security Domains, Application Domains, and More in ActionScript 3.0".
  11. Статьи от Adobe о безопасности во flash.
  12. Официальная статья от Adobe о безопасности во FP 10 (White Paper).
Также в данной статье и кодам к ней могут быть использованы различные материалы из неуказанных тут источников, о которых я не вспомнил.

Файлы к статье: codestage.ru/files/flash_defend_files.7z

Очень много полезных штук для AS3 #1

Недавно в моей RSS ленте сразу несколько людей написало о большой подборке всяких штук для AS3, которые могут изрядно упростить жизнь Flash-разработчикам. Одним из таких людей был injun (чей блог я читаю уже очень давно), в его посте я увидел ссылку на исходный пост одного зарубежного автора, и решил сам посмотреть, что там к чему.

Изначально, я хотел опубликовать все ссылки в рамках одной статьи, но ссылок оказалось слишком много, и статью придётся разделить на несколько частей. В этой статье мы разберём 3D движки, 3D игровые движки, 2D игровые движки, изометрические движки, 3D фреймворки для анимации, 3D физические движки, библиотеки для дополненной реальности, твиннеры (движки для программной анимации). Итак, понеслась.



3D движки


Papervision3D
Away 3D
Sandy 3D
Alternativa Platform
FIVe3D
WireEngine3D (we3d) — «лёгкий» и быстрый 3D движок для 8/9 версии Flash.
Sharikura
Infinity3d (русский разработчик детектед).
AS3Dmod
ND3D — маленький и «лёгкий» 3D движок для AS3.
Flare3D — позволяет экспортировать файлы из Autodesk’s 3DSMax и потом контролировать их, используя AS (коммерческий).
noob3d
Adobe ”Molehill”
Sophie 3D

3D игровые движки


PaperWorld 3D
Yogurt3D

2D игровые движки


Citrus Engine — платформенный игровой движок, заточенный под игры с горизонтальной прокруткой (Sidescrolling — уж не знаю, как правильнее этот термин перевести на русский язык).
FlashPunk — быстрый и «чистый» фреймворк для прототипирования и разработки игр. По-моему, этот движок заточен на векторную графику. И его даже рекомендует создатель движка flixel (см. ниже) на своём сайте, как альтернативу flixel, если кому-то flixel не понравился по какой-то причине.
flixel — коллекция AS3 файлов, который помогают организовывать, автоматизировать и оптимизировать разработку Flash-игр. Создатель этого движка — разработчик «нашумевших» в некоторых кругах игр Canabalt и Gravity Hook. К слову, эти игры были сделаны на движке flixel. Не знаю, как для кого, но для меня, это веский повод попробовать движок в «деле».
PixelBlitz Engine — игровой фреймворк для AS3.
PushButton Engine — open-source движок и фреймворк, разработанный для нового поколения игр (это был перевод исходного текста). От себя замечу, что я уже публиковал несколько переводов вводных статей по этому движку. К сожалению, после вводных статей у меня не было желания дальше продолжать что-то разрабатывать на PushButton Engine, так как, на мой взгляд, вся его «система модулей» добавляет в код неразберихи.

Изометрические движки


as3isolib — open-source AS3 библиотека для изометрии.
FFilmation — по-моему этот проект мёртв, а последняя запись касающаяся движка датирована августом 2009 года.
isoengineas3
OpenSpace — коммерческий движок для изометрии, который работает в связке с SmartFoxServer
Sean Cooper Isometric Engine — коммерческий движок от известного разработчика Sean Cooper. Кстати, этот проект, тоже «мёртв» и никогда не был по-настоящему жив, так как в блоге проекта только 1 запись и та датируется 4 февраля 2010.
TheoWorlds — коммерческий движок.
T.I.L.E. (Tangerine Isometric Level Editor) — коммерческий (на странице проекта нужно кликнуть на кнопке TECH). По-моему, тоже коммерческий.

В своё время, мне, по ходу своей работы нужно было изучить текущий рынок изометрических движков и, на мой взгляд, из всех представленных движков и библиотек обратить внимание стоить только на as3isolib и OpenSpace. Первый — потому что он бесплатный, а второй, потому что работает в связке с SmartFoxServer, который может значительно упростить разработку многопользовательских приложений.

3D фреймворки для анимации


Cast3D

3D физические движки


WOW-Engine
jiglibflash

Дополненная реальность


FLARToolkit
FLARManager

Твиннеры (движки для программной анимации)


Desuade Motion Package — в оригинальной статье пишется, что это — «прорывная» библиотека, которая комбинирует покадровую анимацию, физику и tween-анимацию.
TweenNano — как TweenLite, только размером в 1.6 килобайт и с некоторым «обрезанным» функционалом.
TweenLite
TweenMax
TimelineLite
TimelineMax
Tweener
Tweensy
TweensyZero — «облегчённая» версия Tweensy.
GoASAP (ActionScript Animation Platform)
AS3 Animation System 2.0
Animation Package
KitchenSync
Gyro – A tween and animation library for ActionScript 3.
gTween
HydroTween + HydroSequence (based on GoASAP)
Twease
BetweenAS3
ByteTween
Eaze
Actuate
grape-as3 — библиотека для программной анимации, основанная на «путях». По-моему интересная штука, можно графически задать путь движения объекта.
RabbitTween
Tweaser – The anti-tween engine
NanoTween

Лично я, в основном, использую TweenLite, так как оно прост в использовании и помогает мне решать подавляющее большинство задач связанных с программной анимацией. Когда его не хватает, приходится использовать TweenMax, но это случается крайне редко. Из остальных движков, на мой взгляд, интересен grape-as3, так как позволяет задавать нестандартную траекторию движения объектам.

P.S.: если статья будет полезна другим, то в следующий раз мы разберём 2D физические движки, библиотеки для «защиты» данных, библиотеки для работы со звуком, системы для работы с частицами, библиотеки для загрузки данных, ООП фреймворки и многое другое =)

среда, 19 января 2011 г.

установка webmin'а

Установка для систем с менеджером пакетов rpm (Redhat, Fedora, CentOS):
su
cd /tmp
wget http://prdownloads.sourceforge.net/webadmin/webmin-1.530-1.noarch.rpm
rpm -U webmin-1.530-1.noarch.rpm





Установка для систем с менеджером пакетов dpkg (Debian, Ubuntu, kUbuntu):
sudo -i
cd /tmp
aptitude install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl libmd5-perl libapt-pkg-perl apt-show-versions
wget http://prdownloads.sourceforge.net/webadmin/webmin_1.530_all.deb
dpkg -i webmin_1.530_all.deb








Установка на FreeBSD до 7.1 из системы портов
su
make -C /usr/ports/sysutils/webmin install clean
cd /usr/local/lib/webmin && ./setup.sh'''

* Отвечаем на все вопросы, которые задаёт программа конфигурации. Не обращаем внимания на warning'и.
* Внести запись в /etc/rc.conf: webmin_enable="YES"
* Запуск программы: /usr/local/etc/rc.d/webmin start





Установка на FreeBSD 7.1 и старше из системы портов
su
portinstall webmin
cd /usr/local/lib/webmin && ./setup.sh

* Отвечаем на все вопросы, которые задаёт программа конфигурации. Не обращаем внимания на warning'и.
* Внести запись в /etc/rc.conf: webmin_enable="YES"
* Запуск программы: /usr/local/etc/rc.d/webmin start

asoundrc + разделение звука на компьютер и телевизор

создайте файл ~/.asoundrc с таким содержанием:

pcm.dshare {
type dmix
ipc_key 2048
slave {
pcm "hw:0"
rate 44100
period_time 0
period_size 1024
buffer_size 8192
channels 4
}
bindings {
0 0
1 1
2 2
3 3
}
}
pcm.frontx {
type plug
slave {
pcm "dshare"
channels 4
}
ttable.0.0 1
ttable.1.1 1
}
pcm.rearx {
type plug
slave {
pcm "dshare"
channels 4
}
ttable.0.2 1
ttable.1.3 1
}



speaker-test -t wav -c 2 -Dfrontx
speaker-test -t wav -c 2 -Drearx




для smplayer
alsa:device=frontx
alsa:device=rearx

для vlc
vlc --alsa-audio-device frontx
vlc --alsa-audio-device rearx

понедельник, 17 января 2011 г.

установка unity-2d в ubuntu

sudo add-apt-repository ppa:unity-2d-team/unity-2d-daily
sudo apt-get update
sudo apt-get install unity-qt-default-settings
для тестирования окружения в дисплейном менеджере для новой сессии необходимо выбрать оболочку "Unity Qt".

воскресенье, 16 января 2011 г.

Доступ из Windows к Ext2/Ext3/Ext4

Ext2Read (Ext2explore)

Очистить историю Центра Приложений Ubuntu

sudo rm /var/log/apt/history.log*

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

0000 – Понравиться коллегам просто

Будь проще, одевайся по скромней, не делай вида а-ля компиляторный император, шути и люди к тебе потянуться. Автор оригинала дает совет: поставь на свой рабочий стол коробку с конфетами и все сразу будут с тобой дружить. Вроде неплохой способ, но русский человек за халяву любые деньги заплатит, так что если Вы готовы быть спонсором всех чаепитий, то без проблем =)

0001 – Заработать уважение коллег трудно

Можно конечно одевать на работу каждый день медаль из школы, носить в папке грамоты за победы в турнире «Акварельная кисточка» в 6,7,9-ом классах, проговаривать по слогам БА-КА-ЛА-ВРРР или при встрече с коллегой смачно щелкать 3-мя пальцами и выставлять указательный, направляя на коллегу. Но все это не прибавит Вам авторитета. Только последовательно, эффективно и аккуратно выполняя свою работу, Вы можете быть признаны коллективом как работник.

0010 – Все что Вы узнали в институте – бесполезно

Это надо понять и принять. Я думаю, все прекрасно понимают о чем я и разводить тему насчет нашего образования не хочу. Просто скажу, что институт дает, но иногда не то и не в тех областях.

0011 – Never stop learning

Я даже переводить не стал. Век живи, век учись… программированию =).

0100 – Выберите редактор

Сомнительный пункт, в котором автор говорит, что Вам стоит найти самого крутого программера в офисе и посмотреть, где он колбасит свой код. Так же автор высказывает отрицательно мнение насчет всяких IDE и предпочитает обычные текстовые редактор с подсветкой. Имхо, это выбор каждого, и выбор уже должен был сформироваться до работы. Единственное, что стоит подсматривать за тем, как работают старшие коллеги и в чем.

0101 – Никто не будет волноваться по поводу того, что Вы закончили

С одной стороны автор прав. Если ты реально умеешь кодить, то неважно что ты заканчивал и где учился. С другой стороны, хороший ВУЗ плохих (было много вариантов, остановился на плохих) специалистов не выпускает. Спорно? Бесспорно. В итоге, имхо, все сводится к твоим знаниям, бумаги важны, но только не в ИТ, где дефицит раб.силы на сегодняшний день.

0110 – Не знаешь о чем говорить – молчи

Завести новых друзей, войти в круг доверия =) не просто. Нужно искать точки соприкосновения по интересам. В любом случае, решая рабочие задачи, Вы войдете в группу коллег и Вам придется с ними общаться, а пока просто молчите =) и делайте свою работу.

0111 – Не все люди примут Вас с распростертыми объятьями

Некоторые примут Вас с распростертыми проклятьями. Это все понимают, что ужиться со Всеми не реально. Надо быть выше всех этих заморочек, бороться с не «добрыми людьми» и валить из конторы, если все очень плохо.

1000 – Пытайтесь подружиться

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

1001 – Вы будете подчиняться политике компании

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