Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Bruteforce для TourneyMaster 2.0.4

Обсудить статью на форуме

Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Автор: Nabu <nabu@km.ru>

"Tourney Master" (на www.metalexsoft.com) - это программное средство для проведения чемпионатов и создания турнирных сеток. Tourney Master ориентировано на чемпионаты по компьютерным играм, однако может быть использовано для проведения соревнований в других областях."

::Инструменты::
Все, что на этот раз нам понадобится – это только отладчик OllyDbg.

::Бредисловие::
Помнится, мне было очень интересно, как же пишутся брутфорсы для поиска серийника к программам. После некоторых поисков мне удалось найти статью Hex’a (www.xtin.ru), в которой брутфорсилась прога IP-Tools v1.11. Но по данной тематике я больше ничего не встречал. Думаю, моя статья лишней не будет.

::Сбор информации::
Как всегда разузнаем, на чем написана наша программа, или какой пакер (протектор) на ней висит. Оказывается TourneyMaster-2.0.4 защищена ASProtect’ом 1.23 RC4. Что ж, неплохо. Но снимать мы его не будем, так как в этом нет крайней необходимости, да и это тема совсем другой статьи. Единственное, что нам понадобится, так это спрятать отладчик от обнаружения. Удобнее всего это сделать, используя плагин HideDebugger by Asterix. Его, как и многие другие, можно найти на www.wasm.ru.

::Начнем::
И так запускаем OllyDbg, нажимаем F3 и выбираем файл. Олли спросит, нужно ли проанализировать файл. Нам это не нужно, и чтобы не тратить времени говорим «Нет». Запускаем файл по F9. Но, так как мы имеем дело с Аспаком, то у нас будут выскакивать сообщения в строке состояния при различных исключениях, которые мы обходим по Shift+F9. Вот запустилась наша программка. Теперь неплохо бы найти место, где происходит проверка на валидность рег. кода.

Ставим бряк на MessageBoxA (пишем в командной строке bp MessageBoxA). И не забываем, что Олля чувствительна к регистру. Теперь переходим на окно программы, нажимаем на кнопочку «Регистрация», вводим все, что нашей душе угодно, и подтверждаем. Попадаем в отладчик. Прерывание на MessageBoxA нам больше не понадобится, поэтому снимаем его (bс MessageBoxA или двойной щелчок на строке, помеченной красным цветом). Теперь доходим до инструкции выхода из API функции (Ctrl+F9). Как не странно, выскакивает окно о неправильности рег.ключа. Ну что ж, нажимаем «ОК» и снова уходим в Olly. Выполняем инструкцию RETN 10 (F8), далее еще 2 раза F8, чтобы выйти из системной библиотеки. Вот мы и попали туда, куда нам надо, т.е. в код нашей программы:


0040666F E8 A4A60000 CALL TourneyM.00410D18 ; JMP to mfc70.#3890
00406674 C64424 1C 02 MOV BYTE PTR SS:[ESP+1C],2 ; мы стоим здесь
00406679 E9 B7000000 JMP TourneyM.00406735
0040667E 8B36 MOV ESI,DWORD PTR DS:[ESI]
00406680 E8 99A60000 CALL TourneyM.00410D1E ; JMP to mfc70.#977
00406685 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
00406688 56 PUSH ESI
00406689 68 A8474100 PUSH TourneyM.004147A8 ; ASCII "Key"
0040668E 68 98474100 PUSH TourneyM.00414798 ; ASCII "Registration"


Видим, что далее следует безусловные переход (JMP TourneyM.00406735), ниже которого идет очень интересный код. После недолгих размышлений становится понятно, что именно этот код и будет выполняться при правильном рег. ключе. Значит, необходимо найти место, где происходит переход на адрес 0040667E. Пролистав экран вверх, видим следующее:


004065E7 E8 A4A20000 CALL TourneyM.00410890
004065EC 85C0 TEST EAX,EAX
004065EE 0F85 8A000000 JNZ TourneyM.0040667E


Теперь нужно бы проверить то ли мы нашли место или нет. Ставим бряк на команду JNZ TourneyM.0040667E (двойной щелчок мышки по этой строке или bp 004065EE). Отпускаем программу на волю и снова попытаемся что-нибудь ввести в качестве ключа. Оказавшись в окне дебугера, видим, что перехода на 0040667E не будет (Jump is NOT taken). А нам хотелось бы, чтобы здесь мы прыгнули, значит, меняем условие перехода, т.е. делаем флаг нуля (Z) равным 0. Для этого – двойной щелчок по значению флага. ОК, сменили условие и видим, что теперь произойдет переход. Значится, отпускаем прогу по F9. Видим окошечко, подтверждающее регистрацию. Но на самом деле программа не зарегистрировалась. Это можно увидеть, зайдя в меню «Помощь» - «Регистрация…». Вообще-то этого и следовало ожидать:) Но теперь мы знаем, что вся процедура регистрации лежит по адресу 00410890. Значит, снимаем наш бряк и ставим новый на адрес 004065E7. Опять вводим рег. ключ и прерываемся на нужном адресе. Снимаем этот брекпоинт – он нам больше не нужен, и заходим в CALL по F7. И вот, что видим:


00410890 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
00410894 8B00 MOV EAX,DWORD PTR DS:[EAX]
.......................вырезано.......................
004108BB 8D4C24 00 LEA ECX,DWORD PTR SS:[ESP]
004108BF E8 1CFFFFFF CALL TourneyM.004107E0 (1)
004108C4 8D4C24 00 LEA ECX,DWORD PTR SS:[ESP]
004108C8 E8 63FEFFFF CALL TourneyM.00410730 (2)
004108CD 83C4 64 ADD ESP,64
004108D0 C2 0400 RETN 4


Теперь нужно узнать, что из себя должен представлять наш рег. ключ, так как от этого будет зависеть время работы брутфорса.

Нас будут интересовать только два нижних CALL’a. Первый CALL делает следующие, интересные вещи:


Если код меньше 8 символов, то он дополняет его случайными буквами до 8 символов.
Если код больше 8 символов, то он урезает его до 8 символов.
Если в коде содержатся символы не английского алфавита, то он меняет эти символы на букву «A».

Вот нам уже известно, что рег. ключ должен быть из 8 символов. Теперь необходимо узнать какие это могут быть символы.

Заходим во второй CALL. Я разобью его на 3 блока.


Блок 1:
00410730 /$ 53 PUSH EBX
00410731 |. 55 PUSH EBP
00410732 |. 8B2D 54A04100 MOV EBP,DWORD PTR DS:[41A054]
00410738 |. 56 PUSH ESI
00410739 |. 33F6 XOR ESI,ESI
0041073B |. 85ED TEST EBP,EBP
0041073D |. 7E 1F JLE SHORT TourneyM.0041075E
0041073F |. 90 NOP
00410740 |> 8A1C0E /MOV BL,BYTE PTR DS:[ESI+ECX]
00410743 |. 33D2 |XOR EDX,EDX
00410745 |. 33C0 |XOR EAX,EAX
00410747 |> 3A1C08 |/CMP BL,BYTE PTR DS:[EAX+ECX]
0041074A |. 75 03 ||JNZ SHORT TourneyM.0041074F
0041074C |. 42 ||INC EDX
0041074D |. EB 05 ||JMP SHORT TourneyM.00410754
0041074F |> 83FA 01 ||CMP EDX,1
00410752 |. 7F 77 ||JG SHORT TourneyM.004107CB
00410754 |> 40 ||INC EAX
00410755 |. 3BC5 ||CMP EAX,EBP
00410757 |.^7C EE |\JL SHORT TourneyM.00410747
00410759 |. 46 |INC ESI
0041075A |. 3BF5 |CMP ESI,EBP
0041075C |.^7C E2 \JL SHORT TourneyM.00410740


Здесь происходит проверка символов. Если в коде есть одинаковые символы, то мы переходим на адрес 004107CB. А там у нас обнуляется регистр EAX (XOR EAX,EAX). (Если вы не в курсе, то нам нужно, чтобы в EAX была 1. Именно тогда произойдет переход по адресу 004065EE). Это 1 часть проверки.

Теперь нам все известно о рег. ключе: он должен состоять из 8 неповторяющихся букв английского алфавита. Остальные символы само собой отпадают, т.к. меняются на «А». Конечно, можно использовать и не только буквы, если в коде не будет больше символов «А». Но это уже никому ненужный гемор.

Во втором блоке происходят различные операции с нашим ключом - генерация, так сказать, контрольной суммы, от которой все и зависит. Этот алгоритм я описывать не буду.


И вот 3 блок:
00410798 |. 5F POP EDI
00410799 |> 33D2 XOR EDX,EDX
0041079B |. 8BC3 MOV EAX,EBX
0041079D |. B9 D3070000 MOV ECX,7D3
004107A2 |. F7F1 DIV ECX
004107A4 |. 85D2 TEST EDX,EDX
004107A6 |. 75 23 JNZ SHORT TourneyM.004107CB
004107A8 |. 8BC3 MOV EAX,EBX
004107AA |. B9 17000000 MOV ECX,17
004107AF |. F7F1 DIV ECX
004107B1 |. 85D2 TEST EDX,EDX
004107B3 |. 75 16 JNZ SHORT TourneyM.004107CB
004107B5 |. 8BC3 MOV EAX,EBX
004107B7 |. B9 05000000 MOV ECX,5
004107BC |. F7F1 DIV ECX
004107BE |. 85D2 TEST EDX,EDX
004107C0 |. 75 09 JNZ SHORT TourneyM.004107CB
004107C2 |. 5E POP ESI
004107C3 |. 5D POP EBP
004107C4 |. B8 01000000 MOV EAX,1
004107C9 |. 5B POP EBX
004107CA |. C3 RETN
004107CB |> 5E POP ESI
004107CC |. 5D POP EBP
004107CD |. 33C0 XOR EAX,EAX
004107CF |. 5B POP EBX
004107D0 \. C3 RETN


Здесь у нас и идет 2 часть проверки. Полученная контрольная сумма должна нацело делиться на 7D3h=2003 (нетрудно догадаться, в каком году писалась программа); на 17h=23 (а не возраст ли это автора программы?); на 5h=5 (а это, наверное, его любимая оценка:)). Если это будет так, то в EAX будет лежать 1, а если нет, то 0.

Вот мы и нашли все, что нам надо. Нужно, чтобы никогда не было перехода на адрес 004107CB. За это отвечают 4 перехода: один в 1 блоке (00410752) и три в 3 блоке (004107A6, 004107B3, 004107C0).

Это все, так сказать, была прелюдия к нашему брутфорсу. Думаю она не слишком вас утомила:)

:: Brute-force::
И так, как же будет работать наш брутфорс? Мы введем любые 8 символов, потом, если рег. код неверный, будем переходить не на адрес 004107CB, а на код самого брутфорса. В этом коде мы будем перебирать все символы справа на лево, примерно так:


AAAAAAAA
AAAAAAAB
AAAAAAAC
........
AAAAAABA
........
AAAAABAA


После увеличения кода на "1 символ" мы возвращаем новый код в процедуру проверки. И так до того, пока не подберем необходимый набор символов.

Теперь нужно найти место, где мы и будем писать сам брутфорс. Для этого подойдет конец файла, там как раз стоят одни нули. Значится, начнем писать с адреса 00412FB0. Но для начала необходимо поменять 4 уже известных нам перехода на 00412FB0.

Здесь тоже есть одно небольшое НО. Все эти 4 перехода представлены, как короткие (SHORT) переходники. И занимают 2 байта. Нам же нужно переходить дальше, чем на 128 байт, и понадобятся, соответственно, длинные, которые занимают 6 байт. Так что если мы напишем JNZ 00412FB0, то затрем нижестоящие 4 байта. В таком случае, мы сделаем переходник. После процедуры проверки есть свободные 14 байт, вот туда и запишем переходник. Я решил писать его по адресу 4107D3, а выглядит он просто: JMP 00412FB0. Так что в тех четырех местах меняем адреса, на адрес этого переходника (4107D3).

А теперь и сам код брутфорса. Чуть не забыл. Рег.код то мы будем перебирать, а где он хранится, так и не нашли. При проходе через процедуру проверки, видим, что по адресу, который лежит в ECX, находится наш код. Так что запоминаем это значение (0012F0C8). А вот теперь можно:



00412FB0 B9 C8F01200 MOV ECX,12F0C8 ; ASCII "ABCDEFGH" (1)
00412FB5 B8 07000000 MOV EAX,7 (2)
00412FBA FE0408 INC BYTE PTR DS:[EAX+ECX] (3)
00412FBD 803C08 5B /CMP BYTE PTR DS:[EAX+ECX],5B (4)
00412FC1 75 0A |JNZ SHORT TourneyM.00412FCD (5)
00412FC3 C60408 41 |MOV BYTE PTR DS:[EAX+ECX],41 (6)
00412FC7 48 |DEC EAX (7)
00412FC8 FE0408 |INC BYTE PTR DS:[EAX+ECX] (8)
00412FCB EB 01 |JMP SHORT TourneyM.00412FCE (9)
00412FCD 48 |DEC EAX (10)
00412FCE 83F8 FF |CMP EAX,-1 (11)
00412FD1 ^75 EA \JNZ SHORT TourneyM.00412FBD (12)
00412FD3 33F6 XOR ESI,ESI (13)
00412FD5 BD 08000000 MOV EBP,8 (14)
00412FDA ^E9 61D7FFFF JMP TourneyM.00410740 (15)


А теперь разберем каждую строчку.
(1) Ну, здесь кладем адрес рег.кода в регистр. А перебирать я начал с ABCDEFGH, т.е. его я ввел в программе.
(2) Так как символы мы будем проверять в цикле, то в EAX как раз количество повторов (счетчик). Т.е. 8, а 8 потому, что от 0 до 7.
(3) Увеличиваем нужный нам символ. А начинаем мы с последнего.
(4) Проверяем не вышли ли мы за границу («Z» имеет код 5A).
(5) Если вышли за границу, то идем дальше, а если нет, то прыгаем.
(6) Если мы вышли за границу, то, значит, перебрали все буквы данной позиции. И нужно, перейти на следующую слева позицию. А здесь поставить символ «A» (41).
(7) Уменьшаем счетчик на 1.
(8) И увеличиваем уже следующую слева букву.
(9) Здесь просто перепрыгиваем DEC EAX, т.к. счетчик мы уже уменьшили.
(10) Сюда мы попадем, если не перебрали все буквы позиции.
(11), (12) Это конец цикла.
(13) Цикл закончился, можно сразу переходить в процедуру проверки. Но вначале нее идут всякие подготовительные работы: сохранение в стек регистров, их обнуление, проверка. В стек нам больше сохранять ничего не надо, поэтому обнулим только регистр.
(14) Этой командой я заменил MOV EBP,DWORD PTR DS:[41A054], так как в по адресу 41A054 в данном случае у нас лежит 8.
(15) Ну и возвращаемся почти в начало нашей процедуры проверки кода на валидность.

Объяснить старался поподробнее. Но если все равно не понятно, то следует еще подучить ассемблер.

Ну, вот, в принципе, и все. Ставим бряк на 4107C2, т.к. дойдем до сюда, если все будет верно. И смело отпускаем прогу по F9.
Мгновение, а мы уже на 4107C2. Быстренько у нас и пароль подобрался. Теперь смотрим, что же по адресу 12F0C8 (Ctrl+G), а там правильный код. Переписываем эти циферки и переводим их в символы. Теперь перезапускаем прогу, вводим наши буковки, и юзаем программу на здоровье.

ВСЕ!!!

Статью добавил: Danger

Обсуждение статьи: Bruteforce для TourneyMaster 2.0.4 >>>


Комментарии к статье: Bruteforce для TourneyMaster 2.0.4

DragonT 18.07.2004 09:13:42
Попробуй сломай TourneyMaster 2.0.5
он Xtreme-Protector защищен. И вообще кто знает как с ним бороться напишите visor_12@bk.ru
---
Enzain 15.09.2005 10:33:51
А ключик готовый можно таки выложить? .. если не трудно ...
---
mister KO 24.09.2005 17:57:25
Да это конечно круто, ключик было бы не плохо (как усегда хотеца халявы) :)
---
kate 14.11.2005 13:12:04
Санечка ты лучший
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS