Данный keygenme довольно простой, но тем не мнение, рассмотрим именно его, думаю новичкам будет интересно. В качестве отладчика будем использовать всеми любимый OllyDbg)) Скачать ASM KEYGENME#1 можно тут: http://crackmes.de/users/libertyorde...enme1/download
Из названия подопытного, ясно чем нам придется заняться.
Перед тем как его перейти к реверсингу, запускаем его, и смотрим как он работает. После чего открываем его в отладчике.
Видим следующие:



Не трудно догадаться, что файл зашифрован, причем не очень хорошо. В самом начале видим прыжок на 004011AE, ПКМ – Follow. Попадаем на фрагмент кода декриптора . Так как, сейчас нам это мало интересно, пропустим этот фрагмент, нажимаем F9. Запускается программа..
Дальше в отладчике, нажимаем Ctrl + A или ПКМ – Analysis – Analysis code;
После чего в окне отладчика появляется основной код, нашего keygenme :

Начнем пожалуй с того, что посмотрим WinAPi функции, используемые тут, нажимаем
Ctrl + N или Search for – Name(Label) in current module. Видим следующие:

Там интересны только, GetDlgItemTexaA ( получение текста, например из поля ввода..), MessageBoxA ( вывод сообщения) и на последок wsprintfA( сравнение строк), что уже на данном этапе дает нам понять, что кейгенми довольно простой.
Остановимся на GetDlgItemTexaA .
Выбираем его, после чего ПКМ – Toggle Breakpoint on Import. Теперь при вызове этой функции программой, произойдет ее остановка, дабы дать нам возможность “осмотреться”.
Переходим к нашей запущенной программе, вводим любое имя, с серийником, в моем случаи Fairhawk;123456, нажимаем «ОК».
После чего программа останавливается, т.к срабатывает наша точка останова, что бы убедиться в этом смотрим в нижний левый угол отладчика на строку состояния, и видим там: «Breakpoint at user32.GetDlgItemTexaA.
Смотрим что у нас находиться в стеке:

Давайте обратим внимание на выделенную зеленным цветом строчку. Тут указывается на некий буфер, куда по идеи должно занестись выполнение нашей функции. Выделяем данную строчку, и нажимаем ПКМ – Follow in Dump.

Видим что тут пока не чего нет, т.к мы остановили нашу программу только на начале функции, и она еще не успела выполниться. Нужно это исправить.
Выделяем строку где произошла наша остановка, и нажимаем F2, что снимет от туда Breakpoint.
После чего ставим новый, на конце этой функции:

Опять же нажатием F2 ( хотя если ты читаешь этот материал, то ты наверняка знаком с этим ;) ) ставим новую точку останова.
Нажимаем F9, и наш keygenme снова останавливается, но только уже на другом месте )
Снова смотрим на наш адрес в дампе..

Видим что, наша функция выполнилась, и теперь по адресу находиться то, что мы ввели в поле ввода «Name» !) Запоминаем адрес, думаю он нам пригодиться )
Убираем Breakpoint, и нажимаем F7 что бы выйти из функции.
Останавливаемся на строчке:
MOV DWORDPTRDS:[403100],EAX
Которая заносит результат выполнения функции ( в данном случаи количество символов), в «ячейку» по адресу 403100. После чего EAX обнуляется, командой :
XOR EAX,EAX.
Нажимаем ПКМ на MOV DWORD PTR DS:[403100],EAX– Follow Dump – Memory address. И видим что там тоже пусто. Но стоит нам выполнить данную команду нажатием F7, как видим там:

Число 8, в моем случаи количество символов в слове «Fairhawk») Также «запоминаем» адрес.)
Чуть ниже, видите еще один вызов GetDlgItemTexaA, в точности похожею на первый:

Красным цветом выделен, первый, нами разборный, вызов этой функции. Заметим так же, что тут в строчке :
PUSH ASM_KEYG.004030C0
И указывается, тот адрес, куда и заноситься наше имя, в моем случаи «Fairhawk»)
Во втором, вызове видим подобное:
PUSH ASM_KEYG.004030E0
Следовательно туда наверняка будет заноситься наш серийник . Давайте это проверим, ставим точку останова сюда:

Нажимаем F9. После чего ПКМ на PUSH ASM_KEYG.004030E0– Follow Dump –Immediate constant.
Как видите, наши предположения оправдались:

Там действительно находиться наш серийный номер).
Убираем, точку останова, нажимаем ПКМ на MOV DWORD PTR DS:[403128],EAX– Follow Dump – Memory address, после чего F7,и видим что 403128 находиться число 6 ) длина нашего серийника).
Теперь осталось выяснить, где используется наши числа (6 и 8)…
Cделаем так, найдем в дампе первое (8), после чего выполняем следующие:
Это тот же Breakpoint, только ставиться он на определенный участок в дампе, который срабатывает при любом вызове к этому адресу. И так, убираем наш предыдущую точку останова, и нажимаем F9.
Останавливаемся тут:

Тут и видим CMP DWORD PTR DS:[403100],0 обращение к нашему адресу(где у нас находиться длина нашего имени – 8 ), в данном случаи, происходит проверка, «если по адресу 403100 находиться 0, то вывести пользователю не приятное сообщение).
Чуть выше тоже самое, но уже с адресом 403128 (длина поля для серийника – 6).
После того как программа убеждается, что поля не пустые, выполняется выделенный красным цветом код..
Перед тем как разбирать его, уберем наш Breakpoint , который расположен в дампе. Делается это так, ПКМ – Breakpoint- Remove memory Breakpoint, все )
Первые 4 строчки в выделенной рамки, Обнуляют ESI, ECX, а в EDX заноситься 0A (10);
Ну а после чего, собственно идет генерация гуд серийника ) . Весь его разбирать смысла я не вижу, так что расскажу только основные моменты.
MOVS XEAX,BYTE PTR DS:[ECX+4030C0] – Начало цикла, где берется первый символ нашего имени, после чего выполняется, сам алгоритм генерации ключа, до момента:
CMP ECX,DWORD PTR DS:[403100]
JNZ SHORT ASM_KEYG.00401137
Где проверяется, всели буквы были «пройдены» . После чего результат заноситься в стек, из регистров EDI и ESI.
Затем вызваться функция wsprintfA для преобразования, всего этого в нужный нам формат:
"LOD-%lu-%lX". Затем проверка на правильность нашего, и сгенерированного недавно ключа тут:

Поставим Breakpoint там, где это сделал я.
Нажмем F9.
И видим что нам приходиться сравнивать))

В String1 находиться нужный нам серийник).
CMP EAX,0
Если наш серийник правильный, то в EAX должен оказаться 0.
Давайте проверим это. Убираем точку останова, нажимаем F8(тоже самое что и F7, только не заходит внутрь функций).

Как видите зеленым выделено подтверждение того, что наш серийник не правильный, иначе бы там было 0 )). И флаг Z будет содержать 0, после чего выполниться переход выделенный синим цветом, к плохому сообщению, затем программа закроется.
Перед тем как писать не посредственно keygen давайте проверим то, что я сейчас сказал).
Нажимаем 2 раза F7, пока наш курсор не окажется на:
JNZ SHORT ASM_KEYG.00401191
Как видите, красная линия показывает что он выполниться, смотрим куда.. и видим что к не очень хорошему для нас сообщению.
Кликаем 2 раза на флаг Z:

И видим что переход стал тусклым, что означает, что «прыжка» не будет, а вместо этого выполниться строчка под ним. Давайте посмотрим, нажимаем F9!!!
И как нашей радости видим что программа говорит нам, о том что серийник правельный)
Осталось только написать keygen. Все что нам для этого нужно, так это взять кусок кода генерации, а именно :
XOR ESI,ESI
XOR ECX,ECX
XOR EDX,EDX
MOV ECX,0
MOV EDX,0A
MOVSX EAX,BYTE PTR DS:[ECX+4030C0]
INC EAX
ADD EAX,EDX
ADD ESI,EAX
INC ECX
IMUL EDX,ECX
MOV EDI,EDX
IMUL EDI,ESI
CMP ECX,DWORD PTR DS:[403100]
JNZ SHORT ASM_KEYG.00401137
И переделать под свои нужды.
Скачать написанный мной keygen на masm32 ты можешь скачать ТУТ. Он слегка сыроват, но зато исправно работает))
Из итог наверное то, что кто то укрепил свои знания в реверсинге, ну или дал лишний повод убедиться какой он крутой, сказав себе «Та, я это и так знаю»))))
В любом случаи удачи!)
Вопросы оставляем в коментах )
Топики на форумах для обсуждения:
forum.antichat.ru
forum.hackzona.ru
forum.xakep.ru
Данный материал может свободно распространяться, при условии указания автора