Blog. Just Blog

Исследование защиты программы Sothink SWF Decompiler

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы Sothink SWF Decompiler
Скриншот программы Sothink SWF Decompiler

Sothink SWF Decompiler от компании SourceTec Software - одна из лучших программа для декомпиляции Flash-файлов в формате SWF и Flash EXE, извлечения из них ресурсов, скриптов, графики, музыки, восстановления исходных кодов проектов и т.д. Незаменимый инструмент при изучении чужих разработок и восстановления своих исходников в случае их утери. Было бы странным предполагать, что авторы будут распространять такую прелесть "за красивые глазки", так оно и есть, стоимость Sothink SWF Decompiler почти 80 вечнозеленых денег.

Скачиваем дистрибутив и устанавливаем его. Предварительный анализ исполняемого файла показывает, что он упакован навесным протектором Armadillo. Для распаковки воспользуемся программой ArmaGeddon. К сожалению, она пока не работает под Windows 7, так что придется запускать ее под какой-нибудь виртуальной машиной с установленной Windows XP.

Распаковываем файл
Распаковываем файл

В логе видно, что для защиты использованы почти все опции, но ArmaGeddon успешно с ними справляется. Через несколько секунд получаем распакованный файл размером почти в два раза превышающий исходный. Попробуем немного сократить размер, удалив из него уже ненужные секции протектора. Сделать это можно при помощи программы CFF Explorer, которая входит в состав Explorer Suite.

Удаляем из файла секции протектора
Удаляем из файла секции протектора

В нашем случае не использовалась опция протектора, когда имена секций заменяются на случайный набор символов, это немного облегчит работу. Секции протектора имеют имена, похожие на имена оригинальных секций, но с добавлением в конец цифры, к тому же они идут подряд: .text1, .adata, .data1, .pdata. Отрезайте их по одной, предварительно сделав резервную копию распакованного файла и проверяя каждый раз работоспособность полученного файла. Опытным путем установлено, что безболезненно можно отрезать секции .text1, .adata, .pdata, после чего файл сразу "похудел" наполовину. Загоняем его в дизассемблер и вернемся к теории. Протектор Armadillo предоставляет функции регистрации защищаемых программ своими средствами. Для взаимодействия с защищаемой программой используются переменные окружения, в которые записываются данные об имени пользователя, ключе регистрации (если он найден в системе), триальном времени работы, количестве одновременно запущенных копий и другую информацию. Эти переменные имеют неизменные имена, значит их можно поискать в файле.

Найдены имена переменных окружения
Найдены имена переменных окружения

Имена переменных найдены, они хранятся в файле в юникоде. Переменная EXPIRED устанавливается, когда триальный срок закончился, в переменной DAYSLEFT записано количество оставшихся дней, USERKEY содержит регистрационный ключ, если он установлен. Подробнее о наименованиях переменных и их значениях можете почитать в документации к Armadillo, если интересно, нас же интересует только переменная USERKEY. Посмотрим, где и как она обрабатывается.
  1. ; Процедура проверки переменной окружения USERKEY. Возвращает EAX=1,
  2. ; если такая переменная установлена (т.е. программа зарегистрирована),
  3. ; и EAX=0, если нет.
  4. .text:00446310                 sub     esp, 20Ch
  5. .text:00446316                 mov     eax, dword_9F18B8
  6. .text:0044631B                 xor     eax, esp
  7. .text:0044631D                 mov     [esp+20Ch+var_4], eax
  8. .text:00446324                 push    esi
  9. .text:00446325                 mov     esi, [esp+210h+arg_0]
  10. .text:0044632C                 push    104h            ; nSize
  11. .text:00446331                 lea     eax, [esp+214h+Src]
  12. .text:00446335                 push    eax             ; lpBuffer
  13. ; Получить переменную окружения USERKEY
  14. .text:00446336                 push    offset aUserkey ; lpName
  15. .text:0044633B                 call    ds:GetEnvironmentVariableW
  16. .text:00446341                 test    eax, eax
  17. ; Такая переменная не установлена
  18. .text:00446343                 jbe     short loc_446387
  19. .text:00446345                 lea     eax, [esp+210h+Src]
  20. .text:00446349                 lea     edx, [eax+2]
  21. .text:0044634C                 lea     esp, [esp+0]
  22. .text:00446350 loc_446350:
  23. .text:00446350                 mov     cx, [eax]
  24. .text:00446353                 add     eax, 2
  25. .text:00446356                 test    cx, cx
  26. .text:00446359                 jnz     short loc_446350
  27. .text:0044635B                 sub     eax, edx
  28. .text:0044635D                 sar     eax, 1
  29. .text:0044635F                 push    eax             ; int
  30. .text:00446360                 lea     ecx, [esp+214h+Src]
  31. .text:00446364                 push    ecx             ; Src
  32. .text:00446365                 mov     ecx, esi
  33. .text:00446367                 call    sub_4024D0
  34. ; Переменная есть, установить флаг EAX=1
  35. .text:0044636C                 mov     eax, 1
  36. .text:00446371                 pop     esi
  37. .text:00446372                 mov     ecx, [esp+20Ch+var_4]
  38. .text:00446379                 xor     ecx, esp
  39. .text:0044637B                 call    sub_7BE489
  40. .text:00446380                 add     esp, 20Ch
  41. .text:00446386                 retn
  42. .text:00446387 ; -----------------------------------------------
  43. .text:00446387 loc_446387:
  44. .text:00446387                 mov     ecx, [esp+210h+var_4]
  45. .text:0044638E                 pop     esi
  46. .text:0044638F                 xor     ecx, esp
  47. ; Переменной нет, установить флаг EAX=0
  48. .text:00446391                 xor     eax, eax
  49. .text:00446393                 call    sub_7BE489
  50. .text:00446398                 add     esp, 20Ch
  51. .text:0044639E                 retn
  52. .text:0044639E sub_446310      endp
По перекрестным ссылкам смотрим, что эта процедура проверки вызывается из другой процедуры, которая в свою очередь вызывается уже как минимум из трех мест. Логично предположить, что основной процедурой, возвращающей признак "зарегистрировано" является именно родительская процедура. Под отладчиком видно, что флаг зарегистрированности возвращается в регистре EAX. Значит пропатчим родительскую процедуру, записав в ее начало команды MOV EAX,1; RET. Сохраняем изменения, запускаем программу. Стартовое наг-окно пропало. Теперь проверяем функционал программы. Оппа, при попытке декомпиляции любого ролика выдается следующее сообщение:

Собщение незарегистрированной программы
Собщение незарегистрированной программы

То есть какая-то дополнительная проверка регистрации выполняется где-то еще. Поищем строчку этого сообщения в исполняемом файле. Она найдется в ресурсах.

Строка сообщения в ресурсах
Строка сообщения в ресурсах

Код строки 302, или в шестнадцатеричном виде 12Eh. Поищем в дизассемблированном листинге строку "12Eh".
  1. ; Вызвать какую-то функцию проверки чего-то
  2. .text:00455C28                 call    sub_4466F0
  3. .text:00455C2D                 test    al, al
  4. ; Если она вернула AL=0, то окно с сообщением о незарегистрированной
  5. ; программе не выводить
  6. .text:00455C2F                 jz      short loc_455C5F
  7. .text:00455C31                 cmp     byte ptr word_9FD804+1, 0
  8. .text:00455C38                 jz      short loc_455C5F
  9. .text:00455C3A                 lea     eax, [esp+14h+var_10]
  10. ; Загрузить строку с кодом 302 (12Eh) из ресурсов
  11. .text:00455C3E                 push    12Eh
  12. .text:00455C43                 push    eax
  13. .text:00455C44                 call    sub_4629D0
  14. .text:00455C49                 mov     ecx, [esp+1Ch+var_10]
  15. .text:00455C4D                 add     esp, 8
  16. ; Вывести окно сообщения
  17. .text:00455C50                 push    0               ; int
  18. .text:00455C52                 push    41h             ; uType
  19. .text:00455C54                 push    ecx             ; int
  20. .text:00455C55                 call    ?AfxMessageBox@@YGHPB_WII@Z
  21. ; AfxMessageBox(wchar_t const *,uint,uint)
  22. .text:00455C5A                 cmp     eax, 1
  23. .text:00455C5D                 jnz     short loc_455C0D
  24. .text:00455C5F loc_455C5F:
На вывод окна влияет результат процедуры sub_4466F0, для активации нужной нам ветки алгоритма она должна вернуть EAX=0:
  1. .text:004466F0                 call    sub_445B50
  2. .text:004466F5                 mov     ecx, eax
  3. .text:004466F7                 call    sub_446690
  4. .text:004466FC                 neg     eax
  5. .text:004466FE                 sbb     eax, eax
  6. .text:00446700                 inc     eax
  7. .text:00446701                 retn
Что она делает? Первая процедура интереса не представляет, так как не влияет на результат, а вот вторая, sub_446690, как раз и проверяет по очереди установленные переменные навесной защиты - наличие ключа и окончание триального срока. Для обхода всей этой канители нужно, чтобы sub_446690 вернула EAX=1. Второй патч - записываем в начало sub_446690 команды MOV EAX,1; RET. Сохраняем изменения, запускаем. Все признаки триальности исчезли, программа работает на полную мощность. Цель достигнута. Очень похожим способом обходятся защиты и других программ SourceTec, хотя и со своими тонкостями.

Про наличие кейгенов для навесных защит Armadillo, в том числе и для программ SourceTec, я прекрасно знаю, но информация о способах и алгоритмах кейгенинга для широкой публики недоступна, да и без навесного протектора программы обычно работают гораздо шустрее.

Поделиться ссылкой ВКонтакте
Просмотров: 9261 | Комментариев: 19

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (03.03.2016 в 09:06):
AEV Injector
pawel97 (02.03.2016 в 18:31):
Сделал по-другому:
1( установил USERKEY Вашей замечательной утилитой EAV Injector;
2) запатчил одну из проверок, из-за которой родительская процедура возвращала 0 и ролики не сохранялись. Ищем вызов GetProcAddress, где аргументом передаётся имя функции GetUserString из библиотеки ArmAccess, чуть выше будет прыжок в самый конец процедуры, где обнаружится команда mov eax,edi - меняем на mov al,1. SWF Catcher и Editor вылечились аналогично. Шаблон для патча (дополнительно к переменной USERKEY):
Search:  EB 03 D6 D7 ?? 8B ?? ?? 8B C7
Replace: EB 03 D6 D7 ?? 8B ?? ?? B0 01
Попутно вопрос по арме: есть ли способы борьбы с Secured Sections без валидного ключа? Или хотя бы, если в закромах есть забаненный ключик к старой версии от какой-нибудь team, можно ли его разбанить?
ManHunter (17.02.2016 в 11:21):
Цитатаимена секций - это случайный набор символов

пару лет практики и все будет определяться на глаз

Цитатаполученное приложение запускается на секунд 20 и, затем быстро отключается, так и непоявившись на экране

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

Цитатасодержит цифровую подпись, которая после действий ArmaGeddon'а теряется и не отображается больше в свойствах файла

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

ЦитатаС этой программой понятно! А если взять другую

ожидал найти здесь Единый Ответ на Главный вопрос жизни, вселенной и всего такого? ну так это 42, это общеизвестно. а под каждую конкретную программу должно быть свое решение.
Андрей (17.02.2016 в 11:09):
С этой программой понятно! А если взять другую, например VideoReDo TVSuite v5.1.2.731 от DRD Systems ? Тут есть ряд сложностей: 1) после успешного снятия навесного протектора Armadillo v9.66 ArmaGeddon'ом v2.1 с главного приложения VideoReDo5.exe, имена секций - это случайный набор символов, что затрудняет выбор секций для их последующей обрезки, т.к. полученное приложение запускается на секунд 20 и, затем быстро отключается, так и непоявившись на экране; 2) Изначально главное приложение содержит цифровую подпись, которая после действий ArmaGeddon'а теряется и не отображается больше в свойствах файла.
brute (13.02.2015 в 10:17):
кстати, ArmaGeddon 1.9 на W7_32 у меня тоже не пашет (как и никакой другой), ну и ладно - XP всегда под рукой. При установке Sothink SWF Decompiler в папку с прогой кидаются два инсталятора:Sothink SWF Editor и SWFCatcher. Решил я их пролечить. Со снятием  армы и обрезкой секций .text1, .adata, .pdata, проблем нет. USERKEY запатчил  там где "процедура проверки вызывается.. вызывается уже как минимум из трех мест." Диалоговое окно исчезло. Найти второе окно не могу!!! Нет конструкций call/test и далее push/push/call. Ничего похожего. Возле push/push/call (которых десятки) нет джампов.. Есть ли какая метода поиска этих мест? Может, лучше пытаться не убрать  первое окно (патчить USERKEY), а пытаться отловить сообщение о неправильном серийнике? Или не обрезать секции армы и патчить ALTUSERNAME/USERNAME?
ManHunter (03.05.2011 в 01:06):
Прочитай статью про распаковщики раз пятьдесят до наступления полного просветления, должно помочь.
Антон (02.05.2011 в 22:55):
А все таки можно ли запустить армагеддон под виндовс 7 чтобы он работал. если да, то каким образом. скажите пожалуйста.
Sergey_K (25.03.2011 в 19:56):
ArmaGeddon 1.9 сам все снял, размер уменьшил как в статье, с галочка "Minimize Size" - ничего не вышло. Спасибо.
ManHunter (12.01.2011 в 07:26):
gluzden, да, умеет. Переключаешься на просмотр файла в юникоде (F8 - Unicode) и ищешь.
gluzden (12.01.2011 в 03:08):
А Hiew умеет и в юникоде искать? Давненько я не брал в руки шашек :)
AyTkACT (30.10.2010 в 22:11):
В ArmaGeddon'е есть же галочка "Minimize Size" так зачем ручками то секции прибивать? После галочки очень даже красиво получается ;)
Isaev (08.10.2010 в 23:56):
А мне про секции порадовало... Не знал что их так безболезненно можно убрать. И прога сразу настолько меньше! Приятно :)
ManHunter (08.10.2010 в 21:31):
Vovka, ну так напиши как правильно. Чем критиковать, публикуйте свой материал, делитесь своими знаниями, учите как надо делать. А по поводу использования тулз, так этак надо отказываться от IDA и HIEW, ImpRec и всего остального, будем дизассемблить в уме, и патчить напрямую на диске, так будет точно ТруЪ.
Vovka (08.10.2010 в 20:37):
Если честно, то нифига не информативный мануал, после распаковки чужой тулзой, пропатчить пару байтов это моветон.
Тут-же есть интересная фишка с Code Splicing! mov eax,1 вместо SetEnvironmentVariable, это тоже очень не правильно.
Isaev (07.10.2010 в 14:47):
и дело не в нём, а что ещё может считаться системным отладчиком?
у меня кроме DrWeb и HttpAnalyzer ничего не стоит

ах да, твой форум ещё открыт! :D

кстати бяка ещё одна живёт... видимо это как раз в ней дело
надо систему переставить
ManHunter (07.10.2010 в 14:38):
Значит у тебя гранаты не той системы :) Серьезно, не знаю в чем проблема, у меня работает без прикрытия.
Isaev (07.10.2010 в 14:37):
ArmaGeddon у меня 1.8, что ищет знаю, но ты его в статье не прикрывал ;)
ManHunter (07.10.2010 в 14:29):
Все прекрасно клеится. Попробуй ArmaGeddon 1.7 и выше, он армудилой не обнаруживается, на крайняк прикрой его чем-нибудь типа HideToolz, армудила ищет "системные отладчики" тупо по заголовкам окна.
Isaev (07.10.2010 в 14:27):
Интересная статья, только не всё клеится
"использованы почти все опции, но ArmaGeddon успешно с ними справляется."
что-то нифига он с ним не успешно справляется... Падает с сообщением:
"For security purposes, this program will not run while system debuggers are active. Please remove or disable the system debugger before trying to run this program again."

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0051 сек.) / Память: 4.5 Mb
Наверх