Наконец-таки! Я закончил долбаться со своей прогой. Максимум, что Я смог выжать из нее это 1536 байт. Напоминаю прога генерирует сериал намбер для WinZip 9.0. Были учтены все рекомендации и советы на форуме по улучшению и уменьшению программного кода, после чего Практически всю прогу после этого пришлось перелапатить)) Итак, кто меньше??? Вот сам код: Code (Text): .386P .model flat includelib user32.lib include D:\masm32\include\windows.inc ;вызываемые функции Windows (внешние ссылки) extern _imp__DialogBoxParamA@20:dword extern _imp__GetDlgItem@8:dword extern _imp__SetFocus@4:dword extern _imp__MessageBoxA@16:dword extern _imp__EndDialog@8:dword extern _imp__GetDlgItemTextA@16:DWORD extern _imp__SetDlgItemTextA@12:DWORD ;*****Секция неинициализированных данных***** .DATA? BUFFER DB 1 DUP(?) .code start: push eax ;0 push offset DlgProc ;процедура диалогового окна push eax ;0 push offset DlgName ;имя шаблона диалога, он связывает .asm и rc.-файлы push 400000h ;hInstance call _imp__DialogBoxParamA@20 ;создаем программно-модальное диалоговое окно (тащусь от этих слов) ret DlgProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD xor ebx,ebx ;делаем это для того, чтобы заменить все push 0 на push ebx mov edi,hWin ;в edx теперь дескриптор диалогового окна mov eax,uMsg ;сообщение, которое характеризуется одной из константн MOV ESI,offset BUFFER ;буфер для пользовательского имени sub eax,10h ;cmp eax,WM_CLOSE;10h je @@WM_CLOSE sub eax,101h ;cmp eax,WM_COMMAND;111h jne a0 @@WM_COMMAND: mov eax,wParam ;wParam - константа характеризующая событие, которое приходит в диалог. окно dec eax ;cmp eax,IDOK;1 jne a0 ;прыгаем, если не нажимали IDOK PUSH 41 ;максимальное количество символов, которое может принять буфер (я установил 50) PUSH ESI ;offset BUFFER PUSH EBX ;0 PUSH EDI ;дескриптор диалогового окна CALL _imp__GetDlgItemTextA@16 cmp EAX,6 ;количество символов должно быть >=6 jl @@ERROR ;иначе прыг на месаг. бокс с ошибкой ;Функция генерации серийного номера ;Инициализируем данные push edi ;сохранение дескриптора диалогового окна push eax ;сохраняем количество букв нашего имени MOV ECX,ESI ;в ECX помещаем адрес Name MOV DL, BYTE PTR [ECX] XOR EDI, EDI ;Генерация последних четырех цифр серийного номера @@1: MOVZX DX, DL IMUL EDX, EDI ADD EBX, EDX INC EDI INC ESI MOV DL, BYTE PTR DS:[ESI] DEC EAX JNZ @@1 ;Снова инициализируем данные MOV ESI, ECX pop edi ;заносим количество букв имени в EDI MOV CL, BYTE PTR [ECX] ;Генерация первых четырех цифр серийного номера @@2: PUSH 8 POP EDX XOR ECX, ECX MOV CH,BYTE PTR [ESI] PUSH ESI @@3: MOV ESI, EAX XOR ESI, ECX TEST SI, SI JNS @@4 ADD EAX, EAX XOR EAX, 1021h JMP @@5 @@4: SHL EAX, 1 @@5: SHL ECX, 1 DEC EDX JNZ @@3 POP ESI INC ESI MOV CL, BYTE PTR [ESI] DEC EDI JNZ @@2 MOVZX ECX, BX ;в ЕСХ вторая часть серийного номера ADD EAX, 63h MOVZX EAX, AX ;в ЕАХ первая часть серийного номера shl eax,16 ;Путем магических пассов помещаем весь серийник в EAX, or eax,ecx ;причем в правильном порядке, т.е. сначала первая часть серийника xor ebx,ebx ;а потом вторая ;Далее идет "know-how" моя процедура перевода из 160-ричн. в 10-ричн. сис-му)), написанная за 15 минут, но к удивлению работает)) ;Здесь она начинается mov ecx,10h ;основание системы исчисления, из которой мы переводим - 16 pushad ;помещаем все регистры в стек от греха подальше push 8 pop ebx ;счетчик для цикла, т.к. у нас S/N это 8 символов, то цикл будет повторяться 8 раз @@A: xor edx,edx div ecx cmp dl,10 ;если значение <10, то заменяем его соотвествующим ASCII-символом jl @@B add dl,55 ;то же самое, но только если значение <10 jmp @@C @@B: add dl,48 @@C: mov byte ptr [esi-1],dl ;помещаем серийник в память на то место, где хранилось наше имя dec ebx ;заканчивать цикл? закончить если = 0 je @@D dec esi ;иначе продолжаем jmp @@A ;и переходим к следующему символу серийника @@D: popad ;здесь благополучно восстанвливаем все регистры ;На этом заканчивается процедура перевода ;теперь выводим серийник на экран, точнее в элемент управления pop edi ;Для этого восстанавливаем дескриптор диалогового окна lea eax,dword ptr [esi-8] ;в eax помещаем адресок, где находится наш серийник push eax ;передаем eax в функцию push 2 ;передаем ID нашего элемента управления в функцию push edi ;дескриптор диалога call _imp__SetDlgItemTextA@12 ;Это торжественный момент. Здесь выводится серийный номер! jmp a0 @@ERROR: ;сюда мы прыгаем, когда тупим push EBX push EBX push offset Text push EDI call _imp__MessageBoxA@16 ;информируем пользователя, что его действия это не то что от него ожидала программа PUSH EBX PUSH EDI CALL _imp__GetDlgItem@8 ;возвращает дескриптор оpгана упpавления,содеpжащегося в блоке диалога PUSH EAX call _imp__SetFocus@4 ;устанавливает фокус на орган управления jmp a0 @@WM_CLOSE: push ebx ;0 push edi ;hWin call _imp__EndDialog@8 ;посылаем менеджеру диалоговых окон сигнал о том, что мы завершаем приложение a0: xchg eax, ebx ret DlgProc endp ;*****Секция инициализированных данных***** ClassName db "DLGCLASS",0 DlgName db "Dlg",0 Text db "Минимальная длина имени - 6 символов",0 end start Кто смог меньше, не стесняйтесь, пишите. Можно в личку. Надеюсь на дальнешее сотрудничество))). Заранее Спасибо всем еще не ответившим и тем, кто направлял мои усилия в нужное русло. На всякий случай атачу сорцы и екзешник.
Думаю, оптимизировать дальше не имеет смыла. Это можно сделать только: 1) в написании вируса 2) написании шелл-кода 3) из спортивного интереса. Излишняя оптимизация приведет к усложнению кода. Вдруг найдешь когда-нить ошибку - сам же потом не разберешься P.S.: советую сделать 2 файла: exe - в котором будет храниться форма (окошка/диалог) и библиотеку - в ней будут все написанные тобой процедуры генерации кода. Это очень удобно. Я себе так же сделал.
Code (Text): P.S.: советую сделать 2 файла: exe - в котором будет храниться форма (окошка/диалог) и библиотеку - в ней будут все написанные тобой процедуры генерации кода. Это очень удобно. в моем случае это вряд ли имеет смысл, т. к процедур только 2 и обе маленькие Code (Text): Думаю, оптимизировать дальше не имеет смыла. именно из спортивного интереса! Я пока не хочу лезть PE заголовок и править его, там тоже могут возникнуть свои косяки.
Я имел ввиду, если ты не остановишься только на винзипе. У меня, к примеру, 16 кейгенов. Все они находятся в одном окне. Ну ладно, мое дело предложить, Ваше дело отказаться
))) ладно, не бери в голову. у меня пока что всего три....один из них вот на ассм перелапатил, 2 так и лежит еще на WinApi))) В дальнейшем хочу перелапатить все на ассм. Тогда уже задуматься надо будет о 2-х exe. Спасибо.
Morskoivolk Получить <1.5К можно с меньшими усилиями, написав этот кейген на С (без CRT, конечно). Компилятор сгенерит более эффективный код, чем тот, что ты привёл.
green Code (Text): Компилятор сгенерит более эффективный код, чем тот, что ты привёл т.е. получается, что можно оптимизировать на ассме до предела, а потом сделать то же самое на С и получится еще меньше? Получается можно накатать прогу на С, потом под отладчиком, например в Оле, запустить ее и посмотреть на более оптимизированный код, а затем можно его скопировать и переделать на ассме и получить улучшенный результат? Или же здесь играет решающую роль компилятор С?
Morskoivolk И наивно расчитывают, что другие (в данном случае - callback функция DlgProc) тоже не будут портить эти регистры. Да, хорошая мысль.
Morskoivolk Нет, конечно. Я имел в виду, что компилятор, скорее всего, сгенерирует более оптимальный код, чем ты. Чтобы переплюнуть хороший компилятор, нужно неслабо разбираться в архитектуре проца. --- Исключение - использование продвинутых инструкций типа MMX/SSE. Здесь компиляторы пока весьма слабы. Хотя в последняя версия Intel C++ вроде уже умеет оптимизировать с использованием SSE.
green конечно компиляторы хороши, но они действуют по строгим правилам. Если начнешь разбираться в процце, то запросто компилятор переплюнишь, а этому можно научиться только тогда, когда стремишься к этом. Насчет того чтобы посмотреть в ольке: мало того что ты просто скапируешь код, ты должен еще его проанализировать, и разобраться почему он зделал так и почему зделал вот так. А иначе в будущем станешь ходячим Си компилятором Хочешь вааще маленький размер? Зделай PE заголовок вручную, и консольный тип приложения. Типа вводишь имя и получаешь кейген
Ну конечно, о бездумном копировании и речи нету. Все будет фильтроваться и анализироваться. Я к тому, проще увидеть как это делает компилятор, чтобы поянть как надо.
Конечно на консоли это будет занимать намного меньше, да и быстрее будет по скорости. там API не путаются под руками и окно создавать не надо, не говоря про цикл обработки сообщений))). Да и вообще все это дело можно на Паскале нашлепать Но мне хочется именно в Win32 и на родном языке проца, т.е. на ассме.
может и путаю))) тока я уже говорил мне хочется на Win32, ну вот хочется и все, что ж тут поделаешь)) По ходу тему надо закрывать, последние сообщения уже не касаются топика))