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


Скриншот программы MediaChance QuickHDR

QuickHDR от компании MediaChance - очень интересная программа для работы с HDR изображениями. Но в отличие от аналогичных программ, где для составления фотографии требуется несколько изображений с разной экспозицией, здесь нужно только одно изображение. На его основе и создается качественное изображение с различными HDR-эффектами. Вы можете выбрать эффекты как из предустановленных пресетов, так и самому настроить эффекты в точности как вам надо. Конечно, когда есть время и возможности, то лучше сделать полноценную серию кадров с различной экспозицией, но в реальных условиях это не всегда возможно. Так что программа QuickHDR окажется полезной, когда приходится "вытаскивать" одиночные изображения, имеющие слишком контрастные или слишком затемненные области.

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


Окно ввода серийного номера

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


Триальное сообщение

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


Подозрительная строка

А вот тут сразу две интересные строчки. Во-первых, строчка "Reg Code:". Очевидно, что она как-то относится к регистрационному коду, но при этом в диалоговых окнах ничего подобного нет. Во-вторых, строчка из серии нулей. Она находится в подозрительной близости от "Reg Code", а еще мне сложно представить, где она может применяться в графической программе, кроме как при проверке серийного номера. Посмотрим, какие участки кода ссылаются на них. Как ни странно, но это все находится в одной процедуре:
.text:0046AB50                 push    0FFFFFFFFh
.text:0046AB52                 push    offset SEH_46AB50
.text:0046AB57                 mov     eax, large fs:0
.text:0046AB5D                 push    eax
.text:0046AB5E                 mov     large fs:0, esp
.text:0046AB65                 sub     esp, 24h
.text:0046AB68                 push    ebx
.text:0046AB69                 push    esi
.text:0046AB6A                 mov     esi, ecx
.text:0046AB6C                 lea     eax, [esp+38h+arg_0]
.text:0046AB70                 lea     ecx, [esp+38h+var_30]
.text:0046AB74                 push    eax
.text:0046AB75                 mov     [esp+3Ch+var_4], 0
.text:0046AB7D                 call    sub_6776D3
.text:0046AB82                 mov     ebx, 1
.text:0046AB87                 lea     ecx, [esp+38h+var_30]
.text:0046AB8B                 mov     byte ptr [esp+38h+var_4], bl
.text:0046AB8F                 call    sub_67076E
.text:0046AB94                 lea     ecx, [esp+38h+var_30]
.text:0046AB98                 call    sub_670677
.text:0046AB9D                 mov     ecx, [esp+38h+var_30]
.text:0046ABA1                 mov     al, [ecx]
.text:0046ABA3                 cmp     al, 3Ah
.text:0046ABA5                 jnz     short loc_46ABD2
.text:0046ABA7                 lea     edx, [esp+38h+var_1C]
.text:0046ABAB                 push    ebx
.text:0046ABAC                 push    edx
.text:0046ABAD                 lea     ecx, [esp+40h+var_30]
.text:0046ABB1                 call    ?Mid@CString@@QBE?AV1@H@Z
.text:0046ABB6                 push    eax
.text:0046ABB7                 lea     ecx, [esp+3Ch+var_30]
.text:0046ABBB                 mov     byte ptr [esp+3Ch+var_4], 2
.text:0046ABC0                 call    sub_677A97
.text:0046ABC5                 lea     ecx, [esp+38h+var_1C]
.text:0046ABC9                 mov     byte ptr [esp+38h+var_4], bl
.text:0046ABCD                 call    sub_67795E
.text:0046ABD2 loc_46ABD2:
.text:0046ABD2                 push    offset aRegCode ; "Reg Code:"
.text:0046ABD7                 lea     ecx, [esp+3Ch+var_30]
.text:0046ABDB                 call    sub_670200
.text:0046ABE0                 test    eax, eax
.text:0046ABE2                 jnz     short loc_46AC10
.text:0046ABE4                 lea     eax, [esp+38h+var_1C]
.text:0046ABE8                 push    9
.text:0046ABEA                 push    eax
.text:0046ABEB                 lea     ecx, [esp+40h+var_30]
.text:0046ABEF                 call    ?Mid@CString@@QBE?AV1@H@Z
.text:0046ABF4                 push    eax
.text:0046ABF5                 lea     ecx, [esp+3Ch+var_30]
.text:0046ABF9                 mov     byte ptr [esp+3Ch+var_4], 3
.text:0046ABFE                 call    sub_677A97
.text:0046AC03                 lea     ecx, [esp+38h+var_1C]
.text:0046AC07                 mov     byte ptr [esp+38h+var_4], bl
.text:0046AC0B                 call    sub_67795E
.text:0046AC10 loc_46AC10:
.text:0046AC10                 push    edi
.text:0046AC11                 lea     ecx, [esp+3Ch+var_30]
.text:0046AC15                 call    sub_67076E
.text:0046AC1A                 lea     ecx, [esp+3Ch+var_30]
.text:0046AC1E                 call    sub_670677
.text:0046AC23                 push    offset a00000000000000
; "0000000000000000000"
.text:0046AC28                 lea     ecx, [esp+40h+var_30]
.text:0046AC2C                 call    sub_677D3A
.text:0046AC31                 lea     ecx, [esp+3Ch+var_20]
.text:0046AC35                 push    9               ; Size
.text:0046AC37                 push    ecx             ; int
.text:0046AC38                 lea     ecx, [esp+44h+var_30]
.text:0046AC3C                 call    sub_670166
...

Запустим программу под отладчиком и поставим точку останова в начало этой функции по адресу 0046AB50. Для теста снова введем какой-нибудь заведомо неправильный серийник, например, "1234567890987654321". Точка останова сработает сразу после ввода, на стеке при этом лежит указатель на введенный серийник. Пройдем эту процедуру в пошаговом режиме, при этом внимательно будем смотреть на то, как меняются указатели в регистрах и на значения указателей на стеке. В один из моментов там появится что-то такое:


Указатели на строчки в стеке

Что мы тут видим? Мы видим введенный серийный номер с дописанной к нему в конце группой нулей, первую часть серийного номера, вторую часть серийного номера и строчку "0021-7102". Ее мы точно не вводили, значит она сгенерировалась где-то в дебрях программы и скорее всего на основании введенных нами данных. В отладчике добираемся до следующего блока:
.text:0046AF4C                 mov     al, [ecx+1]
.text:0046AF4F                 mov     bl, [edx+1]
.text:0046AF52                 cmp     al, bl
.text:0046AF54                 jnz     loc_46AFEB
.text:0046AF5A                 mov     al, [ecx+2]
.text:0046AF5D                 mov     bl, [edx+2]
.text:0046AF60                 cmp     al, bl
.text:0046AF62                 jnz     loc_46AFEB
.text:0046AF68                 mov     al, [ecx+5]
.text:0046AF6B                 mov     bl, [edx+5]
.text:0046AF6E                 cmp     al, bl
.text:0046AF70                 jnz     short loc_46AFEB
.text:0046AF72                 mov     cl, [ecx+8]
.text:0046AF75                 mov     al, [edx+8]
.text:0046AF78                 cmp     cl, al
.text:0046AF7A                 jnz     short loc_46AFEB

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


Указатели на строчки в регистрах

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


Программа успешно зарегистрирована

Авторам спасибо за классную программу и за интересную защиту, а вам спасибо за внимание. Это был очередной пример сниффинга серийного номера, но желающие могут копнуть поглубже и даже написать генератор серийных номеров.
Добавлено: 14 Сентября 2013 01:00:56 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...