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

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


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

Исследуем Corman Lisp 2.51 и создаем хитрый KeyGen

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

Хорошая подборка видеоуроков, инструментов крэкера, книг и статей - здесь.

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

Привет всем! Вот где-то с полгода назад принес мне дружбан этот утиль, мол говорит что скоро у него лабы по Lisp начнутся, и что ему понравился именно этот транслятор, но есть загвоздка – он не бесплатный, и просят за него производители 300$ (ну или для студентов 150$), от чего он так же не в восторге. Кряков для этой версии тогда не было( думаю и счас вряд ли появились) вот с этого все и началось… счас наверное уже вышла новая версия данного продукта, но я думаю там ничего не изменилось.

Corman Lisp - это транслятор и компилятор для логического языка Lisp (сайт: www.cormanlisp.com)

Нам понадобятся инструменты:
1) OllyDbg
2) PEiD
3) FASM

В этой статье затрагиваются моментами самые азы пользования отладчиком OllyDbg, поэтому других более опытных прошу без прериканий, пропускать эти места, так как эта статья в основном рассчитана на начинающих!

Итак, посмотрим с чем именно предстоит иметь дело:
После установки просканим экзешник на всякие нехорошие пакеры/протекторы,
PEiD показывает Microsoft Visual C++ 7.0 Method2 [Debug] - Замечательно!!!
Ладно запустим и посмотрим что от нас хотят…

После запуска появляется окно в котором нам говорят, что мы не зарегистрированы и можем работать только 30 дней, а также просят нас ввести свои данные регистрации, которые состоят из трех полей: имени, организации, и серийника. Ладно введем:

Name: RSI
Organization: Home
Registration Code: 12345

Жмем кнопочку “Register Me”, и видим как появляется сообщение с надписью
“ The registration code you entered was not valid “, за него в данном случае отвечает функция MessageBox. Отлично закрываем прогу…

Итак мы узнали, что прога ничем не упакована и что после ввода неправильного серийника она выводит сообщение об этом(этим и воспользуемся -> теперь знаем на какую функцию первым делом поставим бряк, если кто не догадался, то это MessageBoxA) ;)

Грузим наш файл в OllyDbg, и запускаем(F9) видим опять туже картину, проделываем тоже по вводу своих данных, только уже не жмякаем на кнопку. Теперь будем ставить бряк на MessageBoxA.
Что нам надо сделать:
1) Выбираем пункт View -> Exucutable Modules (Ctrl+E)
2) Ставим курсор на библиотеку USER32.DLL именно в ней находится данная функция
3) Нажимаем (Ctrl+N) это значит показать все функции данной библиотеки
4) В появившемся списке ищем MessageBoxA и ставим на нее курсор
5) Теперь ставим бряк на нее(F2)

Поставили, жмем на кнопку “Register Me”, и вываливаемся в отладчик, в таком месте:

77D5ADD7 > 833D C4D3D877 00 CMP DWORD PTR DS:[77D8D3C4],0		<- Мы тут
77D5ADDE   0F85 377E0100    JNZ USER32.77D72C1B
77D5ADE4   6A 00            PUSH 0
77D5ADE6   FF7424 14        PUSH DWORD PTR SS:[ESP+14]
77D5ADEA   FF7424 14        PUSH DWORD PTR SS:[ESP+14]
77D5ADEE   FF7424 14        PUSH DWORD PTR SS:[ESP+14]
77D5ADF2   FF7424 14        PUSH DWORD PTR SS:[ESP+14]
77D5ADF6   E8 03000000      CALL USER32.MessageBoxExA
77D5ADFB   C2 1000          RETN 10

Снимаем бряк с этого места(F2), и если построчно (по F8) пройти этот код, то мы станем по адресу 77D5ADF6, это вылез наш MessageBox, нам чтобы продолжить надо жмякнуть на кнопку OK в нем, после этого опять вренемся в отладчик и станем на адрес 77D5ADFB. Теперь будем идти построчно, до того пока не выйдем в код программы(обычно, пока адрес на станет вида 004XXXXX), получилось вот тут:

004133C1   8B4D E4          MOV ECX,DWORD PTR SS:[EBP-1C]
004133C4   E8 E7000000      CALL CormanLi.004134B0
004133C9   0FB6C0           MOVZX EAX,AL
004133CC   85C0             TEST EAX,EAX
004133CE   75 10            JNZ SHORT CormanLi.004133E0
004133D0   6A 00            PUSH 0
004133D2   6A 00            PUSH 0
004133D4   68 809A4200      PUSH CormanLi.00429A80  	; ASCII "The registration code you entered was not valid."
004133D9   E8 4E2B0000      CALL <JMP.&MFC71.#1123>		<- мы вышли отсюда
004133DE   EB 43            JMP SHORT CormanLi.00413423		<- стоим тут
004133E0   8D4D E8          LEA ECX,DWORD PTR SS:[EBP-18]
004133E3   FF15 6C944100    CALL DWORD PTR DS:[<&MFC71.#876>]        
004133E9   50               PUSH EAX
004133EA   8D4D F0          LEA ECX,DWORD PTR SS:[EBP-10]
004133ED   FF15 6C944100    CALL DWORD PTR DS:[<&MFC71.#876>]        
004133F3   50               PUSH EAX
004133F4   8D4D EC          LEA ECX,DWORD PTR SS:[EBP-14]
004133F7   FF15 6C944100    CALL DWORD PTR DS:[<&MFC71.#876>]        
004133FD   50               PUSH EAX
004133FE   8B4D E4          MOV ECX,DWORD PTR SS:[EBP-1C]
00413401   E8 FA000000      CALL CormanLi.00413500
00413406   0FB6C8           MOVZX ECX,AL
00413409   85C9             TEST ECX,ECX
0041340B   75 0E            JNZ SHORT CormanLi.0041341B
0041340D   6A 00            PUSH 0
0041340F   6A 00            PUSH 0
00413411   68 B49A4200      PUSH CormanLi.00429AB4            ; ASCII "Registration failed."
00413416   E8 112B0000      CALL <JMP.&MFC71.#1123>
0041341B   8B4D E4          MOV ECX,DWORD PTR SS:[EBP-1C]
0041341E   E8 73300000      CALL <JMP.&MFC71.#4735>
00413423   C645 FC 01       MOV BYTE PTR SS:[EBP-4],1
00413427   8D4D E8          LEA ECX,DWORD PTR SS:[EBP-18]
0041342A   FF15 AC944100    CALL DWORD PTR DS:[<&MFC71.#578>]        
00413430   C645 FC 00       MOV BYTE PTR SS:[EBP-4],0
00413434   8D4D F0          LEA ECX,DWORD PTR SS:[EBP-10]
00413437   FF15 AC944100    CALL DWORD PTR DS:[<&MFC71.#578>]        
0041343D   C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-4],-1
00413444   8D4D EC          LEA ECX,DWORD PTR SS:[EBP-14]
00413447   FF15 AC944100    CALL DWORD PTR DS:[<&MFC71.#578>]        
0041344D   8B4D F4          MOV ECX,DWORD PTR SS:[EBP-C]
00413450   64:890D 00000000 MOV DWORD PTR FS:[0],ECX
00413457   8BE5             MOV ESP,EBP
00413459   5D               POP EBP
0041345A   C3               RETN

Видим что мы вышли сразу после сообщения о неверной регистрации, посмотрим что выше:

004133C4   E8 E7000000      CALL CormanLi.004134B0
004133C9   0FB6C0           MOVZX EAX,AL
004133CC   85C0             TEST EAX,EAX
004133CE   75 10            JNZ SHORT CormanLi.004133E0

Меня заинтересовал этот кусок, значит если эта функция вернет al = 1, то после команды
TEST EAX,EAX флаг Z установится в 0, и мы перепрыгнем это сообщение, посмотрим что делается в этой функции, для этого поставим на нее бряк (поставим курсор на адресс 004133C4 и F2), отпускаем программу на дальнейшее выполнение (F9). Опять жмем кнопку “Register Me” и останавливаемся на нашей функции, заходим внутрь(F7).

004134B0   55               PUSH EBP
004134B1   8BEC             MOV EBP,ESP
004134B3   83EC 08          SUB ESP,8
004134B6   894D F8          MOV DWORD PTR SS:[EBP-8],ECX
004134B9   8B4D 10          MOV ECX,DWORD PTR SS:[EBP+10]
004134BC   FF15 6C944100    CALL DWORD PTR DS:[<&MFC71.#876>]        
004134C2   50               PUSH EAX
004134C3   8B4D 0C          MOV ECX,DWORD PTR SS:[EBP+C]
004134C6   FF15 6C944100    CALL DWORD PTR DS:[<&MFC71.#876>]        
004134CC   50               PUSH EAX
004134CD   8B4D 08          MOV ECX,DWORD PTR SS:[EBP+8]
004134D0   FF15 6C944100    CALL DWORD PTR DS:[<&MFC71.#876>]        
004134D6   50               PUSH EAX
004134D7   E8 801B0000      CALL <JMP.&License.CheckRegistration>	<- интересное название
004134DC   83C4 0C          ADD ESP,0C
004134DF   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
004134E2   33C0             XOR EAX,EAX
004134E4   837D FC 00       CMP DWORD PTR SS:[EBP-4],0
004134E8   0F95C0           SETNE AL
004134EB   8BE5             MOV ESP,EBP
004134ED   5D               POP EBP
004134EE   C2 0C00          RETN 0C

Попадается на глаза фукнция с интересным названием CheckRegistration, и опять же если она вернет не нулевое значение, тогда мы al устанавливаем равным 1. Хорошо, посмотрим где находится эта функция - нажав Ctrl+E видим что только один модуль имеет имя License, и это есть библиотека license.dll - теперь мы знаем где и какая фукнция проверяет наши данные. Теперь подумаем, мы не знаем какое значение она должна возвращать, поэтому я решил перезапустить программу и поставив бряк на функцию License.CheckRegistration посмотреть где она вызывается и может там что-нить прояснится...
Перезапускам прогу(Ctrl+F2), бряк на функцию из библиотеки мы ставить уже умееем(если нет, то смотрим как ставили бряк на MessageBoxA), думаю с этим сложностей возникнуть не должно!!!
После запуска, прервались на этой функции - теперь потрейсим(F8) до выхода из нее:

10001448   8986 0C020000    MOV DWORD PTR DS:[ESI+20C],EAX
1000144E   68 68610010      PUSH License.10006168                    ; ASCII "12345"
10001453   55               PUSH EBP
10001454   56               PUSH ESI
10001455   E8 96FCFFFF      CALL License.CheckRegistration	
1000145A   83C4 0C          ADD ESP,0C				     ; <- вышли сюда
1000145D   83F8 14          CMP EAX,14
10001460   5F               POP EDI
10001461   0F9DC1           SETGE CL
10001464   8986 10020000    MOV DWORD PTR DS:[ESI+210],EAX
1000146A   888E 08020000    MOV BYTE PTR DS:[ESI+208],CL	     ; <-адрес [12F2DC]	
10001470   5E               POP ESI
10001471   5D               POP EBP
10001472   5B               POP EBX
10001473   59               POP ECX
10001474   C3               RETN

Это уже интересно!!! Если EAX = 14, то cl устанавливаем в 1 и сохраняем в память по адресу [12F2DC], посмотрим что будет дальше - идем к выходу функции... Выйдя из 2-х функций, пред нами предстает такая картина:

00408A77   E8 C4AA0000      CALL CormanLi.00413540		    ; <- вышли отсюда
00408A7C   83C4 04          ADD ESP,4				
00408A7F   0FB655 E4        MOVZX EDX,BYTE PTR SS:[EBP-1C]	    ; <- [EBP-1C] = [12F2DC]
00408A83   F7DA             NEG EDX
00408A85   1BD2             SBB EDX,EDX
00408A87   81C2 87000000    ADD EDX,87
00408A8D   52               PUSH EDX
00408A8E   68 30140000      PUSH 1430
00408A93   0FB645 E4        MOVZX EAX,BYTE PTR SS:[EBP-1C]
00408A97   F7D8             NEG EAX
00408A99   1BC0             SBB EAX,EAX
00408A9B   05 87000000      ADD EAX,87
00408AA0   50               PUSH EAX
00408AA1   8B8D A0FDFFFF    MOV ECX,DWORD PTR SS:[EBP-260]
00408AA7   51               PUSH ECX
00408AA8   8B8D A0FDFFFF    MOV ECX,DWORD PTR SS:[EBP-260]
00408AAE   81C1 D0020000    ADD ECX,2D0
00408AB4   8B95 A0FDFFFF    MOV EDX,DWORD PTR SS:[EBP-260]
00408ABA   8B82 D0020000    MOV EAX,DWORD PTR DS:[EDX+2D0]
00408AC0   FF90 6C010000    CALL DWORD PTR DS:[EAX+16C]
00408AC6   85C0             TEST EAX,EAX
00408AC8   75 08            JNZ SHORT CormanLi.00408AD2
00408ACA   83C8 FF          OR EAX,FFFFFFFF
00408ACD   E9 CA010000      JMP CormanLi.00408C9C
00408AD2   0FB64D E4        MOVZX ECX,BYTE PTR SS:[EBP-1C]	     ; <- ecx = [12F2DC] = 00	
00408AD6   85C9             TEST ECX,ECX			     ; <- если ecx = 1	
00408AD8   0F84 F8000000    JE CormanLi.00408BD6		     ; тогда не прыгаем, на облом	
00408ADE   68 40060000      PUSH 640
00408AE3   8B8D A0FDFFFF    MOV ECX,DWORD PTR SS:[EBP-260]
00408AE9   81C1 D0020000    ADD ECX,2D0
00408AEF   E8 94D50000      CALL <JMP.&MFC71.#2657>
00408AF4   8985 A8FDFFFF    MOV DWORD PTR SS:[EBP-258],EAX
00408AFA   68 8C704200      PUSH CormanLi.0042708C                   ; ASCII "Registered to: "
00408AFF   8D8D C0FDFFFF    LEA ECX,DWORD PTR SS:[EBP-240]
00408B05   FF15 B4944100    CALL DWORD PTR DS:[<&MFC71.#304>]         
00408B0B   C745 FC 00000000 MOV DWORD PTR SS:[EBP-4],0

Из всего увиденного делаем вывод, что если функция License.CheckRegistration вернет 14, будет все хорошо и мы зарегистрируемся, посмотрим как нам это сделать, вот сама эта функция:

100010F0 > 8B4424 0C        MOV EAX,DWORD PTR SS:[ESP+C]             ; < - наш серийник(строка)
100010F4   53               PUSH EBX
100010F5   50               PUSH EAX
100010F6   FF15 4C300010    CALL DWORD PTR DS:[<&MSVCR71.atoi>]      ; переводим строку в число
100010FC   8BD8             MOV EBX,EAX				     ; EBX = наш серийник(число) 	
100010FE   83C4 04          ADD ESP,4
10001101   85DB             TEST EBX,EBX			     ; проверка что EBX не 0	
10001103   75 02            JNZ SHORT License.10001107		     ; если да, то прыгаем	
10001105   5B               POP EBX
10001106   C3               RETN
10001107   56               PUSH ESI				; <- сохраняем значение ESI
10001108   8B7424 10        MOV ESI,DWORD PTR SS:[ESP+10]	; <- ESI = организация
1000110C   57               PUSH EDI				; <- сохраняем значение EDI
1000110D   8B7C24 10        MOV EDI,DWORD PTR SS:[ESP+10]	; <- EDI = наше имя	
10001111   68 60320010      PUSH License.10003260               ; <-ложим в стек строку "NezzyIdy"
10001116   56               PUSH ESI				; <- ложим в стек организацию
10001117   8BC7             MOV EAX,EDI				; <- EAX = EDI = наше имя
10001119   E8 E2FEFFFF      CALL License.10001000			 
1000111E   83C4 08          ADD ESP,8				; <- выравниваем стек
10001121   85C0             TEST EAX,EAX
10001123   74 0D            JE SHORT License.10001132
10001125   3BD8             CMP EBX,EAX				; сравниваем EAX с серийником
10001127   75 09            JNZ SHORT License.10001132		; если совпали, то не прыгаем	
10001129   5F               POP EDI				; <- восстанавливаем значение EDI
1000112A   5E               POP ESI			        ; <- восстанавливаем значение ESI
1000112B   B8 19000000      MOV EAX,19				; вернем eax = 19	
10001130   5B               POP EBX
10001131   C3               RETN
10001132   68 54320010      PUSH License.10003254               ; <-ложим в стек строку "WoodyWoo"
10001137   56               PUSH ESI			   	; <-ложим в стек организацию	
10001138   8BC7             MOV EAX,EDI				; <- EAX = EDI = наше имя
1000113A   E8 C1FEFFFF      CALL License.10001000
1000113F   83C4 08          ADD ESP,8
10001142   85C0             TEST EAX,EAX
10001144   74 0D            JE SHORT License.10001153
10001146   3BD8             CMP EBX,EAX			        
10001148   75 09            JNZ SHORT License.10001153		; Если совпали вернем 14 
1000114A   5F               POP EDI
1000114B   5E               POP ESI
1000114C   B8 14000000      MOV EAX,14
10001151   5B               POP EBX
10001152   C3               RETN
10001153   68 48320010      PUSH License.10003248               ; <-ложим в стек строку "Fabian15"
10001158   56               PUSH ESI				; <-ложим в стек организацию	
10001159   8BC7             MOV EAX,EDI				; <- EAX = EDI = наше имя
1000115B   E8 A0FEFFFF      CALL License.10001000
10001160   83C4 08          ADD ESP,8
10001163   85C0             TEST EAX,EAX
10001165   74 0D            JE SHORT License.10001174
10001167   3BD8             CMP EBX,EAX
10001169   75 09            JNZ SHORT License.10001174
1000116B   5F               POP EDI
1000116C   5E               POP ESI
1000116D   B8 0F000000      MOV EAX,0F				; Если совпали вернем 0F	
10001172   5B               POP EBX
10001173   C3               RETN
10001174   68 3C320010      PUSH License.1000323C               ; <-ложим в стек строку "ArtHills"
10001179   56               PUSH ESI				; <-ложим в стек организацию
1000117A   8BC7             MOV EAX,EDI				; <- EAX = EDI = наше имя
1000117C   E8 7FFEFFFF      CALL License.10001000
10001181   83C4 08          ADD ESP,8
10001184   85C0             TEST EAX,EAX
10001186   74 0D            JE SHORT License.10001195
10001188   3BD8             CMP EBX,EAX
1000118A   75 09            JNZ SHORT License.10001195
1000118C   5F               POP EDI
1000118D   5E               POP ESI
1000118E   B8 0E000000      MOV EAX,0E			      ; Если совпали вернем 0E
10001193   5B               POP EBX
10001194   C3               RETN
10001195   5F               POP EDI
10001196   5E               POP ESI
10001197   33C0             XOR EAX,EAX		              ; Если ничего не совпало вернем 0
10001199   5B               POP EBX
1000119A   C3               RETN

Судя по строкам видать "прикольные" программисты писали, фукнцию... :)

Нам нужно чтобы функция вернула 14, для этого надо чтобы по адресу 10001146, после коммады
CMP EBX,EAX не произошел переход, для этого содержимое EAX должно быть равно EBX, ну или наоборот.
Значит, что мы видим(стоя по адресу 10001146):

EBX - наш введенный сернйник = "12345" = 3039h
EAX - регистр с которым сравниваем = 4F500092h = 1330643090

И как вы думаете что это за число в EAX??? Правильно это наш серийник, вводим и радуемся жизни...

Name: RSI
Organization: Home
Registration Code: 1330643090

А можно сделать и подругому(как я сначала и сделал), изменить команду CMP EBX,EAX на CMP EAX,EAX и все!!! Программа будет зарегистрирована на любое имя и организацию которую введете...

Но crack или patch это не считается хорошим тоном, поэтому наша цель написать KeyGen!!!

По этому поводу нужно сказать пару слов - я сначала решил разобратся что происходит в функции
CALL License.10001000(которая возвращает верный серийник), но потом после пары часов мои мозги закипели... ;(
И совершенно случайно я решил просканить эту библиотеку на криптограммы, и как вы думаете каков был результат???
плагин к PEiD -> KANAL 2.5 показал DES[key schedule][char]!!! Во как, с криптографией копаться охоты совсем не было, да и гемор это большой...

Но я неотчаился ибо пришла мне интересная идея сделать хитрый KeyGen - хитрость в чем, раз мы знаем какая функция возвращает правильный серийний номер, и знаем каким образом ей передаются пераметры, так почему бы нам не использовать ее саму для кейгена, как это делает программа. ;)

Значит что мы знаем об этой функции???

1) Передоваемые параметры:

ложим в стек строку "WoodyWoo"
ложим в стек название организации
EAX присваиваем наше имя

2) Возвращаемое значение

в EAX будет наш сгенериный серийний номер

Теперь как нам вызвать эту функцию??? Так как функция явно не определена, то мы не
сможем получить ее смещение через GetProcAdress, поэтому рассчитаем его вручную.
Видим что ImageBase данной dll равен 10000000h(можно посмотреть в PEiD), а функция находится по адресу 10001000h исходя из этого получаем что смещение = 1000h.

Ну вот, посмотрим что получилось:

proc generate  

		invoke	 LoadLibrary,license_dll	; грузим нашу license.dll
		cmp	 eax,0			    
	        je	 exit_func			; проверка что все Ok, иначе выход
		mov	 edi,eax
		mov	 esi,eax			; esi = ImageBase
		add	 esi,1000h			; esi + 1000h
		mov	 eax,Woody				
		push	 eax				; push "WoodyWoo"
		mov	 eax,company
		push	 eax				; push company
		mov	 eax,name			; eax = name
		call	 esi				; call [ImageBase+1000h]
		add	 esp,8h				; <- выравниваем стек
		invoke	 ltoa,eax,serial,10		; <- переводим число в строку serial
    		invoke	 FreeLibrary,edi		; выгружаем dll
    exit_func:
		ret
endp

Вот такая маленькая процедурка делает все что нам надо! (полный исходник в конце статьи)

Цель достигнута - мы создали хитрый KeyGen, и пусть кто-нить скажет что наша функция генерит серийник коряво... ;) сразу пошлем... к производителям.

CrackLab FOREVER!!!

RSI (RS1@tut.by)

;----------------------------------------------------------------------------------------------------------------------
format PE GUI 4.0
entry start

include 'win32a.inc'

ID_NAME 	= 101
ID_COMPANY	= 102
ID_SERIAL	= 103

section '.data' data readable writeable

  name		rb 40h
  company	rb 40h
  serial	rb 20h
  caption	db 'Error',0
  message	db 'Not file license.dll',0Ah,'Please copy keygen to folder in program',0
  error 	db 'Incorrect name or company',0
  license_dll	db 'license.dll',0
  Woody 	db 'WoodyWoo',0

section '.code' code readable executable

	start:

		invoke	GetModuleHandle,0
		invoke	DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
		or	eax,eax
		jz	exit
	 exit:
		invoke	ExitProcess,0

proc generate  hwnddlg

		invoke	 LoadLibrary,license_dll
		cmp	 eax,0
		je	 return
		mov	 edi,eax
		mov	 esi,eax
		invoke	 GetDlgItemText,[hwnddlg],ID_NAME,name,40h
		invoke	 GetDlgItemText,[hwnddlg],ID_COMPANY,company,40h
		add	 esi,1000h
		mov	 eax,Woody
		push	 eax
		mov	 eax,company
		push	 eax
		mov	 eax,name
		call	 esi
		add	 esp,8h
		cmp	 eax,0
		je	 incorrect
		invoke	 ltoa,eax,serial,10
		invoke	 SetDlgItemText,[hwnddlg],ID_SERIAL,serial,40h
		jmp	 exit_func
    incorrect:
		invoke	 SetDlgItemText,[hwnddlg],ID_SERIAL,error,40h
		invoke	 FreeLibrary,edi
    exit_func:
		ret
       return:
		invoke	 MessageBox,HWND_DESKTOP,message,caption,MB_ICONERROR
		jmp	 exit_func
endp

proc DialogProc hwnddlg,msg,wparam,lparam

		push	ebx esi edi
		cmp	[msg],WM_COMMAND
		je	wmcommand
		cmp	[msg],WM_CLOSE
		je	wmclose
		xor	eax,eax
		jmp	finish
    wmcommand:
		cmp	[wparam],BN_CLICKED shl 16 + IDCANCEL
		je	wmclose
		cmp	[wparam],BN_CLICKED shl 16 + IDOK
		jne	processed
		push	[hwnddlg]
		call	generate
		jmp	processed
      wmclose:
		invoke	EndDialog,[hwnddlg],0
    processed:
		mov	eax,1
       finish:
		pop	edi esi ebx
		ret
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',
	  ntdll,'NTDLL.DLL',
	  user,'USER32.DLL'

  import kernel,
	 GetModuleHandle,'GetModuleHandleA',
	 LoadLibrary,'LoadLibraryA',
	 FreeLibrary,'FreeLibrary',
	 ExitProcess,'ExitProcess'

  import user,
	 DialogBoxParam,'DialogBoxParamA',
	 GetDlgItemText,'GetDlgItemTextA',
	 SetDlgItemText,'SetDlgItemTextA',
	 MessageBox,'MessageBoxA',
	 EndDialog,'EndDialog'

  import ntdll,
	 ltoa,'_ltoa'

section '.rsrc' resource data readable

  directory RT_DIALOG,dialogs

  resource dialogs,
	   37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration

  dialog demonstration,'KeyGen Corman Lisp 2.5',70,100,190,130,WS_CAPTION+WS_POPUP+DS_MODALFRAME
    dialogitem 'STATIC','&Name:',-1,10,10,70,8,WS_VISIBLE
    dialogitem 'EDIT','',ID_NAME,10,20,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'STATIC','&Company:',-1,10,40,70,8,WS_VISIBLE
    dialogitem 'EDIT','',ID_COMPANY,10,50,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_AUTOHSCROLL
    dialogitem 'STATIC','&Serial:',-1,10,70,90,8,WS_VISIBLE
    dialogitem 'EDIT','',ID_SERIAL,10,80,170,13,WS_VISIBLE+WS_BORDER+ES_READONLY+WS_TABSTOP
    dialogitem 'BUTTON','Get Serial',IDOK,55,105,75,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON
    dialogitem 'BUTTON','C&ancel',IDCANCEL,135,105,45,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON
  enddialog




Обсуждение статьи: Исследуем Corman Lisp 2.51 и создаем хитрый KeyGen >>>


Комментарии к статье: Исследуем Corman Lisp 2.51 и создаем хитрый KeyGen

1234567890 29.04.2007 17:00:30
Help!!! Я новичок, а как правильно подгрузить dll???
В принцепе дело то не в том что у меня версия 3.0 а в том что библа неправильно грузится.
Всё скомпилировал как у тебя. Кладу в папку с Lisp'ом, запускаю, ввожу данные, жму ОК, вылазит что нету "MSVCR80.dll", кладу в папку "MSVCR80.dll", запускаю также, вылазит "Runtime Error!" и говорот что я библу неправильно гружу :( в чем дело то?
Заранее благодарен.
Вот что твориться(21,6 КБ):
http://axelord.nm.ru/err.rar


---

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



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


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