Исследование защиты программы Alarm++
Скриншот программы Alarm++
Alarm++ - шароварная напоминалка с кучей настроек и возможностей. Если интересно, что она умеет, то за этим лучше сходить на офсайт, у меня тут совсем другая цель. В неоплаченном варианте вы можете создавать ограниченное количество напоминалок, после покупки это ограничение снимается. Попробуем добиться такого же результата, но при этом обойтись без траты денежных средств.
Скачиваем дистрибутив, устанавливаем, смотрим. Через меню настроек программы попробуем зарегистрировать ее с каким-нибудь левым серийником. Получим вот такое сообщение:
Сообщение о неправильной регистрации
Теперь поищем, где оно находится. А находится оно в ресурсах исполняемого файла с десятичным индексом 40003 или же 9C43, если считать в шестнадцатеричной системе.
Строка в ресурсах
Вы ведь уже отправили файл в дизассемблер, в сотой статье об этом напоминать не надо? Отлично. Поищем в нем место, где этот индекс используется.
Code (Assembler) : Убрать нумерацию
- .text:004313CE mov eax, [ecx-0Ch]
- .text:004313D1 test eax, eax
- .text:004313D3 jz short loc_431438
- .text:004313D5 push eax
- .text:004313D6 push [ebp+var_30]
- .text:004313D9 push ecx
- .text:004313DA call sub_58CDBF
- .text:004313DF add esp, 0Ch
- .text:004313E2 test eax, eax
- .text:004313E4 jz short loc_431438
- .text:004313E6 lea ecx, [ebp+var_2C]
- .text:004313E9 call sub_4078F0
- .text:004313EE push [ebp+var_30]
- .text:004313F1 lea eax, [ebp+var_2C]
- .text:004313F4 mov byte ptr [ebp+var_4], 4
- .text:004313F8 push dword ptr [esi+0A8h]
- .text:004313FE push 9C4Ch
- .text:00431403 push eax
- .text:00431404 call sub_448C0C
- .text:00431409 push 9C4Ch ; int
- .text:0043140E push 10h ; uType
- .text:00431410 push [ebp+var_2C] ; int
- .text:00431413 call sub_43E611
- .text:00431418 mov edx, [ebp+var_2C]
- .text:0043141B mov eax, edi
- .text:0043141D mov byte ptr [ebp+var_4], 3
- .text:00431421 add edx, 0FFFFFFF0h
- .text:00431424 lock xadd [edx+0Ch], eax
- .text:00431429 dec eax
- .text:0043142A test eax, eax
- .text:0043142C jg short loc_431446
- .text:0043142E mov ecx, [edx]
- .text:00431430 push edx
- .text:00431431 mov eax, [ecx]
- .text:00431433 call dword ptr [eax+4]
- .text:00431436 jmp short loc_431446
- .text:00431438 ; ---------------------------------------
- .text:00431438 loc_431438:
- .text:00431438 push 0FFFFFFFFh
- .text:0043143A push 10h
- ; Индекс строки из ресурсов
- .text:0043143C push 9C43h
- .text:00431441 call sub_43E5AF
- .text:00431446
Code (Assembler) : Убрать нумерацию
- ; Вызвать функцию проверки
- .text:0043134F call sub_420050
- .text:00431354 add esp, 0Ch
- ; Если она вернула AL!=0, то регистрация прошла успешно
- .text:00431357 test al, al
- .text:00431359 jnz loc_43146C
- ...
- ...
- ...
- .text:0043146C loc_43146C:
- .text:0043146C push 0FFFFFFFFh
- .text:0043146E push 40h
- ; Сообщение об успешной регистрации
- .text:00431470 push 9C42h
- .text:00431475 call sub_43E5AF
- .text:0043147A mov ecx, esi
- .text:0043147C call sub_44D5FD
Code (Assembler) : Убрать нумерацию
- .text:00420050 sub_420050 proc near
- .text:00420050 push ebp
- .text:00420051 mov ebp, esp
- .text:00420053 push 0FFFFFFFFh
- .text:00420055 push offset sub_5D2AF0
- .text:0042005A mov eax, large fs:0
- .text:00420060 push eax
- .text:00420061 sub esp, 8
- .text:00420064 push ebx
- .text:00420065 push esi
- .text:00420066 push edi
- .text:00420067 mov eax, ___security_cookie
- .text:0042006C xor eax, ebp
- .text:0042006E push eax
- .text:0042006F lea eax, [ebp+var_C]
- .text:00420072 mov large fs:0, eax
- .text:00420078 mov esi, [ebp+arg_0]
- .text:0042007B lea eax, [ebp+var_14]
- .text:0042007E push esi
- .text:0042007F push eax
- .text:00420080 call sub_420240
- .text:00420085 mov edi, eax
- .text:00420087 lea eax, [ebp+var_10]
- .text:0042008A mov [ebp+var_4], 0
- .text:00420091 push esi
- .text:00420092 push eax
- .text:00420093 call sub_4201B0
- .text:00420098 push [ebp+arg_8]
- .text:0042009B mov byte ptr [ebp+var_4], 1
- .text:0042009F push [ebp+arg_4]
- .text:004200A2 push edi
- .text:004200A3 push eax
- ; Вызвать следующую функцию проверки
- .text:004200A4 call sub_41FE60
- .text:004200A9 mov edx, [ebp+var_10]
- .text:004200AC or esi, 0FFFFFFFFh
- .text:004200AF add esp, 20h
- .text:004200B2 mov byte ptr [ebp+var_4], 0
- ; Сохранить результат проверки из AL в BL
- .text:004200B6 mov bl, al
- .text:004200B8 add edx, 0FFFFFFF0h
- .text:004200BB mov ecx, esi
- .text:004200BD lock xadd [edx+0Ch], ecx
- .text:004200C2 dec ecx
- .text:004200C3 test ecx, ecx
- .text:004200C5 jg short loc_4200CF
- .text:004200C7 mov ecx, [edx]
- .text:004200C9 push edx
- .text:004200CA mov eax, [ecx]
- .text:004200CC call dword ptr [eax+4]
- .text:004200CF loc_4200CF:
- .text:004200CF mov edx, [ebp+var_14]
- .text:004200D2 mov [ebp+var_4], 0FFFFFFFFh
- .text:004200D9 add edx, 0FFFFFFF0h
- .text:004200DC lock xadd [edx+0Ch], esi
- .text:004200E1 dec esi
- .text:004200E2 test esi, esi
- .text:004200E4 jg short loc_4200EE
- .text:004200E6 mov ecx, [edx]
- .text:004200E8 push edx
- .text:004200E9 mov eax, [ecx]
- .text:004200EB call dword ptr [eax+4]
- .text:004200EE loc_4200EE:
- ; Вернуть сохраненный результат проверки из BL в AL
- .text:004200EE mov al, bl
- .text:004200F0 mov ecx, [ebp+var_C]
- .text:004200F3 mov large fs:0, ecx
- .text:004200FA pop ecx
- .text:004200FB pop edi
- .text:004200FC pop esi
- .text:004200FD pop ebx
- .text:004200FE mov esp, ebp
- .text:00420100 pop ebp
- .text:00420101 retn
- .text:00420101 sub_420050 endp
Code (Assembler) : Убрать нумерацию
- .text:0041FE8E push ebx
- .text:0041FE8F push esi
- ; Следующая функция проверки
- .text:0041FE90 call sub_420B50
- .text:0041FE95 add esp, 8
- .text:0041FE98 test al, al
- .text:0041FE9A jnz short loc_41FEF0
- .text:0041FE9C push 30h ; uType
- ; Выдать сообщение с бибикалкой и зависнуть
- .text:0041FE9E call ds:MessageBeep
- .text:0041FEA4 call sub_441A5C
- .text:0041FEA9 mov ecx, [eax+4]
- .text:0041FEAC call sub_43D138
- .text:0041FEB1 imul eax, dword_65DC18, 3E8h
- .text:0041FEBB push eax ; dwMilliseconds
- .text:0041FEBC call ds:Sleep
- .text:0041FEC2 mov eax, dword_65DC18
- .text:0041FEC7 cmp eax, 3Ch
Code (Assembler) : Убрать нумерацию
- .text:00420B9C xor eax, eax
- .text:00420B9E mov [ebp+var_98], offset off_5E2990
- .text:00420BA8 mov [ebp+var_94], offset aR29krmfkzxi ; "R29kRmFkZXI="...
- .text:00420BB2 mov [ebp+var_90], offset aW3bjdf0 ; "W3BjdF0="...
- .text:00420BBC mov [ebp+var_8C], offset aW1rfwf0 ; "W1RFWF0="...
- .text:00420BC6 mov [ebp+var_88], offset off_5E2AF0
- .text:00420BD0 mov [ebp+var_84], offset aW0zsdwtlxq ; "W0ZsdWtlXQ=="...
- .text:00420BDA mov [ebp+var_80], offset aU2lyyvg ; "U2lyYVg="...
- .text:00420BE1 mov [ebp+var_7C], offset aS2lmtge ; "S2lMTGE="...
Code (Assembler) : Убрать нумерацию
- .text:0041FEF0 push esi
- .text:0041FEF1 push [ebp+arg_4]
- .text:0041FEF4 lea eax, [ebp+var_14]
- .text:0041FEF7 push [ebp+arg_0]
- .text:0041FEFA push eax
- .text:0041FEFB call sub_420540
- .text:0041FF00 lea eax, [ebp+var_14]
- .text:0041FF03 mov [ebp+var_4], 0
- .text:0041FF0A push ebx
- .text:0041FF0B push eax
- ; Вывать функцию проверки
- .text:0041FF0C call sub_4045E0
- .text:0041FF11 add esp, 18h
- .text:0041FF14 or esi, 0FFFFFFFFh
- ; По ее результатам перейти на завершение или продолжить выполнение
- .text:0041FF17 test al, al
- .text:0041FF19 jz short loc_41FF27
- .text:0041FF1B call sub_4208C0
- .text:0041FF20 xor bl, bl
- .text:0041FF22 jmp loc_420017
Вызов функции сравнения строк
Вызывается функция сравнения строк. При этом, если обратить внимание на регистры, то один из них указывает на введенный левый серийник:
Регистр указывает на серийный номер
Есть подозрение, что это именно он должен с чем-то сравниваться. Заруливаем в функцию сравнения. Там выполняется еще одно сравнение, но на этот раз регистр указывает вот на такую интересную строку:
Регистр указывает на серийный номер
Именно с ней сравнивается введенный серийный номер и по результатам этого итогового сравнения выносится вердикт о правильности или неправильности регистрации. Получается, что для регистрационного имени "ManHunter / PCL" правильный серийный номер будет "201BFDA2AEF05FB3360D1DA47BA55F17". Закрываем программу, выходим из отладчика и пробуем зарегистрировать программу с найденными данными:
Сообщение об успешной регистрации
Программа благодарит за регистрацию. Всегда пожалуйста, рад был помочь, приходите еще. Вы держитесь там, вам всего доброго, хорошего настроения и здоровья. А денег нет.
Программа успешно зарегистрирована
Не удивлюсь, если в какой-нибудь очередной версии программы мой ник также добавят в список запрещенных. Но это уже не так важно, зная принцип, можно наловить серийников под любое имя.
Просмотров: 3520 | Комментариев: 14
Метки: исследование защиты, система
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
DimitarSerg
(31.08.2016 в 22:58):
Лол, если программа сравнивает верный и неверный серийники, то кейген уже априори возможен - это лишь дело времени и желания.
Шел 2016 год, шароварщики продолжают юзать strcmp :) facepalm
TheCracker
(27.08.2016 в 14:00):
Подскажу идею: похоже, в программе используется видоизмененный MD5. Так называемый, MD5 с солью. Надо отследить что происходит с введенными символами имени и куда они передаются.
Предполагаю, что символы каким-то образом изменяются и скармливаются алгоритму md5. После чего получаем валидный серийник.
Можно сделать кейген ;)
Предполагаю, что символы каким-то образом изменяются и скармливаются алгоритму md5. После чего получаем валидный серийник.
Можно сделать кейген ;)
ManHunter
(22.08.2016 в 10:29):
Патч текстовой строки из черного списка всегда будет предпочтительнее патча самого кода. Во-первых, при таких раскладах нарисовать универсальный патчер легче легкого, сигнатура строки неизменна. Во-вторых, в этом случае целостность алгоритма регистрации сохраняется, ведь фактически это валидный серийник, который должен проходить все проверки, в том числе отложенные, хитро запрятанные и т.д. Я не говорю именно про эту программу, тут таких извратов нет, я вообще про принцип.
Doxtur
(21.08.2016 в 12:25):
Хоспода патчеры, а на ум вам не приходит, что при выпуске новой версии (например с именем manhunter в ч0рном списке) патчить вам придется еще раз ?
wetal
(20.08.2016 в 18:57):
pawel97, ну да, что то такое я имел в виду.
А на счет слабой защиты - я тоже не сторонник извращённых криптографий, дорогих защит и прочих сложностей. Если программу надо сломать, то всё равно сломают, а для честных людей защита не нужна. Покупают то всё равно честные, другие по любому деньги не платят, так зачем для них стараться, защищать?
А на счет слабой защиты - я тоже не сторонник извращённых криптографий, дорогих защит и прочих сложностей. Если программу надо сломать, то всё равно сломают, а для честных людей защита не нужна. Покупают то всё равно честные, другие по любому деньги не платят, так зачем для них стараться, защищать?
pawel97
(19.08.2016 в 09:49):
wetal, "А можно ли сделать не спортивно и грубо?"
Пытаемся создать более 5 напоминаний - получаем облом. Находим сообщение в листинге и перед ним классика жанра вида call xxx; test al,al; jnz...
Идём в функцию проверки и видим, что там просто в al заносится байт из [eax+374]
Смотрим, где похожий байт инициализируется нулём и меняем ноль на единицу.
Однобайтовый патч и даже ключ вводить не надо.
p.s. Вот думаю, автор специально .pdb забыл, чтобы ида имена функций показывала? Он бы ещё исходник приложил.
Пытаемся создать более 5 напоминаний - получаем облом. Находим сообщение в листинге и перед ним классика жанра вида call xxx; test al,al; jnz...
Идём в функцию проверки и видим, что там просто в al заносится байт из [eax+374]
Смотрим, где похожий байт инициализируется нулём и меняем ноль на единицу.
Однобайтовый патч и даже ключ вводить не надо.
p.s. Вот думаю, автор специально .pdb забыл, чтобы ида имена функций показывала? Он бы ещё исходник приложил.
ManHunter
(18.08.2016 в 17:01):
Из IDA только текстовые листинги, а серенькие скриншоты - это OllyDbg.
Noobie
(18.08.2016 в 16:58):
Толково, жаль что редко так бывает, имеется в виду самогенерация серийников программой. Но и не без этого, как видим. Давно хотел спросить - скриншоты дизассемблера, это IDA? Просто ни разу ее не юзал, поэтому не знаком с таким фейсом. HIEW и олька - наше фсё! :-)
ManHunter
(18.08.2016 в 13:48):
Патч черного списка легко решает эту проблему. В конце концов для домашнего использования можно сгенерить ключик на любое имя, главное не расшаривать его.
wetal
(18.08.2016 в 13:36):
Хотя бы для того, чтобы избежать этого:
"Не удивлюсь, если в какой-нибудь очередной версии программы мой ник также добавят в список запрещенных."
"Не удивлюсь, если в какой-нибудь очередной версии программы мой ник также добавят в список запрещенных."
ManHunter
(18.08.2016 в 09:06):
Можно, наверное. Но зачем?
wetal
(18.08.2016 в 07:54):
Красиво и спортивно подобрать валидный код регистрации. А можно ли сделать не спортивно и грубо?
Вот тут Вы писали:
"Именно с ней сравнивается введенный серийный номер и по результатам этого итогового сравнения выносится вердикт о правильности или неправильности регистрации."
Просто подправить код, чтобы любой введённый серийник возвращал правильный вердикт?
Вот тут Вы писали:
"Именно с ней сравнивается введенный серийный номер и по результатам этого итогового сравнения выносится вердикт о правильности или неправильности регистрации."
Просто подправить код, чтобы любой введённый серийник возвращал правильный вердикт?
SHREEF
(17.08.2016 в 22:42):
Молодец как всегда!
Добавить комментарий
Заполните форму для добавления комментария
Тише, не спугни :)