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

Софтовая компания Absolute Software делает программы, нацеленные на обработку мультимедийных файлов. Среди унылых стопицотдесятых реинкарнаций всяких конвертеров проскакивают неплохие решения, например Amazon DVD Shrinker, которым я частенько пользуюсь.


Скриншот программы Absolute Video to Audio Converter

Защита во всех программах однотипная, так что достаточно разобрать ее на примере одной из их программ. Пусть это будет Absolute Video to Audio Converter, программа для извлечения звуковых дорожек из видеофайлов. Пользовался несколько раз, впечатления хорошие. Для исследования нам конечно понадобится дистрибутив программы и отладчик. Правильные регистрационные данные мы будем находить уже известным способом "ловись рыбка большая и маленькая", то есть фишингом.

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


Строка найдена

Теперь найдем и посмотрим код, который на нее ссылается. Он понятен даже без моих комментариев, в дизассемблере имена библиотечных функций говорят сами за себя:
...
CODE:004D9B0C                 lea     edx, [ebp+var_4]
CODE:004D9B0F                 mov     eax, [ebx+314h]
; Прочитать в память введенные имя и серийный номер
CODE:004D9B15                 call    @Controls@TControl@GetText$qqrv
CODE:004D9B1A                 lea     edx, [ebp+var_8]
CODE:004D9B1D                 mov     eax, [ebx+318h]
CODE:004D9B23                 call    @Controls@TControl@GetText$qqrv
CODE:004D9B28                 mov     eax, ds:off_4E5BB0
CODE:004D9B2D                 mov     eax, [eax]
; В регистрах ECX и EDX содержатся указатели на имя и введенный серийник
CODE:004D9B2F                 mov     ecx, [ebp+var_8]
CODE:004D9B32                 mov     edx, [ebp+var_4]
; Интересующая нас процедура проверки серийного номера
CODE:004D9B35                 call    sub_4E1A34
; Если процедура вернула AL=0, то серийный номер введен неправильно
CODE:004D9B3A                 test    al, al
CODE:004D9B3C                 jz      short loc_4D9B6E
; Регистрация успешна, записать куда-то в реестр имя и серийник,
; поблагодарить за покупку, но это для нас уже интереса не представляет
CODE:004D9B3E                 mov     eax, ds:off_4E5BB0
CODE:004D9B43                 mov     eax, [eax]
CODE:004D9B45                 mov     edx, [ebp+var_4]
CODE:004D9B48                 call    sub_4E1BC4
CODE:004D9B4D                 push    40h             ; uType
                              ; "Congratulations!"
CODE:004D9B4F                 mov     ecx, offset aCongratulation
                              ; "Register successfully!  Thank you for y"...
CODE:004D9B54                 mov     edx, offset aRegisterSucces
CODE:004D9B59                 mov     eax, ds:off_4E5E40
CODE:004D9B5E                 mov     eax, [eax]      ; int
CODE:004D9B60                 call    @Forms@TApplication@MessageBox$qqrpxct1i
CODE:004D9B65                 mov     eax, ebx
CODE:004D9B67                 call    @Forms@TCustomForm@Close$qqrv
CODE:004D9B6C                 jmp     short loc_4D9B86
CODE:004D9B6E ; ---------------------------------------------------------
CODE:004D9B6E loc_4D9B6E:
; Сюда мы попадем в случае неудачной регистрации
CODE:004D9B6E                 push    40h             ; uType
CODE:004D9B70                 mov     ecx, offset aSorry ; "Sorry"
                              ; "Invalid user name or registration code!"
CODE:004D9B75                 mov     edx, offset aInvalidUserNam
CODE:004D9B7A                 mov     eax, ds:off_4E5E40
CODE:004D9B7F                 mov     eax, [eax]      ; int
CODE:004D9B81                 call    @Forms@TApplication@MessageBox$qqrpxct1i
CODE:004D9B86 loc_4D9B86:
CODE:004D9B86                 xor     eax, eax
CODE:004D9B88                 pop     edx
CODE:004D9B89                 pop     ecx
...

То есть процедура проверки серийного номера должна вернуть в регистре AL единицу в случае успешной регистрации и ноль если введенные данные ошибочные. Теперь посмотрим саму процедуру проверки. Ее можно просто пропатчить, чтобы она всегда возвращала 1, но тогда теряется весь интерес к исследованию. Пройдем по ней отладчиком в пошаговом режиме.
; Процедура проверки серийного номера. В принципе, можно пропатчить первые
; команды на MOV AL,1 - RET, но это как-то неспортивно :)
CODE:004E1A34                 push    ebp
CODE:004E1A35                 mov     ebp, esp
CODE:004E1A37                 add     esp, 0FFFFFFE4h
CODE:004E1A3A                 push    ebx
CODE:004E1A3B                 xor     ebx, ebx
CODE:004E1A3D                 mov     [ebp+var_C], ebx
CODE:004E1A40                 mov     [ebp+var_8], ecx
CODE:004E1A43                 mov     [ebp+var_4], edx
CODE:004E1A46                 mov     eax, [ebp+var_4]
CODE:004E1A49                 call    @System@@LStrAddRef$qqrpv
CODE:004E1A4E                 mov     eax, [ebp+var_8]
CODE:004E1A51                 call    @System@@LStrAddRef$qqrpv
CODE:004E1A56                 lea     eax, [ebp+var_14]
CODE:004E1A59                 mov     edx, off_4D6428
CODE:004E1A5F                 call    unknown_libname_93
CODE:004E1A64                 lea     eax, [ebp+var_1C]
CODE:004E1A67                 mov     edx, off_4D6428
CODE:004E1A6D                 call    unknown_libname_93
CODE:004E1A72                 xor     eax, eax
; Тут начинаются всякие шаманские танцы по превращению имени в правильный
; серийный номер...
CODE:004E1A74                 push    ebp
CODE:004E1A75                 push    offset loc_4E1AF6
CODE:004E1A7A                 push    dword ptr fs:[eax]
CODE:004E1A7D                 mov     fs:[eax], esp
CODE:004E1A80                 xor     ebx, ebx
CODE:004E1A82                 lea     edx, [ebp+var_14]
CODE:004E1A85                 mov     eax, ds:off_4E5A30
CODE:004E1A8A                 call    sub_4D6AB8
CODE:004E1A8F                 lea     edx, [ebp+var_1C]
CODE:004E1A92                 mov     eax, ds:off_4E5A34
CODE:004E1A97                 call    sub_4D6AB8
CODE:004E1A9C                 lea     eax, [ebp+var_4]
CODE:004E1A9F                 push    eax
CODE:004E1AA0                 lea     ecx, [ebp+var_1C]
CODE:004E1AA3                 lea     edx, [ebp+var_14]
CODE:004E1AA6                 mov     eax, [ebp+var_4]
CODE:004E1AA9                 call    sub_4D8EA4
CODE:004E1AAE                 lea     edx, [ebp+var_C]
CODE:004E1AB1                 mov     eax, [ebp+var_4]
CODE:004E1AB4                 call    sub_4D6690
; ... и заканчивается вся эта движуха банальным сравнением правильного
; серийного номера и введенного нами. Регистр EAX указывает на введенные
; данные, EDX указывает на правильный серийный номер для введенного имени
CODE:004E1AB9                 mov     eax, [ebp+var_8]
CODE:004E1ABC                 mov     edx, [ebp+var_C]
; Вызвать функцию сравнения двух строк
CODE:004E1ABF                 call    @System@@LStrCmp$qqrv
CODE:004E1AC4                 jnz     short loc_4E1AC8
CODE:004E1AC6                 mov     bl, 1
CODE:004E1AC8 loc_4E1AC8:
CODE:004E1AC8                 xor     eax, eax
CODE:004E1ACA                 pop     edx
CODE:004E1ACB                 pop     ecx
...

Содержимое регистров перед сравнением никаких сомнений вызывать не должно:


Правильный серийный номер

Заковыристая строка, обведенная красной рамкой, - это и есть правильный серийный номер для введенного имени. Сохраним его куда-нибудь и повторим регистрацию, но теперь уже с найденным серийником.


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

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