Исследование защиты программы 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. Ну или наоборот, это сути не меняет :) Посмотрим на фрагмент кода, который отвечает за вывод сообщения о неправильном серийном номере.
Code (Assembler) : Убрать нумерацию
- ...
- .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
- ...
Code (Assembler) : Убрать нумерацию
- .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
Code (Assembler) : Убрать нумерацию
- ; Первая проверка. Берутся 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
Code (Assembler) : Убрать нумерацию
- ; Вторая проверка. Берутся 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
Code (Assembler) : Убрать нумерацию
- ; Третья проверка: 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
Code (Assembler) : Убрать нумерацию
- ; Последняя проверка. Берутся 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
Программа успешно зарегистрирована
Последний момент. Не знаю как вас, а меня просто вымораживают уродливые скины, которые используются для оформления программ. Для того, чтобы окна программ PDF Password Cracker или PDF Password Remover приняли обычный вид, достаточно удалить файл xpgrean.smf, который находится в папке с программой.
Просмотров: 5687 | Комментариев: 3
Метки: исследование защиты, PDF
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Виталий
(02.02.2012 в 19:25):
Спасибо за помощь!
ManHunter
(23.11.2010 в 08:52):
AyTkACT, да тут для патча вообще бы одного HIEW хватило. Просто привычка, HIEW у меня забинден на Alt-F3 в качестве альтернативного просмотрщика в Total Commander, поэтому все файлы исследую сперва через него.
У каждого ресурса есть свой уникальный идентификатор, по которому он загружается и который можно найти. Многоязычные строки обычно хранятся в одном контейнере с одним ID, или в разных файлах, но тоже с одинаковым ID. Так что и тут никаких проблем не вижу, все действия стандартные.
А если чего-то нет на паблике, это не значит, что этого нет в природе :)
У каждого ресурса есть свой уникальный идентификатор, по которому он загружается и который можно найти. Многоязычные строки обычно хранятся в одном контейнере с одним ID, или в разных файлах, но тоже с одинаковым ID. Так что и тут никаких проблем не вижу, все действия стандартные.
А если чего-то нет на паблике, это не значит, что этого нет в природе :)
AyTkACT
(23.11.2010 в 07:10):
Давно назревал вопрос: бинарный поиск в IDA отменили или просто так привык к hiew? Кстати, не заметил на паблике hiew версии 8.12. Честно купленный?
Собсна что бинарный поиск, что hiew мало выручат, если нет xref'ов на строки, а скажем строки в ресурсах файла на нескольких языках.
Как мне кажется пора раскрыть тему как выкручиваться в подобных ситуациях.
з.ы. Тема кейгенинга раскрыта! =)
Собсна что бинарный поиск, что hiew мало выручат, если нет xref'ов на строки, а скажем строки в ресурсах файла на нескольких языках.
Как мне кажется пора раскрыть тему как выкручиваться в подобных ситуациях.
з.ы. Тема кейгенинга раскрыта! =)
Добавить комментарий
Заполните форму для добавления комментария