BEGINNER SOFTWARE'S DELPHI TOOLS 1.01 by NightCat \\ TEAM-53 Инструменты: UPX > 1.01, W32Dasm Музыка.....: Jaci Velasquez, The Game Это будет простенький туториал. Мы будем разбирать алгоритм генерации серийника! Сама программа довольно неплоха и, иногда, может сохранить некоторое кол-во времени. Советую попробовать. Ну а эта статья написана только в образовательных целях и только для образования, т.к. без образования ну просто никуда! =) Приступим. После установки проги я полез в её папку и посмотрел на екзешник. Он оказался упакован UPX'oм версиии 1.01. Распаковывается им же любой версии от 1.01. Я распаковывал версией 1.25.Теперь посмотрим на распакованный файл. Ну, стояло ожидать, что он будет написан на Делфи. =) Никаких крипто-алгоритмов замечено не было (thanks x3chun ;). Запускаем, ага, уже сразу в заставке видим, что программа не зарегана. Так-с, пройдёмся по пунктам, ага-ага, хм, угу, так-так, понятно. Вот, дошли до Registration, вводим что-нибудь и получаем ошибку. Ясно, запоминаем появившийся текст. Загружаем файлик во W32Dasm и топаем в уже привычное окошко String References. Находим наш текст и жмякаем по нему два раза и приземляемся тут вот: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0048E074(C) | :0048E15A 6A00 push 00000000 :0048E15C 668B0D0CE24800 mov cx, word ptr [0048E20C] :0048E163 B201 mov dl, 01 * Possible StringData Ref from Code Obj ->"Registration error! Try again!" | :0048E165 B838E24800 mov eax, 0048E238 :0048E16A E8DDAEFAFF call 0043904C :0048E16F 33D2 xor edx, edx :0048E171 8B83D0040000 mov eax, dword ptr [ebx+000004D0] :0048E177 E854DDF8FF call 0041BED0 :0048E17C 33D2 xor edx, edx :0048E17E 8B83DC040000 mov eax, dword ptr [ebx+000004DC] :0048E184 E847DDF8FF call 0041BED0 Так-с, сюда ведёт прыжок с 0048E074, ну значит нам туда! Скроллим вверх и вот что мы видим: :0048E05B 8D55F8 lea edx, dword ptr [ebp-08] :0048E05E 8B83D0040000 mov eax, dword ptr [ebx+000004D0] :0048E064 E837DEF8FF call 0041BEA0 :0048E069 8B45F8 mov eax, dword ptr [ebp-08] :0048E06C 5A pop edx :0048E06D E8C650FFFF call 00483138 <-- Вот она, бяка! :0048E072 84C0 test al, al :0048E074 0F84E0000000 je 0048E15A <-- Прыжок, если серийник не прошёл! :0048E07A B201 mov dl, 01 :0048E07C A1440C4400 mov eax, dword ptr [00440C44] :0048E081 E8BA2CFBFF call 00440D40 :0048E086 8BF0 mov esi, eax :0048E088 BA01000080 mov edx, 80000001 :0048E08D 8BC6 mov eax, esi :0048E08F E8402DFBFF call 00440DD4 :0048E094 B101 mov cl, 01 Итак, братья и сестры, всё ясно! По адресу 00483138 у нас процедура проверки серийника, заходим туда! Так-так: * Referenced by a CALL at Addresses: |:00486E23 , :0048E06D | :00483138 55 push ebp :00483139 8BEC mov ebp, esp :0048313B 83C4F8 add esp, FFFFFFF8 :0048313E 53 push ebx :0048313F 56 push esi :00483140 8955F8 mov dword ptr [ebp-08], edx :00483143 8945FC mov dword ptr [ebp-04], eax :00483146 8B45FC mov eax, dword ptr [ebp-04] :00483149 E89E0AF8FF call 00403BEC :0048314E 8B45F8 mov eax, dword ptr [ebp-08] :00483151 E8960AF8FF call 00403BEC :00483156 33C0 xor eax, eax :00483158 55 push ebp :00483159 68FD314800 push 004831FD :0048315E 64FF30 push dword ptr fs:[eax] :00483161 648920 mov dword ptr fs:[eax], esp :00483164 33F6 xor esi, esi :00483166 837DFC00 cmp dword ptr [ebp-04], 00000000 <-- оч интересно... :0048316A 7406 je 00483172 :0048316C 837DF800 cmp dword ptr [ebp-08], 00000000 <-- и познавательно :00483170 7504 jne 00483176 :00483166 837DFC00 cmp dword ptr [ebp-04], 00000000 Тут проверяется, чтобы первый символ серийника был НЕ МЕНЬШЕ единицы. :0048316C 837DF800 cmp dword ptr [ebp-08], 00000000 А тут, Чтобы последний символ был НЕ БОЛЬШЕ девяти! То есть, иными словами, все символы серийного номера должны быть цифрами... логично. =) Теперь скроллим вниз, пока не найдём вот такое вот чудо: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004831CE(C) | :004831B8 8B4DFC mov ecx, dword ptr [ebp-04] :004831BB 0FB64C01FF movzx ecx, byte ptr [ecx+eax-01] :004831C0 0FAFC8 imul ecx, eax :004831C3 8BD8 mov ebx, eax :004831C5 03DB add ebx, ebx :004831C7 0FAFCB imul ecx, ebx :004831CA 03F1 add esi, ecx :004831CC 40 inc eax :004831CD 4A dec edx :004831CE 75E8 jne 004831B8 Ё-хо-хо, так это ж алгоритм генерации серийного номера! Итак, давайте мы его разберём: movzx ecx, byte ptr [ecx+eax-01] - получаем символ имени. imul ecx, eax - умножаем этот символ на его номер в имени(первый, второй...) mov ebx, eax - присваеваем ebx номер символа в имени add ebx, ebx - складываем ebx с самим собой imul ecx, ebx - перемножаем наш символ с только что удвоенным ebx add esi, ecx - складываем результат с ESI inc eax - увеличиваем счётчик dec edx - проверяем, нет ли в имени еще одного символа jne 004831B8 - если есть, то всё повторяем Ну как? Понятно что-нибудь? Нет? Жаль, ну давайте разберём что-нибудь простое... например имя Cat. =) Итак, сначала переводим всё в HEX, Cat -> 43 61 74. Теперь берём первый символ (C), умножаем на его номер в имени, т.е. 1! 43 * 1 = 43. Т.к. ebx у нас тоже равен 1, то после сложения с самим собой он равен 2-м. Теперь мы умножаем 43 на 2, логично, что получаем 86. =) Далее второй символ "a" = 61. Он второй, следовательно умножаем его на два, 61 * 2 = C2. Складываем ebx + ebx = 2 + 2 = 4. Умножаем С2 на 4 = 308. Ну и последний символ "t" = 74. Он третий, умножаем 74 на 3 = 15C. Опять складваем ebx + ebx = 6, умножаем 15C на 6 = 828. Всё, теперь просто складываем получившиеся результаты. 86 + 308 + 828 = BB6. Вот и всё, всё очень просто. =) Ну а если без слов, то всё выглядит так... C -> 43 * 1 = 43 -> 43 * 2 = 86 a -> 61 * 2 = C2 -> C2 * 4 = 308 t -> 74 * 3 = 15C -> 15c * 6 = 828 86 + 308 + 828 = BB6 -> 2998 Для имени Cat серийный номер будет 2998. Ну, я надеюсь, теперь вам всё понятно. =) Кейген на самом деле написать очень просто, но это вы должны сделать, сами, если хотите, чему-то научиться. Делфи вам в помощь, программьте! Хочу вас обрадовать, кейген Будет работать с версии 1.0 по версию 1.2 т.к. алгорим один и тот же, дальше я не проверял. Ну вот и всё! Удачи! Читайте Team-53 Tutorials, программируйте, защищайте свои программы! NightCat \\ TEAM-53 www.bsuir.com