Автор: Fess | Дата: 19.10.2002 | Тьютор: 24 |
Target: JPEG Optimizer v2.02 Tools: Some brains Win32Dasm 8.93 Все, кроме мозгов, можно найти на www.exetools.com
Как это начиналось:
Принесли мне компакт от какой-то книги издательства Питер, кажется книга про Web. Там
валялись всякие проги для работы с графикой и html, не долго думая, я решил скопировать все
это на свой хард, чтобы потом поразобраться...
Спустя неделю ко мне в руки попал компакт с огромным количеством картинок в формате jpg.
При не очень большом разрешении их размер достигал 500 кило, и это меня не обрадовало.
Их было так много, что я сразу отбросил мысль об использовании IrfanView'а (очень рулезная
прога, всем рекомендую www.irfanview.com). Тут я
вспомнил о компакте, где были проги для работы с графикой, а точнее оптимизаторы. Так я вышел
на эту прогу. К моему сожалению, она просила за регистрацию $29 и это была ее главная ошибка.
Приступаем
Что за прога:
Очень хорошая прога для сжатия графики, позволяет обрабатывать файлы в автоматическом режиме.
Короче мне понравилась, я ее себе даже русифицировал, если кому интересно, то напишите на мыло.
Размер в архиве примерно 400Kb. Единственный недостаток - регистрация, который мы сейчас исправим.
Взглянув на ресурсы, я понял, что программа написана на Delphi и это хорошо (присутствуют bmp файлы всегда вставляющиеся Delphi). Запускаем ее, заходим в раздел Register и вводим произвольный пароль. На это нам выплевывается надпись Incorrect Registration Code. Это будет главная зацепка.
Кидаем программу в Win32Dasm. И в секции строк ищем нашу. Нашли. Нажимаем на нее два раза и оказываемся тут
:00427F8E 50 push eax :00427F8F FF4E1C dec [esi+1C] :00427F92 8D45F8 lea eax, dword ptr [ebp-08] :00427F95 BA02000000 mov edx, 00000002 :00427F9A E891D10100 call 00445130 :00427F9F 59 pop ecx :00427FA0 84C9 test cl, cl :00427FA2 0F84B7000000 je 0042805F :00427FA8 66C746102C00 mov [esi+10], 002C * Possible StringData Ref from Data Obj ->"JPEG Optimizer" | :00427FAE BA6D9B4700 mov edx, 00479B6D (всякий мусор выкинут) :00427FF0 8D4DEC lea ecx, dword ptr [ebp-14] * Possible StringData Ref from Data Obj ->"Code" | :00427FF3 BA7C9B4700 mov edx, 00479B7C (здесь выкинут код отвечающий за запись правильного кода в реестр) :00428040 8BC3 mov eax, ebx :00428042 E8054A0200 call 0044CA4C :00428047 6A40 push 00000040 * Possible StringData Ref from Data Obj ->"Message" | :00428049 B9AA9B4700 mov ecx, 00479BAA <- Выводится сообщение о правильной регистрации. * Possible StringData Ref from Data Obj ->"Thank you for registering JPEG " ->"Optimizer" | :0042804E BA819B4700 mov edx, 00479B81 :00428053 A104F54700 mov eax, dword ptr [0047F504] :00428058 E843A80300 call 004628A0 :0042805D EB16 jmp 00428075 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427FA2(C) <- Вот оттуда переход на првильный или неправильный | :0042805F 6A30 push 00000030 * Possible StringData Ref from Data Obj ->"Error" | :00428061 B9CE9B4700 mov ecx, 00479BCE * Possible StringData Ref from Data Obj ->"Incorrect Registration Code" | :00428066 BAB29B4700 mov edx, 00479BB2 :0042806B A104F54700 mov eax, dword ptr [0047F504] :00428070 E82BA80300 call 004628A0
Вроде бы проверка в процедуре call 445130. Но меня смутила строка 427F9F (она выделена). А потом я просек в чем дело, взглянув чуть выше, строка 427F8E. Я уж не знаю, сами ли программеры решили так нас обмануть, а может компилятор. Скорее всего второе. Теперь смотрим повыше
:00427F75 BA6C9B4700 mov edx, 00479B6C * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427F73(U) | :00427F7A 52 push edx :00427F7B E8380A0000 call 004289B8 :00427F80 59 pop ecx :00427F81 84C0 test al, al <- Проверяем :00427F83 7504 jne 00427F89 <- Если все тип-топ (al<>0), то переход * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427F68(C) | :00427F85 33C0 xor eax, eax :00427F87 EB05 jmp 00427F8E * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427F83(C) | :00427F89 B801000000 mov eax, 00000001
Что ж идем в процедуру и попробуем разобраться в коде.
:004289B8 55 push ebp :004289B9 8BEC mov ebp, esp :004289BB 83C4F8 add esp, FFFFFFF8 :004289BE 53 push ebx :004289BF 8B4508 mov eax, dword ptr [ebp+08] :004289C2 8D5DF8 lea ebx, dword ptr [ebp-08] :004289C5 8A10 mov dl, byte ptr [eax] <- :004289C7 8813 mov byte ptr [ebx], dl <- :004289C9 8A4801 mov cl, byte ptr [eax+01] <- :004289CC 884B01 mov byte ptr [ebx+01], cl <- :004289CF 8A5002 mov dl, byte ptr [eax+02] <- :004289D2 885302 mov byte ptr [ebx+02], dl <- Копируем 6 байт регистрационного кода :004289D5 8A4803 mov cl, byte ptr [eax+03] <- в другое местов оперативной памяти :004289D8 884B03 mov byte ptr [ebx+03], cl <- :004289DB 8A5004 mov dl, byte ptr [eax+04] <- :004289DE 885304 mov byte ptr [ebx+04], dl <- :004289E1 8A4005 mov al, byte ptr [eax+05] <- :004289E4 884305 mov byte ptr [ebx+05], al <- :004289E7 0FBE0B movsx ecx, byte ptr [ebx] <- :004289EA 51 push ecx :004289EB E8AC240400 call 0046AE9C :004289F0 59 pop ecx :004289F1 83F851 cmp eax, 00000051 <- Проверка кода 1 символа пароля с кодом буквы Q :004289F4 7544 jne 00428A3A <- Если не правильно, то переход :004289F6 0FBE4301 movsx eax, byte ptr [ebx+01] :004289FA 50 push eax :004289FB E89C240400 call 0046AE9C :00428A00 59 pop ecx :00428A01 83F84F cmp eax, 0000004F <- Проверка кода 2 символа пароля с кодом буквы O :00428A04 7534 jne 00428A3A <- Если не правильно, то переход :00428A06 0FBE5302 movsx edx, byte ptr [ebx+02] :00428A0A 83FA37 cmp edx, 00000037 <- Проверка кода 3 символа пароля с кодом символа 7 :00428A0D 752B jne 00428A3A <- Если не правильно, то переход :00428A0F 0FBE4B03 movsx ecx, byte ptr [ebx+03] :00428A13 83F930 cmp ecx, 00000030 <- Проверка кода 4 символа пароля с кодом символа 0 :00428A16 7522 jne 00428A3A <- Если не правильно, то переход :00428A18 0FBE4304 movsx eax, byte ptr [ebx+04] :00428A1C 83F831 cmp eax, 00000031 <- Проверка кода 5 символа пароля с кодом символа 1 :00428A1F 7519 jne 00428A3A <- Если не правильно, то переход :00428A21 0FBE5305 movsx edx, byte ptr [ebx+05] :00428A25 83FA32 cmp edx, 00000032 <- Проверка кода 6 символа пароля с кодом символа 2 :00428A28 7510 jne 00428A3A <- Если не правильно, то переход :00428A2A C605F0EC470001 mov byte ptr [0047ECF0], 01 :00428A31 E85AAEFDFF call 00403890 :00428A36 B001 mov al, 01 <- Вроде как код введен правильно {В итоге для того, чтобы пройти эту проверку нужно написать код QO7012} :00428A38 EB18 jmp 00428A52 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:004289F4(C), :00428A04(C), :00428A0D(C), :00428A16(C), :00428A1F(C) |:00428A28(C) | :00428A3A 53 push ebx :00428A3B E8501A0000 call 0042A490 :00428A40 59 pop ecx :00428A41 84C0 test al, al :00428A43 7404 je 00428A49 :00428A45 B001 mov al, 01 :00428A47 EB09 jmp 00428A52 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00428A43(C) | :00428A49 C605F0EC470000 mov byte ptr [0047ECF0], 00 :00428A50 33C0 xor eax, eax * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00428A38(U), :00428A47(U) | :00428A52 5B pop ebx :00428A53 59 pop ecx :00428A54 59 pop ecx :00428A55 5D pop ebp :00428A56 C3 ret
И вроде бы, код найден, но меня заинтересовала процедура call 0042A490 (она выделена). После нее AL тоже устанавливается в единицу. И я решил проверить.
:0042A490 55 push ebp :0042A491 8BEC mov ebp, esp :0042A493 53 push ebx :0042A494 8B5D08 mov ebx, dword ptr [ebp+08] <- В ebx адрес памяти с введенным кодом (какой-то мутный код) :0042A4B1 33D2 xor edx, edx <- Обнуляем edx :0042A4B3 8BC3 mov eax, ebx <- В eax указатель на введенный код * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042A4BD(C) | :0042A4B5 803093 xor byte ptr [eax], 93 <- Ксорим все символы введеного кода с 93h :0042A4B8 42 inc edx <- Увеличиваем счетчик :0042A4B9 40 inc eax <- Увеличиваем указатель :0042A4BA 83FA06 cmp edx, 00000006 <- Сравниваем счетчик с 6 :0042A4BD 7CF6 jl 0042A4B5 <- Если меньше, то повторяем цикл :0042A4BF 0FBE0B movsx ecx, byte ptr [ebx] <- Берем 1 символ отxorенного кода :0042A4C2 83F9D8 cmp ecx, FFFFFFD8 <- Сравниваем с :0042A4C5 7545 jne 0042A50C <- Если не равно, то в пролете {Значит надо, чтобы было равно этим мы вычислим символ, который надо написать в коде, можно, конечно, попробовать угадать в дебаггере или написать программу, но мы попробуем посчитать все в ручную. Как, надеюсь, вам известно, что функция xor обратима, поэтому ее часто используют для шифрования. Функция устанавливаем бит в единицу, если один операнд единица, а второй ноль, иначе будет ноль. Переводим 93h в двоичную систему, это можно сделать с помощью простого виндового калькулятора, можно тетрадами, а можно в ручную. 93h - 10010011 93h - 10010011 93h - 10010011 D8h - 11011000 D9h - 11011001 A4h - 10100100 -------------- -------------- -------------- 01001011 -> 4Bh(K) 01001010 -> 4Ah(J) 00110111 - 37h(7) и так далее. В итоге получаем KJ7246} :0042A4C7 0FBE4301 movsx eax, byte ptr [ebx+01] :0042A4CB 83F8D9 cmp eax, FFFFFFD9 :0042A4CE 753C jne 0042A50C :0042A4D0 0FBE5302 movsx edx, byte ptr [ebx+02] :0042A4D4 83FAA4 cmp edx, FFFFFFA4 :0042A4D7 7533 jne 0042A50C :0042A4D9 0FBE4B03 movsx ecx, byte ptr [ebx+03] :0042A4DD 83F9A1 cmp ecx, FFFFFFA1 :0042A4E0 752A jne 0042A50C :0042A4E2 0FBE4304 movsx eax, byte ptr [ebx+04] :0042A4E6 83F8A7 cmp eax, FFFFFFA7 :0042A4E9 7521 jne 0042A50C :0042A4EB 0FBE5305 movsx edx, byte ptr [ebx+05] :0042A4EF 83FAA5 cmp edx, FFFFFFA5 :0042A4F2 7518 jne 0042A50C :0042A4F4 C605F0EC470001 mov byte ptr [0047ECF0], 01 :0042A4FB C60500F4470001 mov byte ptr [0047F400], 01 :0042A502 E88993FDFF call 00403890 :0042A507 B001 mov al, 01 <- Если все хорошо :0042A509 5B pop ebx :0042A50A 5D pop ebp :0042A50B C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:0042A4C5(C), :0042A4CE(C), :0042A4D7(C), :0042A4E0(C), :0042A4E9(C) |:0042A4F2(C) | :0042A50C 33C0 xor eax, eax <- здесь не есть хорошо :0042A50E 5B pop ebx :0042A50F 5D pop ebp :0042A510 C3 ret
Ну вот и все, найдены два кода QO7012 и KJ7246. Чем они отличаются, честно говоря не знаю. Но все-таки думаю, что второй код приоритетней, т.к. он был замудрован посильнее первого (хотя и не очень сильно).
Спасибо авторам за предоставленный для исследования продукт. Он мне очень помог при переделывании картинок.
Господа Авторы: "Худшая защита месяца" только так можно охарактеризовать то, что я увидел в этой программе. Перед тем, как делать защиту можно было и почитать мануалы, написанные в этом направлении. Извините меня, но $29 для России это не дела. Крэкеров в Росии много. Россия рулез!
Братья Крэкеры: Не стоит сильно ругать авторов, они там за бугром не ведают, что творят.
И да пребудет с вами великий дух bad-сектора.
Материалы находятся на сайте http://cracklab.narod.ru/doc/