суббота, 4 апреля 2026 г.

Первое крекми с Главы 15.

Название главы: «Глава 15 - Поиск жестко заданного серийного номера. Часть 3»

Найти рассматриваемые крекми и уроки можно на сайте GitHub, гуглите "Уроки по ollydbg Рикардо Наваха" и переходите на GitHub к пользователю  в папку /.gitbook/assets/files/14 

Посмотрим на нашего подопытного: 

  • Называется сие чудо: Splish.exe; 
  • Точный вес: 232 KB (237.568 byte) (Такой вес благодаря картинке в ресурсах);
  • Распознан по имени окна: "Splish, Splash";
  • Дополнительная информация: "
  • Your mission is to disable the Splash Screen, find the hardcoded serial

    and to keygen the Name/Serial part.  This level is to make sure you understand

    how to use your tools and what is going on in the program.  These are three very

    basic and easy protections.  Good luck and see you on the next level.

    Crudd

    "; 

  • Дата создания: четверг ‎28 ‎марта ‎2002, ‏‎14:27:56
  • Компилятор: MASM(6.14.8444)[MMX2 support]
  • Язык: x86 Assembler 
  • Автор: Crudd. 
  • Задачи: Убрать заставку, Найти Hardcoded ключ, Написать кейген к Name/Serial части.

  • 1. Убираем заставку:

    Открываем наш EXE в olly или x32dbg, далее смотрим список импортируемых функций или  ставим брейкпоинт в командной строке. Можно брать любую или ShowWindow (момент показа окна) или СreateWindowExA (момент создания окна) или GetTickCount (используется для задержки показа окна). Трассируем до возврата из функции (до команды ret). 
    Попадаем сюда:
     
    0040105E6A 01push 1
    00401060E8 BF060000call <JMP.&GetSystemMetrics>
    0040106550push eax
    00401066FF35 73344000push dword ptr ds:[403473]
    0040106CE8 F0030000call splish.401461
    00401071A3 7B344000mov dword ptr ds:[40347B],eax
    00401076FF75 08push dword ptr ss:[ebp+8]
    00401079E8 F9030000call splish.401477<--- наша функция
    0040107EC745 D0 30000000mov dword ptr ss:[ebp-30],3030:'0' <--- попадаем сюда
     
    Теперь надо вызов нашей функции пропатчить nop командами. Нажимаем на строчку c функцией -> Двоичные операции -> Заполнить командами NOP -> OK. Файл -> Исправить файл -> Исправить файл.  (для x32dbg). Также можно пропатчить в любом Hex редакторе, просто ищем байты E8F9030000С7 и заменяем на 9090909090С7. 
     

    2. Находим Hardcoded ключ:

    Открываем наш EXE в olly или x32dbg, ставим брейкпоинт на GetWindowTextA (так программа получает введённую строку с edit). Далее F9, жмем пока появится окно, потом вводим какой-то ключ жмем кнопку Check Hardcoded, трасируем пока не, попадаем сюда:
     
    0040135F68 15324000push splish.403215
    00401364FF35 90344000push dword ptr ds:[403490]
    0040136AE8 BB030000call <JMP.&GetWindowTextA>
    0040136F8D05 53134000lea eax,dword ptr ds:[401353]00401353:"HardCoded" <---- сюда 
    004013758D1D 15324000lea ebx,dword ptr ds:[403215]<---- наш код
    0040137B8038 00cmp byte ptr ds:[eax],0eax:"HardCoded"
    0040137E74 0Cje splish.40138C
    004013808A08mov cl,byte ptr ds:[eax]eax:"HardCoded"
    004013828A13mov dl,byte ptr ds:[ebx]
    0040138438D1cmp cl,dl<--- посимвольное сравнение нашего кода
    0040138675 4Ajne splish.4013D2со строкой "HardCoded"
    0040138840inc eaxeax:"HardCoded"
    0040138943inc ebx
    0040138AEB EFjmp splish.40137B
    0040138CEB 2Fjmp splish.4013BD
     

    3. Пишем кейген к Name/Serial части:  

    Опять мне возвращаться нужно к этому crackme, он мне уже надоел, то что я его решил ещё хрен знает когда (3 дня назад) и теперь опять...
    Расчехляем отладчик (x32dbg), ставим брейкпоинт, на уже полюбившейся нам функцию GetWindowTextA, жмем F9 до появления окна, далее вводим данные, нажимаем ок, и  очутились в функции GetWindowTextA, трассируем до возврата в нашу программу видим это:
     
    0040160DE8 18010000call <JMP.&GetWindowTextA><--- наш брейкпоинт
    0040161285C0test eax,eax
    0040161474 68je splish.40167E
    00401616A3 63344000mov dword ptr ds:[403463],eax
    0040161B33C9xor ecx,ecx
    0040161D33DBxor ebx,ebx
    0040161F33D2xor edx,edx
    004016218D35 36324000lea esi,dword ptr ds:[403236]esi:"3058561", 00403236:"mackswe"
    004016278D3D 58324000lea edi,dword ptr ds:[403258]а это промежуточная переменная для вычислений
    0040162DB9 0A000000mov ecx,A0A:'\n'
    004016320FBE041Emovsx eax,byte ptr ds:[esi+ebx]"Генерация по имени" берём посимвольно
    0040163699cdq
    00401637F7F9idiv ecxделим на десять name[i] символ
    0040163933D3xor edx,ebxманипуляции с остачей от деления
    0040163B83C2 02add edx,2манипуляции с остачей от деления
    0040163E80FA 0Acmp dl,A0A:'\n'
    004016417C 03jl splish.401646
    0040164380EA 0Asub dl,Aесли остача больше или равно 10, отнимаем 10
    0040164688141Fmov byte ptr ds:[edi+ebx],dlсохраняем наш байт в промежуточную переменную
    0040164943inc ebx
    0040164A3B1D 63344000cmp ebx,dword ptr ds:[403463]конец строки? Нет?
    0040165075 E0jne splish.401632Значит возвратимся для генерации байтов перемеременной
    0040165233C9xor ecx,ecx
    0040165433DBxor ebx,ebx
    0040165633D2xor edx,edx
    004016588D35 42324000lea esi,dword ptr ds:[403242]esi:"3058561", 00403242:"3058561"
    0040165E8D3D 4D324000lea edi,dword ptr ds:[40324D]промежуточная переменная которая будет сравнена с др. перемен.
    00401664B9 0A000000mov ecx,A0A:'\n'
    004016690FBE041Emovsx eax,byte ptr ds:[esi+ebx]генерация по паролю посимвольно
    0040166D99cdq
    0040166EF7F9idiv ecxделим код символа на 10 и
    0040167088141Fmov byte ptr ds:[edi+ebx],dlсохраняем
    0040167343inc ebx
    004016743B1D 67344000cmp ebx,dword ptr ds:[403467]сравнение с длиной имени
    0040167A75 EDjne splish.401669возвращаемся пока не конец имени
     
    Вот такой кусок я вам приготовил, тут идёт генерация двух массивов байтов которые потом будут сравнены и если будут равны тогда ключ подойдёт. И вот собственно сравнение:
     
    004016BE0FBE041Fmovsx eax,byte ptr ds:[edi+ebx]  
    004016C20FBE0C1Emovsx ecx,byte ptr ds:[esi+ebx]esi+ebx*1:"058561"
    004016C63BC1cmp eax,ecx<-- сравнение наших сериалов посимвольно
    004016C875 18jne splish.4016E2
    004016CA43inc ebx
    004016CBEB E9jmp splish.4016B6
    004016CD6A 00push 0
    004016CF68 0A304000push splish.40300A40300A:"Splish, Splash"
    004016D468 42304000push splish.403042403042:"Good job, now keygen it."
    004016D96A 00push 0
    004016DBE8 68000000call <JMP.&MessageBoxA>
    004016E0EB 13jmp splish.4016F5
    004016E26A 00push 0
    004016E468 0A304000push splish.40300A40300A:"Splish, Splash"
    004016E968 67304000push splish.403067403067:"Sorry, please try again."
    004016EE6A 00push 0
    004016F0E8 53000000call <JMP.&MessageBoxA>
    004016F5C9leave
    004016F6C2 0800ret 8
     
    Я не буду разбирать что там по длине, так как мне лень, вроде как длина Serial должна быть равна длине Name. Кейгеним: 
    1. Посивольно берём имя;
    2. Получаем последнее число символа для каждого символа по очереди в десятичной системе (делим на десять и получаем остаток);
    3. Для полученого остатка для каждого символа, применяем  команду xor <остаток>, <индекс символа в строке> (нумерация индекса начинается с нуля);
    4. Далее к этому байту добавляем двойку;
    5. Теперь если наш байт (остаток по сути), больше равно 10 тогда отнимаем 10, и сохраняем байт. И так для каждого символа Name; 
    6. И теперь каждое полученное число должно равняться, последнему числу кода символа нашего Serial. 

    При таких условиях, для одного имени можно генерить сотни а то и тысячи Serial, но мы не будем в это углубляться так как задача уже выполнена.   

    Интерфейс программы 

     Обращайтесь если нужно, могу скинуть листинг кейгена написаного на Delphi 7.

     

    Комментариев нет:

    Отправить комментарий

    Глобал близко? ч.2

    Ну что глобал близко? Ну он не просто близко, а уже есть! Сейчас глянул, это было: 17 мая в 1:04. После того на втором  аккаунте сняли супр...