[ Интуиция крэкера ]

Взлом программ, многие думают что это трудно потому что пытаются сразу 
сломать большую программу с продуманной защитой, не понимая того что все 
приходит с опытом. Сегодня я с тобой поломаю крякмис, покажу как можно  сломать 
его разными способами, я буду как можно более понятнее комментировать код ассемблера 
что бы хоть что то понял. Что нам нужно для взлома? отладчик Ollydbg и все :) и конечно
же крякмисы где их взять? сайт crackmes.de качай тренируйся. И так 
давай сначала скачаем крякмис от Skapunky его название CrackMe Renascense 1, 
запускаем видим окошко о воде имени и пароля, тут защита reg/codename то есть 
пароль генерируется от имени пользователя. Почему я так решил? ты поймешь в ходе 
взлома, и так вводим любое имя и пароль тыкаем на register и получаем сообщение 
"Sorry, password Incorrect". И что дальше спросишь ты меня? ;) Давай загрузим наш 
крякмис в отладчик, в нем нажмем правой кнопкой и в меню выберим 
"Search For -> All referenced text strings". Откроется окно в нем ищем сообщение о не 
правильном коде, оно почти в самом незу, как только найдем его тыкнем по нему два раза и 
окажемся тут:

0040A8F8   . C785 E8FEFFFF >MOV DWORD PTR SS:[EBP-118],CrackMe_.0040>;  UNICODE "Sorry, password Incorrect"  <- Мы тут

Так дальше будем искать код генерации серийника, он как правило будет выше. Почему выше а не в незу? Скажу так, 
обычно когда программеры пишу программы они в начале кодят код проверки если код 
совподает с вложеным кодом то код проверки переходит на сообщение о 
правильном вводе если же нет то о не правильном смекаешь? ;) И так листаем вверх и 
находим сообщение о правильной регистрации:

0040A81B   . C785 E8FEFFFF >MOV DWORD PTR SS:[EBP-118],CrackMe_.0040>;  UNICODE "Good, this version is registrered !" <-Сообщение о правильной реге

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

0040A7BE   . 85C0           TEST EAX,EAX                                 <- Сравнение двух регистров
0040A7C0     0F85 DD000000  JNZ CrackMe_.0040A8A3            <-Прыжок на код о не правильном вводе

Почему я решил что прыжок прыгает к вызову о неправильном вводе? 
Посмотри ниже куда прыгает этот вызов и ты увидишь такой код:

0040A8A3   > C745 FC 1C000000      MOV DWORD PTR SS:[EBP-4],1C  <- Куда мы прыгаем
0040A8AA   . C785 28FFFFFF 0400028>MOV DWORD PTR SS:[EBP-D8],80020004
0040A8B4   . C785 20FFFFFF 0A00000>MOV DWORD PTR SS:[EBP-E0],0A
0040A8BE   . C785 38FFFFFF 0400028>MOV DWORD PTR SS:[EBP-C8],80020004
0040A8C8   . C785 30FFFFFF 0A00000>MOV DWORD PTR SS:[EBP-D0],0A
0040A8D2   . C785 D8FEFFFF 7C8F400>MOV DWORD PTR SS:[EBP-128],CrackMe_.00408F7C       ;  UNICODE "CrackMe"
0040A8DC   . C785 D0FEFFFF 0800000>MOV DWORD PTR SS:[EBP-130],8
0040A8E6   . 8D95 D0FEFFFF         LEA EDX,DWORD PTR SS:[EBP-130]
0040A8EC   . 8D8D 40FFFFFF         LEA ECX,DWORD PTR SS:[EBP-C0]
0040A8F2   . FF15 BC104000         CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarDup>]        ;  MSVBVM60.__vbaVarDup
0040A8F8   . C785 E8FEFFFF 908F400>MOV DWORD PTR SS:[EBP-118],CrackMe_.00408F90       ;  UNICODE "Sorry, password Incorrect" 

Ты скажешь ну и что? все равно не понимаю почему имено он прыгает к коду о вызове о 
неправильном воде скажешь ты, так давай проверим так ли это поставим на адресс куда мы 
прыгнули брэкпоинт, это можно сделать двумя способами прописать в Command Bar "bpx 0040A8A3" 
или перейти на строку и нажать F2 тем немения ставим бряку и нажимаем F9 для запуска программы 
и набираем все что попало и тыкаем register и поподаем сюда:

0040A8A3   > C745 FC 1C0000>MOV DWORD PTR SS:[EBP-4],1C <- Сработала точка останова

А ниже ты видишь код с сообщением о неправильном вводе ;) И так давай подумаем ведь где 
то должен быть вызов для генерации серийника, так думаем до сравнения регистров есть вызов:

0040A7B8   . FF15 68104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCmp>]      ;  MSVBVM60.__vbaStrCmp <-Вызов генерации серийника

Ага после него идет test eax, eax давай проверим верно мы думаем или нет? 
выше этого вызова поставим бряк на вызов:

0040A7A0   . FF15 A8104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>] ;  MSVBVM60.__vbaFreeStrList <-Ставим бряк

Теперь запускаем программу с помощью F9 и вводим в поля имя и ложный серийник и нажимаем 
register и оказываемся на нашем бряке :)
ты опять скажешь и что? А дальше мы стобой начнем трассировку программы с помощью F8 
трассировать программу без захода в подпрограмму, и так трассируем программу до:

0040A7B8   . FF15 68104000         CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCmp>]        ;  MSVBVM60.__vbaStrCmp <- Тут мы нажимаем F7

Как видеш после этой строки идет проверка регистров, самое время нажать F7 трассировка 
программы с заходом в подпрограмму и окажемся в коде генерации серийника, давай посмотрим в 
окошко registers FPU там мы увидим код для нашего имени,если нет жми F8 и код появится в окошке 
registers FPU трассируй программу до:

660E8A12   C2 0800                 RETN 8

Почему до сюда спросишь ты меня? потому что когда мы попадем на этот код мы попадем сюда:

0040A7BE   . 85C0                  TEST EAX,EAX <- Мы опять тут ;)

Знакомый код не так ли? ;) И так  ты видел что код сгенирировался от твоего имени, я 
искал серийник для ника outlaw и получил ska6683330 теперь осталось тока проверить его, 
закрываем программу и открываем наш крякмис и вводим свои данные, я ввел outlaw и ska6683330 и 
увидел сообщение от которого появляется легкая улыбка "God, this version is registered !". Так 
почему эта программа имеет защиту reg/codename а вот давай проверим, я ввел в полях Outlaw и 
ska6683330 и получил сообщение "Sorry, password Incorrect" потому что код генерировался для 
outlaw, а между Outlaw и outlaw есть разница :).
Второй способ взлома этого крякмиса, теперь мы знаем что 
"0040A7C0     0F85 DD000000  JNZ CrackMe_.0040A8A3" прыгает на код о вызове о неправильной 
регистрации, а если мы сделаем так что бы прыжка не было? Проще говоря мы занопим прыжок, 
то есть поставим NOP(Означает нет операции), для этого грузим наш отладчик переходим к 
нашему прыжку и нажимаем по меню правой кнопкой в меню выбираем "Binary -> Fill With NOPs" 
после этого увидим 6 nop`ов в место прыжка, после этого нам надо модифицировать файл опять 
нажимаем правой кнопкой и выбираем "Copy to executable -> All Modifications" появится окошко 
в нем нажимаем "Copy All" Появится окно с нашим новым кодом, в нем опять ;) же нажимаем правой 
кнопкой и выбираем "Save File" и выбираем куда сохранить файл, меняем ему имя если сохроняем в 
папку со старым крякмисом и тыкаем "Сохранить", после этого запускаем наш новый крякмис и вводим 
любыем имена и серийники и мы всегда будем видеть "God, this version is registered !" :) Легко не правда ли?

Тренеровка тренеровкой, а дело делом!
И так мы стобой взломали крякмис давай проверим полученые нами знания на какой нить программе? 
Это будет интересно, я выбрал старую программу которую я взломал первый раз после крякмисов, у 
нее появилась новая версия и это для нас плюс кароче что я говорю давай ломать :). И так сайт 
программы www.ronimusic.com программа "Audio Companion 1.5.4" И так давай запустим нашу 
программу и что мы видим? После загрузки перед нами окошко которое говорит что бы мы 
посмотрели файл order.txt но мы конечно кладем большой и толстный на него ) и открываем 
панель ввода пароля "Help->Password.." вводим любой пароль и сообщение "Invalid Password" 
Закрываем программу и грузим ее в отладчик и ставим бряку на MessageBoxA то есть так 
"bpx MessageBoxA" что было понятно MessageBoxA это API функция для вывода диологовых окон, 
как наше о неправильном пароле, у нас есть лишнии бряки нажимаем F9 останавливаемся снимаем 
бряк с помощью F2 и дальше в том же духе до кода:
00404C69   . FF15 EC244700  CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA  <- Вызов 
сообщения о неправильном воде
И так мы нашли сообщение о неправильном вводе в окошке register FPU видно это сообщение :) Тут 
мы делаем как делали в крякмисе ищим код проверки листаем вверх и видим:

00404B7C   . FF15 34244700  CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
00404B82   . E8 F9FDFFFF    CALL Audiocom.00404980 <-Вызов проверки кода
00404B87   . 85C0           TEST EAX,EAX <-Сравнение регистров
00404B89   . 0F84 84000000  JE Audiocom.00404C13 <-Прыжок на сообщение о неправильной регистрации

И так этот код нам более менее понятен простыми проверками мы можем проверить что наша 
интуиция нас не подведет :) И так нам надо попасть в код проверки пароля куда же нам поставить 
бярку? Правильно если вызов CALL Audiocom.00404980 то что бы попасть в подпрограмму с помощью F7 
надо поставить бряк на 

00404B7C   . FF15 34244700  CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA <- Ставим бряк

После того как мы поставим бряк перезагружаем программу с помощью ctrl+F2 и запускаем F9, вводим в 
панели пароля любой пасс и останавливаемся тут:

00404B7C   . FF15 34244700  CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA <-Бряк сработал

Нам осталось только нажать один раз F8 и как мы только попадем на CALL Audiocom.00404980 нажмем F7 и 
попадем в процедуру проверки пароля и начнем трассировку до:

00404980  /$ 83EC 24        SUB ESP,24 <-Отсюда начинается проверка кода
00404983  |. A1 7CF94900    MOV EAX,DWORD PTR DS:[49F97C]
00404988  |. 33C4           XOR EAX,ESP
0040498A  |. 894424 20      MOV DWORD PTR SS:[ESP+20],EAX
0040498E  |. E8 1DFEFFFF    CALL Audiocom.004047B0
00404993  |. 8D1424         LEA EDX,DWORD PTR SS:[ESP]
00404996  |> 8A08           /MOV CL,BYTE PTR DS:[EAX]
00404998  |. 880A           |MOV BYTE PTR DS:[EDX],CL
0040499A  |. 83C0 01        |ADD EAX,1
0040499D  |. 83C2 01        |ADD EDX,1
004049A0  |. 84C9           |TEST CL,CL
004049A2  |.^75 F2          \JNZ SHORT Audiocom.00404996
004049A4  |. 8D0424         LEA EAX,DWORD PTR SS:[ESP]
004049A7  |. 50             PUSH EAX
004049A8  |. E8 C3CC0000    CALL Audiocom.00411670
004049AD  |. 83C4 04        ADD ESP,4
004049B0  |. B9 9C1C4A00    MOV ECX,Audiocom.004A1C9C                ;  ASCII "45645" <- Тут лежит наш код

Как только мы окажемся на адресе 004049B0  |. B9 9C1C4A00    MOV ECX,Audiocom.004A1C9C сразу 
посмотрим в окошко registers FPU и увидим такой код U6c-7M-zDy-45 осталось только проверить правильный 
ли код или нет? :) Что мы и делаем вводим код  и видим "Thanks for registerind!" Неужели я сломал один 
крякмис и смог сломать уже простую shareware программу? скажешь ты :) Скажу тебе одно что практика и 
тренеровка лучший способ чего нить добится я тебе показал как это возможно, конечно во второй программе 
мы уже ставили бряк на апи функции я специально не говорил он них в первой части статьи что бы хоть что 
нить показать нового во второй части. Ты конечно понимаешь как можно взломать эту программу другим спомобом 
а ну ка, что ты будешь делать с 00404B89   . 0F84 84000000  JE Audiocom.00404C13 ;)
От Автора: Конечно взлом программ для многих кажется не интересным занятием, но знание крэкинга а имено 
искусство взлома программ пригодится тебе в будующем, даже если ты решишь стать программистом :) 
Извиниясь за большие вставки асм кода, но куда же без него. Последний код где идет сравнения пароля я не 
прокоментировал если тебе интересно то пиши, я напишу тебе что и как ;) И на этой ноте я прощаюсь с вами  :) 
до новых встреч с вами был Outl@w.

(c) Outlaw