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

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


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

Исследуем Lavalys Everest Ultimate Edition 2006 v.3.01.652 и пишем KeyGen

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

Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник от EXELAB - вот тут.

Автор: RSI <RS1@tut.by>


Привет Всем! Как уже принято писать начинающим в этом «нелегком» деле, «Это моя первая статья….» и т.д. и. т.п., поэтому не будем особо на этом останавливаться, просто отнеситесь к этому с пониманием! И к орфографии, которая периодически хромает... ;)

И так приступим, нам понадобится:
1) OllyDbg 1.10
2) PEiD v0.93
3) Visual C++ 6.0 SE (для написания Keygen)
4) UPX 1.90w
5) И немножко выдержки и терпения

О самой программе: (сайт проги www.lavalys.com)
Эта программа для диагностики и теста вашего железа ,там еще есть всякие полезные фичи… В целом прикольная программа иногда приходится пользоваться :)

Что нам не нравится:
1) Выскакивает NAG окно из трея где написано, что это Триал
2) В заголовке окна присутствует надпись [Trial version]
3) Не выводится некоторая информация о системе и железе
4) Срок действия программы 3 месяца

Ну чтож попробуем от этого избавится!!!

Проверка программы на упакованность:

PEiD нам показывает UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo,

но только настораживает что размер такого exe файла всего 42 Kb, для такой многофункциональной программы это очень мало
(скорее всего программа либо юзает DLL или где-то еще есть исполняемый модуль), ну ладно, не будем загоняться, а посмотрим что там!
Для распаковки используем UPX 1.90w (т.к. 1.24 у меня отказался ее распаковать)!

В командной строке пишем: upx.exe –d everest.exe (теперь размер распакованного файла 75 Кб)

Итак грузим распакованный everest.exe в OllyDbg и немножно потрейсим по F8, Дойдем вот до такой функции:

004015E1   > 6A 0A          PUSH 0A
004015E3   . 59             POP ECX
004015E4   > 51             PUSH ECX                                 ; /Arg4
004015E5   . 50             PUSH EAX                                 ; |Arg3
004015E6   . 6A 00          PUSH 0                                   ; |Arg2 = 00000000
004015E8   . 68 00004000    PUSH everest.00400000                    ; |Arg1 = 00400000
004015ED   . E8 0EFAFFFF    CALL everest.00401000                    ; \everest.00401000

После нее запускается наша программа, поэтому интересно посмотреть, что эта функция делает. Для этого на адрес 004015ED ставим бряк(F2)
и перезапускаем программу (Ctrl+F2), нажимаем F9 чтобы запуститть программу, прервались на нашем бряке, теперь чтобы зайти во внутрь функции нажимаем F7, и дальше продолжаем трейсить по F8, идем дальше и натыкаемся на такой кусок:

0040117A  |. 50                  PUSH EAX                                 ; /pProcessInfo
0040117B  |. 8D8D 50FEFFFF       LEA ECX,DWORD PTR SS:[EBP-1B0]           ; |
00401181  |. 51                  PUSH ECX                                 ; |pStartupInfo
00401182  |. 6A 00               PUSH 0                                   ; |CurrentDir = NULL
00401184  |. 6A 00               PUSH 0                                   ; |pEnvironment = NULL
00401186  |. 6A 00               PUSH 0                                   ; |CreationFlags = 0
00401188  |. 6A 01               PUSH 1                                   ; |InheritHandles = TRUE
0040118A  |. 6A 00               PUSH 0                                   ; |pThreadSecurity = NULL
0040118C  |. 6A 00               PUSH 0                                   ; |pProcessSecurity = NULL
0040118E  |. FF15 08804000       CALL DWORD PTR DS:[<&KERNEL32.GetCommand>; |[GetCommandLineA
00401194  |. 50                  PUSH EAX                                 ; |CommandLine
00401195  |. 68 90B44000         PUSH everest.0040B490                    ; |ModuleFileName = ""
0040119A  |. FF15 04804000       CALL DWORD PTR DS:[<&KERNEL32.CreateProc>; \CreateProcessA
004011A0  |. 85C0                TEST EAX,EAX
004011A2  |. 74 2A               JE SHORT everest.004011CE
004011A4  |. 68 5C814000         PUSH everest.0040815C                    ;  ASCII "/WAIT"
004011A9  |. 8B55 10             MOV EDX,DWORD PTR SS:[EBP+10]
004011AC  |. 52                  PUSH EDX

Немного теории:
Функция CreateProcessA – создает новый процесс, из исполняемого файла! То есть в данном случае эта функция запускает файл everest.bin
(как исполняемый .exe)! Значит, как мы и предполагали, главный исполняемый файл – это everest.bin, поэтому закрываем файл в OllyDbg (Alt+F2),
удаляем файл everest.exe, он нам больше не нужен, затем переименовываем файл everest.bin в everest.exe - далее мы будем работать уже с ним!
Он тоже запакован UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo, но у этого размер уже посолидней (1,5 Mb) :) !!! Продолжаем…

Распакуем его, для этого опять пишем: upx.exe -d everest.exe

Смотрим в PeiD и видим Borland Delphi 6.0 - 7.0 – это хорошо! (Теперь после распаковки файл весит аж 4,5 Mb)

Итак грузим файл в OllyDbg и запускаем(F9). Все запустилось…
Ну что будем регить? Но есть загвоздка - нет вкладки для ввода серийника… :(

Ну что попробуем подумать ( логика так сказать :) )! Значит при запуске прога проверяет наличие какого-нибудь ключа
после чего появляются надписи [Trial Version]!

Полез в инет посмотреть мож есть кряки на ранюю версию этой проги и скачал keygen powered by VRL forse (для версии 2.50.480).

Запустил, вписал свое свое имя «RSI» и в папке с keygen-ом появился файл everest.key - ага значит вот какой ключ должен быть!!!
На всякий случай попробовал: переписал файл в папку с прогой и запустил - авось ключ подойдет :), но облом!
Вываливается собщение:


KEY file of this product is modified or corrupted
Product has reverted back to Evaluation mode

Значит нам надо искать место, где прога открывает файл everest.key и проверяет его! Попробуем в OllyDbg поискать строку с именем файла.
Жмем(Ctrl+B) в поле ASCII вводим everest.key и OK – ничего! Ладно, значит она потом в процессе «собирается» или зашифрована, чтобы мы ее не нашли!

Теперь есть 2 пути:
1)Будем пробовать искать строки содержащие имя или расширение KEY файла
2)Если пункт 1 не помог, тогда будем ставить бряки на функции открытия или чтения файлов (такие как CreateFileA, OpenFile, ReadFile и др…..)
Начнем с пункта 1 - попробуем поискать «.key» и:
сначала находим какие-то
URL http://www.keytronic.com/home/keyboards/mice/mice.html, но нам это не надо, поэтому ищем дальше (Ctrl+L) и через пару раз – о ДА!!! Ура! Есть такая строчка, поднимемся выше и бряк(F2) на начало той функции по адресу 0075E858:

0075E858  /$ 55                   PUSH EBP				; <- Начало функции	
0075E859  |. 8BEC                 MOV EBP,ESP
0075E85B  |. B9 46000000          MOV ECX,46
0075E860  |> 6A 00                /PUSH 0
0075E862  |. 6A 00                |PUSH 0
0075E864  |. 49                   |DEC ECX
0075E865  |.^75 F9                \JNZ SHORT everest.0075E860
0075E867  |. 53                   PUSH EBX
0075E868  |. 56                   PUSH ESI
0075E869  |. 57                   PUSH EDI
0075E86A  |. 8BD8                 MOV EBX,EAX
0075E86C  |. 33C0                 XOR EAX,EAX
0075E86E  |. 55                   PUSH EBP
0075E86F  |. 68 FEEC7500          PUSH everest.0075ECFE
0075E874  |. 64:FF30              PUSH DWORD PTR FS:[EAX]
0075E877  |. 64:8920              MOV DWORD PTR FS:[EAX],ESP
0075E87A  |. C783 C4000700 010000>MOV DWORD PTR DS:[EBX+700C4],1
0075E884  |. 66:B9 0100           MOV CX,1
0075E888  |. 66:BA 0B00           MOV DX,0B
0075E88C  |. 66:B8 D607           MOV AX,7D6
0075E890  |. E8 9FD6CAFF          CALL everest.0040BF34
0075E895  |. DD9B C8000700        FSTP QWORD PTR DS:[EBX+700C8]
0075E89B  |. 9B                   WAIT
.	   .			   .		
.	   .	                   .					; <- кусок пропущен
.          .			   .	
0075ECF3  |. BA 05000000    	  MOV EDX,5
0075ECF8  |. E8 1766CAFF    	  CALL everest.00405314
0075ECFD  \. C3                   RETN

Ну что же посмотрим, что у нас там – перезапускаем прогу и останавливаемся на бряке. Видно , что это функция что-то делает с содержимым KEY файла, но ничего не понятно… Идем по F8 и уже подошли к выходу, ладно выходим из этой функции и что мы видим:

0072F99F  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072F9A1  |. E8 B2EE0200          CALL everest.0075E858			   ;<- Отсюда мы вышли	
0072F9A6  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072F9A8  |. 83B8 C0000700 00     CMP DWORD PTR DS:[EAX+700C0],0	   ; <- Проверка если там не 0
0072F9AF  |. 75 0C                JNZ SHORT everest.0072F9BD                  ;  то прыгаем
0072F9B1  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072F9B3  |. 05 BC000700          ADD EAX,700BC
0072F9B8  |. E8 3359CDFF          CALL everest.004052F0                    ; иначе, заносим 0 в  [EAX+700BC]
0072F9BD  |> 6A 02                PUSH 2                                   ; /Index = SM_CXVSCROLL
0072F9BF  |. E8 F88ACDFF          CALL <JMP.&user32.GetSystemMetrics>      ; \GetSystemMetrics
0072F9C4  |. 8B13                 MOV EDX,DWORD PTR DS:[EBX]
0072F9C6  |. 8982 444F0000        MOV DWORD PTR DS:[EDX+4F44],EAX
0072F9CC  |. 6A 05                PUSH 5                                   ; /Index = COLOR_WINDOW
0072F9CE  |. E8 D18ACDFF          CALL <JMP.&user32.GetSysColor>           ; \GetSysColor
0072F9D3  |. 3D FFFFFF00          CMP EAX,0FFFFFF
0072F9D8  |. 75 19                JNZ SHORT everest.0072F9F3
0072F9DA  |. 6A 08                PUSH 8                                   ; /Index = COLOR_WINDOWTEXT
0072F9DC  |. E8 C38ACDFF          CALL <JMP.&user32.GetSysColor>           ; \GetSysColor
0072F9E1  |. 85C0                 TEST EAX,EAX
0072F9E3  |. 75 0E                JNZ SHORT everest.0072F9F3
0072F9E5  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072F9E7  |. C780 C4060000 316AC5>MOV DWORD PTR DS:[EAX+6C4],0C56A31
0072F9F1  |. EB 0F                JMP SHORT everest.0072FA02
0072F9F3  |> 6A 0D                PUSH 0D                                  ; /Index = COLOR_HIGHLIGHT
0072F9F5  |. E8 AA8ACDFF          CALL <JMP.&user32.GetSysColor>           ; \GetSysColor
0072F9FA  |. 8B13                 MOV EDX,DWORD PTR DS:[EBX]
0072F9FC  |. 8982 C4060000        MOV DWORD PTR DS:[EDX+6C4],EAX
0072FA02  |> 8D55 E4              LEA EDX,DWORD PTR SS:[EBP-1C]
0072FA05  |. 33C0                 XOR EAX,EAX
0072FA07  |. E8 EC31CDFF          CALL everest.00402BF8
0072FA0C  |. 8B45 E4              MOV EAX,DWORD PTR SS:[EBP-1C]
0072FA0F  |. 8D4D E8              LEA ECX,DWORD PTR SS:[EBP-18]
0072FA12  |. BA E8FF7200          MOV EDX,everest.0072FFE8                 ;  ASCII "ProductVersion"
0072FA17  |. E8 80F0D8FF          CALL everest.004BEA9C
0072FA1C  |. 8B55 E8              MOV EDX,DWORD PTR SS:[EBP-18]
0072FA1F  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072FA21  |. 05 68070000          ADD EAX,768
0072FA26  |. E8 1959CDFF          CALL everest.00405344
0072FA2B  |. 8D55 DC              LEA EDX,DWORD PTR SS:[EBP-24]
0072FA2E  |. 33C0                 XOR EAX,EAX
0072FA30  |. E8 C331CDFF          CALL everest.00402BF8
0072FA35  |. 8B45 DC              MOV EAX,DWORD PTR SS:[EBP-24]
0072FA38  |. 8D4D E0              LEA ECX,DWORD PTR SS:[EBP-20]
0072FA3B  |. BA 00007300          MOV EDX,everest.00730000                 ;  ASCII "FileVersion"
0072FA40  |. E8 57F0D8FF          CALL everest.004BEA9C
0072FA45  |. 8B55 E0              MOV EDX,DWORD PTR SS:[EBP-20]
0072FA48  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072FA4A  |. 05 6C070000          ADD EAX,76C
0072FA4F  |. E8 F058CDFF          CALL everest.00405344
0072FA54  |. 8D55 F8              LEA EDX,DWORD PTR SS:[EBP-8]
0072FA57  |. B8 14007300          MOV EAX,everest.00730014         	;  ASCII "EVEREST Ultimate Edition 2006"
0072FA5C  |. E8 C3A2CDFF          CALL everest.00409D24
0072FA61  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]
0072FA63  |. 83B8 BC000700 00     CMP DWORD PTR DS:[EAX+700BC],0	; <- Проверка если там не 0,
0072FA6A  |. 75 1A                JNZ SHORT everest.0072FA86		; то прыгаем и не добавляем надпись 
0072FA6C  |. FF75 F8              PUSH DWORD PTR SS:[EBP-8]
0072FA6F  |. 68 3C007300          PUSH everest.0073003C                ;  ASCII "  "
0072FA74  |. 68 48007300          PUSH everest.00730048                ;  ASCII "[ TRIAL VERSION ]"
0072FA79  |. 8D45 F8              LEA EAX,DWORD PTR SS:[EBP-8]

Вот оно: по адресу 0072FA63 проверка, если по адресу [EAX+700BC] лежит 0, тогда прибавляем строку [Trial Version] в заголовок окна , а как мы видели выше (строка 0072F9A8) там идет проверка, если в [EAX+700C0] был не ноль, то и в [EAX+700BC] не заносится ноль. Значит будем искать место, где в [EAX+700C0] заносится ноль. И где же вы думаете это место??? Правильно! В функции проверки ключа ( CALL everest.0075E858 ), значит будем смотреть ее более подробно!!!

Для начала посмотрим что у нас в сгенерином key файле (который выдал KeyGen):

RSI
Unlimited
20501231
00D0050000F0060000D005000090060000D005000040060000D0050000A0060000D0050000F0060000D0050000500600

Пока нам это ни о чем не говорит, итак идем по адресу 0075E858 на начало функции проверки и трейсим по F8, только уже смотрим внимательно, что там делается :)

0075E971  |> 8B55 D4              MOV EDX,DWORD PTR SS:[EBP-2C]
0075E974  |. 8D85 08FEFFFF        LEA EAX,DWORD PTR SS:[EBP-1F8]
0075E97A  |. E8 C546CAFF          CALL everest.00403044
0075E97F  |. A1 88E57900          MOV EAX,DWORD PTR DS:[79E588]
0075E984  |. C600 00              MOV BYTE PTR DS:[EAX],0
0075E987  |. 8D85 08FEFFFF        LEA EAX,DWORD PTR SS:[EBP-1F8]
0075E98D  |. E8 3644CAFF          CALL everest.00402DC8
0075E992  |. E8 B540CAFF          CALL everest.00402A4C
0075E997  |. 85C0                 TEST EAX,EAX				; Если нет KEY файла, то 
0075E999  |. 0F85 24030000        JNZ everest.0075ECC3			; прыгаем на облом
0075E99F  |. 8D45 E4              LEA EAX,DWORD PTR SS:[EBP-1C]
0075E9A2  |. E8 4969CAFF          CALL everest.004052F0
0075E9A7  |. 8D45 E0              LEA EAX,DWORD PTR SS:[EBP-20]
0075E9AA  |. E8 4169CAFF          CALL everest.004052F0

Хорошо! Файл у нас есть – поэтому не прыгаем, идем дальше

0075EA92  |. E8 9D3ECAFF          CALL everest.00402934
0075EA97  |. 837D E4 00           CMP DWORD PTR SS:[EBP-1C],0	; <- Проверка, что 1-я строка KEY файла не 0
0075EA9B  |. 74 3D                JE SHORT everest.0075EADA
0075EA9D  |. 837D E0 00           CMP DWORD PTR SS:[EBP-20],0	; <- Проверка, что 2-я строка KEY файла не 0
0075EAA1  |. 74 37                JE SHORT everest.0075EADA
0075EAA3  |. 837D D8 00           CMP DWORD PTR SS:[EBP-28],0	; <- Проверка, что 4-я строка KEY файла не 0
0075EAA7  |. 74 31                JE SHORT everest.0075EADA
0075EAA9  |. 8D95 E4FDFFFF        LEA EDX,DWORD PTR SS:[EBP-21C]
0075EAAF  |. 8B45 E0              MOV EAX,DWORD PTR SS:[EBP-20]
0075EAB2  |. E8 6DB2CAFF          CALL everest.00409D24		 ; Приводим 2-ю строку к верхнему регистру
0075EAB7  |. 8B85 E4FDFFFF        MOV EAX,DWORD PTR SS:[EBP-21C]
0075EABD  |. 8D95 E8FDFFFF        LEA EDX,DWORD PTR SS:[EBP-218]
0075EAC3  |. E8 0CB0CAFF          CALL everest.00409AD4
0075EAC8  |. 8B85 E8FDFFFF        MOV EAX,DWORD PTR SS:[EBP-218] ; указатель на 2-ю строку файла
0075EACE  |. BA 58ED7500          MOV EDX,everest.0075ED58       ; указатель на строку "UNLIMITED"
0075EAD3  |. E8 406CCAFF          CALL everest.00405718		 ; сравнение строк
0075EAD8  |. 75 0C                JNZ SHORT everest.0075EAE6	 ; Если они равны, то не прыгаем
0075EADA  |> C683 D0000700 01     MOV BYTE PTR DS:[EBX+700D0],1	 		
0075EAE1  |. E9 DD010000          JMP everest.0075ECC3		 ; Прыжок на облом...
0075EAE6  |> 8D95 E0FDFFFF        LEA EDX,DWORD PTR SS:[EBP-220]

Ага значит 2-я строка KEY файла на должна быть UNLIMITED, а у нас там как раз она, поэтому откроем KEY файл и вместо нее напишем, например, «Never»!!! Хорошо, снова перезапустились, теперь прыгнули в этом месте и идем дальше:

0075EAE6  |> 8D95 E0FDFFFF        LEA EDX,DWORD PTR SS:[EBP-220]  ; передаем в функцию 4-ю строку
0075EAEC  |. 8B45 D8              MOV EAX,DWORD PTR SS:[EBP-28]
0075EAEF  |. E8 D08FE3FF          CALL everest.00597AC4		  ; функция отработала
0075EAF4  |. 8B85 E0FDFFFF        MOV EAX,DWORD PTR SS:[EBP-220]  ; получаем на выходе строку "249728"
0075EAFA  |. 8D55 F8              LEA EDX,DWORD PTR SS:[EBP-8]
0075EAFD  |. E8 2254CAFF          CALL everest.00403F24		  ; <- переводим строку в число	
0075EB02  |. DD5D E8              FSTP QWORD PTR SS:[EBP-18]	  ; <- сохраняем число в [EBP-18]	
0075EB05  |. 9B                   WAIT
0075EB06  |. 33C0                 XOR EAX,EAX

Видим функция 00597AC4 ( далее функция_1) вернула нам "249728", пока назовем его число_1, ХЗ зачем идем дальше и видим:

0075EB06  |. 33C0                 XOR EAX,EAX
0075EB08  |. 8945 F0              MOV DWORD PTR SS:[EBP-10],EAX		; <-  [EBP-10] = 0
0075EB0B  |. 8945 F4              MOV DWORD PTR SS:[EBP-C],EAX
0075EB0E  |. 8B45 E4              MOV EAX,DWORD PTR SS:[EBP-1C]		; <- наша 1-я строка (Имя)
0075EB11  |. E8 B66ACAFF          CALL everest.004055CC
0075EB16  |. 8BD0                 MOV EDX,EAX				; <- в EDX длина 1-ой строки
0075EB18  |. 85D2                 TEST EDX,EDX
0075EB1A  |. 7E 2C                JLE SHORT everest.0075EB48
0075EB1C  |. B8 01000000          MOV EAX,1
0075EB21  |> 8B4D E4              /MOV ECX,DWORD PTR SS:[EBP-1C]	; <- в ЕСХ наше имя
0075EB24  |. 0FB64C01 FF          |MOVZX ECX,BYTE PTR DS:[ECX+EAX-1]	; <- берем eax-1 символ имени (т.е 0,1,2...)
0075EB29  |. 8BF0                 |MOV ESI,EAX						
0075EB2B  |. 83F6 6D              |XOR ESI,6D				; <- ксорим номер символа с константой 6Dh = 109
0075EB2E  |. 0FAFCE               |IMUL ECX,ESI				; <- умножаем на наш символ имени
0075EB31  |. 898D DCFDFFFF        |MOV DWORD PTR SS:[EBP-224],ECX
0075EB37  |. DB85 DCFDFFFF        |FILD DWORD PTR SS:[EBP-224]
0075EB3D  |. DC45 F0              |FADD QWORD PTR SS:[EBP-10]		; <- результат прибавляем в [EBP-10]
0075EB40  |. DD5D F0              |FSTP QWORD PTR SS:[EBP-10]
0075EB43  |. 9B                   |WAIT
0075EB44  |. 40                   |INC EAX
0075EB45  |. 4A                   |DEC EDX
0075EB46  |.^75 D9                \JNZ SHORT everest.0075EB21		; <- выполняем пока не дошли до конца имени
0075EB48  |> 8B45 E0              MOV EAX,DWORD PTR SS:[EBP-20]		; <- наша 2-я строка "Never"
0075EB4B  |. E8 7C6ACAFF          CALL everest.004055CC
0075EB50  |. 8BD0                 MOV EDX,EAX
0075EB52  |. 85D2                 TEST EDX,EDX
0075EB54  |. 7E 2F                JLE SHORT everest.0075EB85
0075EB56  |. B8 01000000          MOV EAX,1				; <- все тоже самое, только
0075EB5B  |> 8B4D E0              /MOV ECX,DWORD PTR SS:[EBP-20]
0075EB5E  |. 0FB64C01 FF          |MOVZX ECX,BYTE PTR DS:[ECX+EAX-1]
0075EB63  |. 8BF0                 |MOV ESI,EAX
0075EB65  |. 81F6 E6000000        |XOR ESI,0E6				; <- ксорим с E6h = 230
0075EB6B  |. 0FAFCE               |IMUL ECX,ESI
0075EB6E  |. 898D DCFDFFFF        |MOV DWORD PTR SS:[EBP-224],ECX
0075EB74  |. DB85 DCFDFFFF        |FILD DWORD PTR SS:[EBP-224]
0075EB7A  |. DC45 F0              |FADD QWORD PTR SS:[EBP-10]
0075EB7D  |. DD5D F0              |FSTP QWORD PTR SS:[EBP-10]
0075EB80  |. 9B                   |WAIT
0075EB81  |. 40                   |INC EAX
0075EB82  |. 4A                   |DEC EDX
0075EB83  |.^75 D6                \JNZ SHORT everest.0075EB5B
0075EB85  |> 8B45 DC              MOV EAX,DWORD PTR SS:[EBP-24]		; <- наша 3-я строка
0075EB88  |. E8 3F6ACAFF          CALL everest.004055CC
0075EB8D  |. 8BD0                 MOV EDX,EAX
0075EB8F  |. 85D2                 TEST EDX,EDX
0075EB91  |. 7E 2C                JLE SHORT everest.0075EBBF
0075EB93  |. B8 01000000          MOV EAX,1				; <- все тоже самое, только
0075EB98  |> 8B4D DC              /MOV ECX,DWORD PTR SS:[EBP-24]
0075EB9B  |. 0FB64C01 FF          |MOVZX ECX,BYTE PTR DS:[ECX+EAX-1]
0075EBA0  |. 8BF0                 |MOV ESI,EAX
0075EBA2  |. 83F6 11              |XOR ESI,11				; <- ксорим с 11h = 17
0075EBA5  |. 0FAFCE               |IMUL ECX,ESI
0075EBA8  |. 898D DCFDFFFF        |MOV DWORD PTR SS:[EBP-224],ECX
0075EBAE  |. DB85 DCFDFFFF        |FILD DWORD PTR SS:[EBP-224]
0075EBB4  |. DC45 F0              |FADD QWORD PTR SS:[EBP-10]
0075EBB7  |. DD5D F0              |FSTP QWORD PTR SS:[EBP-10]
0075EBBA  |. 9B                   |WAIT
0075EBBB  |. 40                   |INC EAX
0075EBBC  |. 4A                   |DEC EDX
0075EBBD  |.^75 D9                \JNZ SHORT everest.0075EB98
0075EBBF  |> DD45 F0              FLD QWORD PTR SS:[EBP-10]
0075EBC2  |. DC5D E8              FCOMP QWORD PTR SS:[EBP-18]		; сравниваем [EBP-10] и [EBP-18]
0075EBC5  |. DFE0                 FSTSW AX
0075EBC7  |. 9E                   SAHF
0075EBC8  |. 74 0C                JE SHORT everest.0075EBD6		; если они равны,то прыгаем
0075EBCA  |. C683 D0000700 	 >MOV BYTE PTR DS:[EBX+700D0],1
0075EBD1  |. E9 ED000000    	  JMP everest.0075ECC3

Ну вот! Основной алгоритм в принципе стал понятен:
Берется 4-я строка из нашего KEY файла и на основаниее ее мы получаем число_1, после этого мы подсчитываем суммы от первой второй и третей строки, предварительно с кладывая их в одну переменную(число_2), затем сравниваются число_1 и число_2 если они равны, тогда мы прыгаем и в адрес [EAX+700C0] заносится указатель на строку "Never", и дальше все в идет как по маслу... ;)

Итак алгоритм создания KeyGen-a:

1. Надо сделать цикл подсчета нашего имени
Он будет следующим:

	
                               for( int i=1; i <= strlen(name) ; i++) 	
				{				
					c = name[i-1]; 		// c = [eax-1] символ нашего имени
					a = i;			// mov esi,eax
					a ^= 109;		// xor esi,6Dh
					b  = c*a;		// imul ecx,esi
					result += b;		// fadd qword ptr ss:[ebp-10]
				}


После этого цикла переменная result будет содержать нашу сумму

2. Прибавить к ней число от цикла строки «Never»,оно будет постоянно и равно 116772.

3. Прибавить к нему число от цикла 3-й строки в файле она может быть любая (в keygen я взял строку «01010101» результат ее цикла = 7960)

4. Сгенерить 4-ю строку, чтобы сумма ее цикла была равна нашему числу

5. Сохранить эти данные в файл everest.key

По поводу генерации 4-ой строки надо сказать! Как генерится число от нее?

После того как в функцию_1 мы передали строку

00D0050000F0060000D005000090060000D005000040060000D0050000A0060000D0050000F0060000D0050000500600

И получили строку «249728», которую потом будем переводить в число и с ней сравнивать!
Не буду вдаваться в подробности, короче эта строка генерится ТАК:
00D0050000X00600 - Вот такой кусок повторяется 6 раз, причем буква X отвечает за генерацию каждого символа в строке.

Вот значения X ( могут и другие символы удовлетворять этим значениям!!! ):

Таблица 1:

--------------------------------------------------------------------------------------------
Символ =   	0	1	2	3	4	5	6	7	8	9  
--------------------------------------------------------------------------------------------
X = 	        d	c	f	e	9	8	b	a	5	4  
--------------------------------------------------------------------------------------------

То есть строку «123456» можно зашифровать так(см. Таблицу 1):

00D0050000с0060000D0050000f0060000D0050000e0060000D005000090060000D005000080060000D0050000b00600

          1		  2		  3	     	  4               5		  6

Исходя из этого, вот такой ключ получился для моего имени:

RSI
Never
01010101
00D0050000c0060000D005000080060000D0050000d0060000D005000050060000D0050000e0060000D0050000c00600

Исходный код KeyGen-a:(писал на VC++ 6.0 SE под Win32 Console)

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

void main()
{
	FILE *file;
        long result=0;
        сhar name[25],data[100];
        char str[10],tmp[2];
        char mas[]={'d','c','f','e','9','8','b','a','5','4'};	// массив значений X отвечающих за генерацию 4 строки
	
        data[0] = '\0';
        tmp[1] = '\0';

	printf(" Lavalys Everest Ultimate Edition 2006 v3.01.652\n KeyGen by RSI, 2006\n\n");
	printf(" Enter your name: ");
	scanf("%s",&name);

	for(unsigned int i=1; i <= strlen(name) ; i++) 	// цикл считает результат имени
	{				
		result += name[i-1]*(i^109);
	}
	result += 116772; //прибавляем результат цикла от строки "Never"
	result += 7960;   //прибавляем результат цикла от строки "01010101"

	ltoa(result,str,10); // переводим результат из числа в строку
	
	for( i=0; i < strlen(str); i++)  // делаем бинарную строку от результата
	{
			strcat(data,"00D0050000");
			tmp[0] = mas[ str[i]-'0' ];
			strcat(data,tmp);
			strcat(data,"00600");
	}

	file = fopen("everest.key","w");  // сохраняем файл лицензии
	if(file == NULL) 
	{
		printf(" \n Error!!! Key File not is created");
		getch();
		return;
	}
	fprintf(file,"%s\n",name);
	fprintf(file,"Never\n01010101\n");
	fprintf(file,"%s",data);
	fclose(file);

	printf("\n License file is created\n\n Press any key to quit...");
	getch();
}


Вот и все!!!

Огромное спасибо сайту www.cracklab.ru и его создателям за то, что «научили»!!!
Приветы ВСЕМ, а так же тем, кто прочитал эту статью… :)

Если есть вопросы, или что-нибудь по статье пишите RS1@tut.by




Обсуждение статьи: Исследуем Lavalys Everest Ultimate Edition 2006 v.3.01.652 и пишем KeyGen >>>


Комментарии к статье: Исследуем Lavalys Everest Ultimate Edition 2006 v.3.01.652 и пишем KeyGen

Devastator_ 21.10.2006 09:54:32
По-поводу CreateProcessA(W)... есть много способов подгрузить код в адресное пространство существующего процесса например LoadLibraryA(W) (использовалось в OutpostFirewall кажется). Или банально выделить память GlobalAlloc, в качестве флагов функции указать executable, влить туда код из файла или из секции ресурсов например и передать управление коду. Вариантов масса.

---
RSI 23.10.2006 10:19:39
Я написал только то, что здесь использовалось! Еслиб ломал Outpost то написал бы и про это... ;)
---
Nitrogen 29.10.2006 19:50:39
Devastator
ну вот ты это к чему сказал, типа показать какой ты умный?

RSI
маладес. статья толковая!
---
Z0oMiK 30.10.2006 03:10:43
Хорошая статейка :) тока кейген на С это (_/_) ( для меня ) :)
---

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



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


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