Исследование защиты программы TopStyle 4


Скриншот программы TopStyle 4

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

Для работы нам потребуется дистрибутив последней версии 4.0.0.62 и дизассемблер. Устанавливаем, запускаем. Налицо все признаки триальности: надпись "Trial" в заголовке программы, триальные надписи и ссылка на покупку в окне About, сообщения об ограничениях в редакторе и еще целая куча подобных прелестей.


Триальные надписи в окне "О программе"

Смотрим исполняемый файл. По характерным названиям секций визуально определяем, что он накрыт ASPack. Анализаторы исполняемых файлов это подтверждают.


Файл упакован ASPack

Распаковываем его или вручную, или с помощью инструментов типа QuickUnpack или Abstersiver, проверяем работоспособность после распаковки и загоняем в дизассемблер. Файл достаточно большой, так что времени на его полную обработку тоже уйдет немало. Когда дизассемблер закончит работу, начнем поиски "нехороших строк" и ссылающегося на них кода.


"Нехорошая строка"

Ссылающийся на строчку код:
...
.text:008F0E77 loc_8F0E77:
; Вызов функции проверки регистрации
.text:008F0E77                 call    sub_8F0C3C
.text:008F0E7C                 test    al, al
; Если она вернула 1, то программа зарегистрирована
.text:008F0E7E                 jnz     short loc_8F0E8D
.text:008F0E80                 lea     eax, [ebp+var_4]
; Ссылка на строку "trial mode (unregistered)"
.text:008F0E83                 mov     edx, offset aTrialModeUnreg
.text:008F0E88                 call    sub_405A00
.text:008F0E8D
.text:008F0E8D loc_8F0E8D:
.text:008F0E8D                 cmp     [ebp+var_4], 0
...

Забиваем в начало процедуры по адресу 008F0C3C команды MOV AL,1; RET, запускаем, строка пропала. Но все остальные триальные признаки остались. Поищем другой признак, например, строку "Trial" в заголовке:
...
; Вызов функции проверки регистрации
.text:0096FB17                 call    sub_96F968
.text:0096FB1C                 test    al, al
.text:0096FB1E                 jnz     short loc_96FB2D
.text:0096FB20                 lea     eax, [ebp+var_4]
; Ссылка на строку "Trial"
.text:0096FB23                 mov     edx, offset aTrial ; " Trial"
.text:0096FB28                 call    sub_405C60
.text:0096FB2D loc_96FB2D:
.text:0096FB2D                 mov     eax, ebx
.text:0096FB2F                 call    sub_9749F0
.text:0096FB34                 test    eax, eax
...

Смотрим процедуру по адресу 0096F968 и видим, что она точно такая же! Не та же, а точно такая же. Пропатчиваем ее таким же образом, надпись в заголовке пропала. Попробуем теперь поискать по сигнатуре все аналогичные процедуры проверки. Сразу скажу, что их будет около полутора десятков, в этом плане автор явно большой шутник. Запускаем и видим, что внешние триальные признаки пропали, но через секунду после открытия главного окна появляется сообщение "TopStyle failed a data integrity check, which means either that an error occurred while downloading or that the EXE has been tampered with. Please download this program again." и программа закрывается. Значит еще присутствует проверка целостности кода. Давайте поищем ее. Строка сообщения об ошибке содержится в ресурсах с индексом 0FCEFh, а ссылающийся код сделан в виде такой конструкции:
.text:00581E70 off_581E70      dd offset hInstance
.text:00581E74                 dd 0FCEFh ; <-- наш индекс

В свою очередь на эту конструкцию ссылается указатель в сегменте данных:
.data:009E8764 off_9E8764      dd offset off_581E70

А вот на этот указатель ссылается уже 5 процедур, и снова все они однотипные:
.text:00972E44                 push    ebp
.text:00972E45                 mov     ebp, esp
.text:00972E47                 xor     ecx, ecx
.text:00972E49                 push    ecx
.text:00972E4A                 push    ecx
.text:00972E4B                 push    ecx
.text:00972E4C                 push    ecx
.text:00972E4D                 push    ecx
.text:00972E4E                 push    ecx
.text:00972E4F                 push    ebx
.text:00972E50                 mov     ebx, eax
.text:00972E52                 xor     eax, eax
.text:00972E54                 push    ebp
.text:00972E55                 push    offset loc_972EFD
.text:00972E5A                 push    dword ptr fs:[eax]
.text:00972E5D                 mov     fs:[eax], esp
.text:00972E60                 push    ebx
.text:00972E61                 lea     edx, [ebp+var_4]
; Здесь выводится окно с сообщением о нарушении целостности, после этого
; программа закрывается
.text:00972E64                 mov     eax, off_9E8764
.text:00972E69                 call    sub_408254
.text:00972E6E                 mov     eax, [ebp+var_4]
.text:00972E71                 push    eax
.text:00972E72                 lea     eax, [ebp+var_10]
.text:00972E75                 call    sub_9AF3E0
.text:00972E7A                 mov     eax, [ebp+var_10]
.text:00972E7D                 mov     [ebp+var_C], eax
.text:00972E80                 mov     [ebp+var_8], 0Bh
.text:00972E84                 lea     edx, [ebp+var_C]
.text:00972E87                 xor     ecx, ecx
.text:00972E89                 pop     eax
.text:00972E8A                 call    sub_40F35C
.text:00972E8F                 push    10h
.text:00972E91                 lea     eax, [ebp+var_18]
.text:00972E94                 call    sub_9AF390
.text:00972E99                 mov     eax, [ebp+var_18]
.text:00972E9C                 lea     edx, [ebp+var_14]
.text:00972E9F                 call    sub_40E3A4
.text:00972EA4                 mov     eax, [ebp+var_14]
.text:00972EA7                 call    sub_405E24
.text:00972EAC                 push    eax
.text:00972EAD                 mov     eax, [ebx]
.text:00972EAF                 call    sub_405E24
.text:00972EB4                 mov     edx, eax
.text:00972EB6                 mov     eax, off_9E8518
.text:00972EBB                 mov     eax, [eax]
.text:00972EBD                 pop     ecx
.text:00972EBE                 call    sub_4E86E0
.text:00972EC3                 mov     eax, off_9E70DC
.text:00972EC8                 mov     dword ptr [eax], 17h
.text:00972ECE                 mov     eax, off_9E8518
.text:00972ED3                 mov     eax, [eax]
.text:00972ED5                 call    sub_4E85E0
.text:00972EDA                 xor     eax, eax
.text:00972EDC                 pop     edx
.text:00972EDD                 pop     ecx
.text:00972EDE                 pop     ecx
.text:00972EDF                 mov     fs:[eax], edx
.text:00972EE2                 push    offset loc_972F04
.text:00972EE7 loc_972EE7:
.text:00972EE7                 lea     eax, [ebp+var_18]
.text:00972EEA                 mov     edx, 3
.text:00972EEF                 call    sub_40598C
.text:00972EF4                 lea     eax, [ebp+var_4]
.text:00972EF7                 call    sub_405968
.text:00972EFC                 retn
.text:00972EFD loc_972EFD:
.text:00972EFD                 jmp     loc_4050F8
.text:00972F02                 jmp     short loc_972EE7
.text:00972F04 loc_972F04:
.text:00972F04                 pop     ebx
.text:00972F05                 mov     esp, ebp
.text:00972F07                 pop     ebp
.text:00972F08                 retn

Уже зная повадки автора, можно предположить, что и здесь все было сделано простым копированием исходников. А поскольку процедура не содержит условных переходов и просто выводит окно с сообщением, то надо смотреть код, который ее вызывает.
...
; Тут какая-то движуха с вычислениями с плавающей запятой
.text:00972FB2                 call    sub_48AEE8
.text:00972FB7                 fstp    [ebp+var_10]
.text:00972FBA                 wait
.text:00972FBB                 push    dword ptr [ebp+var_10+4]
.text:00972FBE                 push    dword ptr [ebp+var_10] ; double
.text:00972FC1                 call    sub_410F28
.text:00972FC6                 add     esp, 0FFFFFFF8h
.text:00972FC9                 fstp    [esp+74h+var_74]
.text:00972FCC                 wait
; Какая-то функция проверки
.text:00972FCD                 call    sub_8856EC
.text:00972FD2                 cmp     eax, 3
; Этот условный переход надо пропатчить на безусловный
.text:00972FD5                 jl      short loc_97300B
; Этот код выполняется, когда проверка целостности не пройдена
.text:00972FD7                 mov     [ebp+var_1], 1
.text:00972FDB                 lea     eax, [ebp+var_18]
; Вызвать окно с сообщением об ошибке
.text:00972FDE                 call    sub_972E44
.text:00972FE3                 lea     eax, [ebp+var_28]
.text:00972FE6                 mov     dl, 1
.text:00972FE8                 call    sub_41B710
.text:00972FED                 lea     edx, [ebp+var_28]
...

По очереди смотрим все участки кода и заменяем условные переходы, которые предшествуют вызовам сообщений об ошибке целостности. Таких участков будет пять. Сохраняем изменения, запускаем. Все работает как часы.
Теги:
защита, взлом
Добавлено: 21 Сентября 2013 02:33:01 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...