скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Нахождение ключей для JPEG Optimizer v2.02 (взлом без Soft-Ice)


Автор: Fess

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. Чем они отличаются, честно говоря не знаю. Но все-таки думаю, что второй код приоритетней, т.к. он был замудрован посильнее первого (хотя и не очень сильно).

Спасибо за интерес к моему творчеству!

Удачи в Reversing Engeneering!

Послесловие

Спасибо авторам за предоставленный для исследования продукт. Он мне очень помог при переделывании картинок.

Господа Авторы: "Худшая защита месяца" только так можно охарактеризовать то, что я увидел в этой программе. Перед тем, как делать защиту можно было и почитать мануалы, написанные в этом направлении. Извините меня, но $29 для России это не дела. Крэкеров в Росии много. Россия рулез!

Братья Крэкеры: Не стоит сильно ругать авторов, они там за бугром не ведают, что творят.

Автор: Fess
Все остальное на lomovskih@yandex.ru

P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!

P.P.S. Возможно имеют место опечатки, заранее извините!

With best wishes Fess Member of the group PTDS

И да пребудет с вами великий дух bad-сектора






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook