Исследование защиты программы PDF Password Cracker


Скриншот программы PDF Password Cracker

Программа PDF Password Cracker предназначена для подбора и удаления паролей из PDF-файлов. Поддерживается стандартное 40-битное шифрование, улучшенное 128-битное шифрование и шифрование по алгоритму AES. Подбор пароля выполняется по заданному диапазону символов, по словарю или прямым поиском ключа. Кроме пароля позволяет удалять из PDF-файлов ограничения на печать и копирование, различные приватные данные, такие как мета-данные, формы, скрипты, вложенные файлы, цифровые подписи и т.п. В общем реально нужная и полезная программа. Есть несколько вариантов дистрибутивов, в зависимости от количества наворотов растет и цена, доходя на версии Enterprise аж до 60 баксов. Бесплатных версий нет, по крайней мере пока.

Раз уж взялись изучать защиту этого поделия, так начнем сразу с его максимально навороченной редакции. Загружаем дистрибутив версии Enterprise, устанавливаем, запускаем. Получаем вот такое симпатичное окно:


Окно регистрации

На ввод левых данных программа реагирует сообщением "Your registration key is wrong, please check it and try again". Где-то я все это уже видел. Назначение программы и внешний вид окон очень сильно напоминает мне разобранную ранее программу PDF Password Remover. Там было такое же грозное окно с фейковым Machine ID и регистрационным ключом. Обе программы также используют одинаковый скиновый движок, и это наводит на мысли, что автор у них один. Значит и используемые методы защиты могут совпадать. Проверим это на практике.

Исполняемый файл упакован UPX, заголовки и служебные поля не испорчены, и файл возвращается в исходное состояние при помощи самого же UPX командой upx -d crackpdf.exe, после чего сразу загоняем его в дизассемблер. Параллельно поищем строку сообщения об ошибке регистрации в распакованном файле.


Нехорошая строка найдена

Да, наша догадка полностью подтвердилась, внутри программа PDF Password Cracker очень похожа на PDF Password Remover. Ну или наоборот, это сути не меняет :) Посмотрим на фрагмент кода, который отвечает за вывод сообщения о неправильном серийном номере.
...
.text:004086AA                 push    (offset Src+20h) ; lpString
.text:004086AF                 push    414h            ; nIDDlgItem
.text:004086B4                 push    esi             ; hDlg
.text:004086B5                 rep stosd
.text:004086B7                 call    ds:GetDlgItemTextA
; Получить введенный текст серийного номера
.text:004086BD                 push    4F5C94h
; Вызвать процедуру проверки
.text:004086C2                 call    sub_408060   ; <---- Проверка
.text:004086C7                 add     esp, 4
.text:004086CA                 test    eax, eax
; Если процедура проверки вернула EAX=0, то серийный номер неправильный
.text:004086CC                 jz      short loc_408712
; Вывести сообщение о правильной регистрации
.text:004086CE                 push    40h             ; uType
.text:004086D0                 push    offset aThankYou_ ; "Thank you."
.text:004086D5                 push    offset aThankYouForPur
; "Thank you for purchase the PDF Password"...
.text:004086DA                 push    esi             ; hWnd
.text:004086DB                 call    ds:MessageBoxA
.text:004086E1                 push    ecx             ; lpData
.text:004086E2                 mov     ecx, esp
.text:004086E4                 mov     [esp+0E8h+var_D8], esp
.text:004086E8                 push    (offset Src+20h) ; Src
.text:004086ED                 call    sub_47F96A
.text:004086F2                 call    sub_408310
.text:004086F7                 add     esp, 4
.text:004086FA                 mov     dword ptr Src+0E8h, 1
.text:00408704                 push    1               ; nResult
.text:00408706                 push    esi             ; hDlg
.text:00408707                 call    ds:EndDialog
.text:0040870D                 jmp     loc_408982
.text:00408712 ; --------------------------------------------------
.text:00408712 loc_408712:
; Вывести сообщение о неправильной регистрации
.text:00408712                 push    10h             ; uType
.text:00408714                 push    0               ; lpCaption
.text:00408716                 push    offset aYourRegistrati
; "Your registration key is wrong, please "...
.text:0040871B                 push    esi             ; hWnd
.text:0040871C                 call    ds:MessageBoxA
.text:00408722                 push    414h            ; nIDDlgItem
.text:00408727                 push    esi             ; hDlg
...

Как и в прошлый раз, здесь есть два варианта. Можно пропатчить процедуру проверки серийного номера по адресу 00408060, чтобы она всегда возвращала EAX=1, в этом случае программа станет портативной и ее можно будет таскать с собой на флешке. Для собственный нужд я сделал именно такой вариант. А чтобы немного порадовать приверженцев кейгенов, разберем алгоритм проверки серийного номера. Он очень похож на алгоритм, который использовался в программе PDF Password Remover, ну это и не удивительно.
.text:00408060                 sub     esp, 18h
.text:00408063                 or      ecx, 0FFFFFFFFh
.text:00408066                 xor     eax, eax
.text:00408068                 push    ebx
.text:00408069                 push    esi
.text:0040806A                 mov     esi, [esp+20h+arg_0]
.text:0040806E                 push    edi
; Самопальная функция получения длины строки
.text:0040806F                 mov     edi, esi
.text:00408071                 repne scasb
.text:00408073                 not     ecx
.text:00408075                 dec     ecx
; После отработки в регистре ECX содержится значение длины строки
.text:00408076                 cmp     ecx, 14h
; Должно быть 14h (20 в десятичной системе) символов
.text:00408079                 jz      short loc_408082
.text:0040807B                 pop     edi
.text:0040807C                 pop     esi
.text:0040807D                 pop     ebx
.text:0040807E                 add     esp, 18h
; Если это не так, то на выход
.text:00408081                 retn

Длина серийного номера, как и в прошлый раз, равна 20 символам.
; Первая проверка. Берутся 14-й и 15-й символы серийного номера
.text:00408082                 mov     al, [esi+0Eh]
.text:00408085                 mov     cl, [esi+0Fh]
.text:00408088                 lea     edx, [esp+24h+Str]
.text:0040808C                 xor     bl, bl
.text:0040808E                 push    edx             ; Str
.text:0040808F                 mov     [esp+28h+var_C], al
.text:00408093                 mov     [esp+28h+var_B], bl
.text:00408097                 mov     [esp+28h+Str], cl
.text:0040809B                 mov     [esp+28h+var_17], bl
; Оба символа преобразуются в числа и складываются
.text:0040809F                 call    _atoi
.text:004080A4                 mov     edi, eax
.text:004080A6                 lea     eax, [esp+28h+var_C]
.text:004080AA                 push    eax             ; Str
.text:004080AB                 call    _atoi
.text:004080B0                 add     edi, eax
.text:004080B2                 add     esp, 8
; В сумме должно получиться 10
.text:004080B5                 cmp     edi, 0Ah
.text:004080B8                 jz      short loc_4080C3
.text:004080BA                 pop     edi
.text:004080BB                 pop     esi
.text:004080BC                 xor     eax, eax
.text:004080BE                 pop     ebx
.text:004080BF                 add     esp, 18h
.text:004080C2                 retn

Первая проверка. Из серийного номера берутся 14-й и 15-й символы, переводятся в численное значение и складываются. В сумме должно получиться 10.
; Вторая проверка. Берутся 1-й и 2-й символы серийного номера
.text:004080C3                 mov     cl, [esi]
.text:004080C5                 mov     dl, [esi+1]
.text:004080C8                 lea     eax, [esp+24h+Str]
.text:004080CC                 mov     [esp+24h+var_C], cl
.text:004080D0                 push    eax             ; Str
.text:004080D1                 mov     [esp+28h+var_B], bl
.text:004080D5                 mov     [esp+28h+Str], dl
.text:004080D9                 mov     [esp+28h+var_17], bl
; Оба символа преобразуются в числа и складываются
.text:004080DD                 call    _atoi
.text:004080E2                 lea     ecx, [esp+28h+var_C]
.text:004080E6                 mov     edi, eax
.text:004080E8                 push    ecx             ; Str
.text:004080E9                 call    _atoi
.text:004080EE                 add     edi, eax
.text:004080F0                 add     esp, 8
; В сумме должно получиться 11
.text:004080F3                 cmp     edi, 0Bh
.text:004080F6                 jz      short loc_408101
.text:004080F8                 pop     edi
.text:004080F9                 pop     esi
.text:004080FA                 xor     eax, eax
.text:004080FC                 pop     ebx
.text:004080FD                 add     esp, 18h
.text:00408100                 retn

Во второй проверке суммируются первый и второй символы серийного номера, в сумме они должны дать 11.
; Третья проверка: 6-й символ серийного номера должен быть "2"
.text:00408101                 cmp     byte ptr [esi+5], 32h
.text:00408105                 jz      short loc_408110
.text:00408107                 pop     edi
.text:00408108                 pop     esi
.text:00408109                 xor     eax, eax
.text:0040810B                 pop     ebx
.text:0040810C                 add     esp, 18h
.text:0040810F                 retn

Третья проверка - 6-й символ серийного номера должен быть "2".
; Последняя проверка. Берутся 8-й и 9-й символы серийного номера
.text:00408110                 mov     dl, [esi+7]
.text:00408113                 mov     al, [esi+8]
.text:00408116                 lea     ecx, [esp+24h+Str]
.text:0040811A                 mov     [esp+24h+var_C], dl
.text:0040811E                 push    ecx             ; Str
.text:0040811F                 mov     [esp+28h+var_B], bl
.text:00408123                 mov     [esp+28h+Str], al
.text:00408127                 mov     [esp+28h+var_17], bl
; Оба символа преобразуются в числа и складываются
.text:0040812B                 call    _atoi
.text:00408130                 lea     edx, [esp+28h+var_C]
.text:00408134                 mov     esi, eax
.text:00408136                 push    edx             ; Str
.text:00408137                 call    _atoi
.text:0040813C                 add     esp, 8
.text:0040813F                 add     esi, eax
.text:00408141                 xor     eax, eax
; В сумме должно получиться 15
.text:00408143                 cmp     esi, 0Fh
.text:00408146                 pop     edi
.text:00408147                 pop     esi
.text:00408148                 setz    al
.text:0040814B                 pop     ebx
.text:0040814C                 add     esp, 18h
.text:0040814F                 retn

В последней проверке складываются 8-й и 9-й символы серийного номера, в сумме они должны дать 15. Остальные символы серийного номера не учитываются и могут быть любыми. Готовый серийный номер может быть, например, таким: 56PCL2078MANHU55NTER. Рабочий кейген вы теперь можете написать самостоятельно.


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

Последний момент. Не знаю как вас, а меня просто вымораживают уродливые скины, которые используются для оформления программ. Для того, чтобы окна программ PDF Password Cracker или PDF Password Remover приняли обычный вид, достаточно удалить файл xpgrean.smf, который находится в папке с программой.
Теги:
защита, взлом
Добавлено: 20 Сентября 2013 09:07:39 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...