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


Скриншот программы Billion Chords

Billion Chords - самая крупная база аккордов, содержащая тысячи различных аккордов и их вариантов. Вы можете составить любой аккорд, а главное, что вы сразу же можете прослушать выбранный аккорд. За все это добро автор просит около 15 вечнозеленых, но, по всей видимости, он уже давно забил на проект. Ссылка на закачку на сайте не работает, форму оплаты и покупки я даже не проверял. Да и вообще, я не вижу смысла покупать программы.

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


Окно активации программы

Однако если попытаться активировать программу через меню, то окно активации будет совершенно другим:


Окно активации программы

Кроме поля ввода нам еще показывается какой-то серийный номер, причем на разных компьютерах он будет разный. По всей видимости это HWID, то есть код привязки к конкретному компьютеру. На ввод левых данных программа реагирует сообщением "Invalid Activation Code", поищем ее в файле. Найдется два вхождения.


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

Теперь посмотрим условия срабатывания этих фрагментов кода. Первый блок проверки:
.text:0041859F                 call    sub_480838
.text:004185A4                 lea     edx, [ebp+var_1F4]
.text:004185AA                 lea     eax, [ebp+var_4]
; Вызвать функцию проверки и сохранить ее результат EAX в стеке
.text:004185AD                 call    sub_4B67FC
.text:004185B2                 push    eax
.text:004185B3                 dec     [ebp+var_218]
.text:004185B9                 lea     eax, [ebp+var_1F4]
.text:004185BF                 mov     edx, 2
.text:004185C4                 call    sub_4B6700
.text:004185C9                 dec     [ebp+var_218]
.text:004185CF                 lea     eax, [ebp+var_1F0]
.text:004185D5                 mov     edx, 2
.text:004185DA                 call    sub_4B6700
.text:004185DF                 dec     [ebp+var_218]
.text:004185E5                 lea     eax, [ebp+var_1EC]
.text:004185EB                 mov     edx, 2
.text:004185F0                 call    sub_4B6700
; Прочитать сохраненное значение из стека в регистр ECX
.text:004185F5                 pop     ecx
; Если ECX=0, то перепрыгнуть сообщение о неправильном коде
.text:004185F6                 test    cl, cl
.text:004185F8                 jz      loc_4186EC
.text:004185FE                 push    0
.text:00418600                 lea     eax, [ebp+var_246]
.text:00418606                 call    unknown_libname_55
.text:0041860B                 mov     dl, 2
.text:0041860D                 call    sub_4189FC
.text:00418612                 mov     cx, [eax]
.text:00418615                 push    ecx
.text:00418616                 mov     [ebp+var_224], 1DCh
.text:0041861F                 mov     edx, offset aInvalidActivat
; "Invalid Activation Code."
.text:00418624                 lea     eax, [ebp+var_1F8]
.text:0041862A                 call    sub_4B6518
.text:0041862F                 inc     [ebp+var_218]
.text:00418635                 mov     eax, [eax]
...

Второй блок проверки:
...
.text:0041B98A                 call    sub_4B6700
.text:0041B98F                 lea     edx, [ebp+var_4]
.text:0041B992                 mov     eax, [ebp+var_4C]
.text:0041B995                 add     eax, 320h
; Вызвать функцию проверки регистрационных данных
.text:0041B99A                 call    sub_4B67FC
.text:0041B99F                 test    al, al
; Если она вернула EAX=0, то перепрыгнуть сообщение о неправильном коде
.text:0041B9A1                 jz      short loc_41BA07
.text:0041B9A3                 push    0
.text:0041B9A5                 lea     eax, [ebp+var_52]
.text:0041B9A8                 call    unknown_libname_55
.text:0041B9AD                 mov     dl, 2
.text:0041B9AF                 call    sub_4189FC
.text:0041B9B4                 mov     cx, [eax]
.text:0041B9B7                 push    ecx
.text:0041B9B8                 mov     [ebp+var_38], 2Ch
.text:0041B9BE                 mov     edx, offset aInvalidActiv_0
; "Invalid Activation Code."
.text:0041B9C3                 lea     eax, [ebp+var_10]
.text:0041B9C6                 call    sub_4B6518
.text:0041B9CB                 inc     [ebp+var_2C]
.text:0041B9CE                 mov     eax, [eax]
.text:0041B9D0                 mov     dl, 1
...

В обеих случаях вызывается функция:
.text:004B67FC                 push    ebp
.text:004B67FD                 mov     ebp, esp
.text:004B67FF                 push    ebx
.text:004B6800                 mov     eax, [eax]
.text:004B6802                 mov     edx, [edx]
.text:004B6804                 call    @System@@LStrCmp$qqrv
; System::__linkproc__ LStrCmp(void)
.text:004B6809                 setnz   al
.text:004B680C                 and     eax, 1
.text:004B680F                 pop     ebx
.text:004B6810                 pop     ebp
.text:004B6811                 retn

Сравниваются два значения, если они равны, то на выходе получаем заветное EAX=0. Если посмотреть по перекрестным ссылкам, то обнаружатся вызовы этой же функции и в других местах программы, ответственной за регистрацию, а именно добавление пунктов в меню, изменение заголовка окна и вывод наг-окон. Отлично, все симптомы известны, приступаем к лечению.

Первый вариант, самый простой - патч. Записываем в начало функции проверки по адресу 004B67FC команды XOR EAX,EAX; RET. Теперь программа будет всегда чувствовать себя зарегистрированной. Любителям "красивых" решений я могу сказать следующее: программа хранит свои регистрационные данные в реестре, и кроме того они привязаны к железу. После патча программа становится портативной и прекрасно работает на любой машине с любого носителя. Так что в этом случае патч более чем уместен.

Второй вариант, посложнее - сниффер серийника. Ставим в отладчике точку останова на начало функции проверки по адресу 004B67FC, затем запускаем программу. Брейкпоинт сработает несколько раз еще до появления главного окна программы, после этого можно попытаться активировать ее с любыми левыми данными. На следующем останове протрассируем функцию проверки в пошаговом режиме.


Правильные регистрационные данные

Видно, что в регистрах EAX и EDX сравниваются две строки - введенная нами неправильная строка и какая-то строка "E7A6E293191305390318B375". Перезапустим программу без отладчика и попробуем ввести эту строку в качестве кода активации. Как и ожидалось, все прошло гладко:


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

Но есть одно большое "но". Этот код подходит только для моего компьютера, так как был сгенерирован на основании данных моего серийного номера. Значит остался третий вариант лечения - генератор ключей активации для любого железа. Но вместо того, чтобы ковыряться в достаточно объемном алгоритме генерации, попробуем превратить в кейген саму программу. Для этого внимательно посмотрим на код:
; Перед сравнением строк записать в регистр EAX адрес указателя на
; строку с правильным регистрационным ключом
.text:004185AA                 lea     eax, [ebp+var_4]
и вот сюда:
Code (Assembler) : Убрать нумерацию
; Записать куда-то какие-то значение
.text:00418616                 mov     [ebp+var_224], 1DCh
; Записать в регистр EDX указатель на строку сообщения
.text:0041861F                 mov     edx, offset aInvalidActivat
; "Invalid Activation Code."
.text:00418624                 lea     eax, [ebp+var_1F8]
; Вывести сообщение на экран
.text:0041862A                 call    sub_4B6518

Пожертвуем двумя командами по адресу 00418616 и 0041861F (забьем их командами NOP), а вместо них запишем пару команд lea edx, [ebp+var_4] и mov edx,
. В отладчике это выглядит следующим образом:

[IMG]https://pp.vk.me/c411316/v411316982/8a84/wty7g9KYKOI.jpg

Патч программы под отладчиком

Теперь сохраняем изменения в исполняемый файл. Запускаем программу и попробуем ее зарегистрировать с любыми левыми данными. И о чудо :) Вместо сообщение об ошибке мы видим правильный регистрационный номер:

Программа работает как кейген

Вот и все, теперь Billion Chords сам будет подсказывать нам правильные ключи для своей же регистрации. Цинично, но ничего не поделаешь, мир реверсинга бывает очень жесток по отношению к шароварным программам.
Теги:
защита, взлом
Добавлено: 17 Сентября 2013 07:25:50 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...