
Скриншот программы 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". Перезапустим программу и введем на этот раз его. Триальная надпись мгновенно исчезнет, а водяные знаки при сохранении изображений также пропадут. То есть программа успешно зарегистрирована.

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