← Октябрь 2002 → | ||||||
1
|
2
|
3
|
4
|
5
|
||
---|---|---|---|---|---|---|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
|
15
|
16
|
17
|
18
|
19
|
|
21
|
22
|
23
|
24
|
25
|
26
|
27
|
28
|
29
|
30
|
31
|
За последние 60 дней ни разу не выходила
Открыта:
21-07-2002
Статистика
0 за неделю
Программирование во всем великолепии
Информационный Канал Subscribe.Ru |
Программирование во всем великолепии.
Выпуск #00000005
Содержание:
1. Вступление.
2. Программирование на Assembler: Assembler для начинающих. Урок 5.
3. Программирование на Delphi: Delphi для начинающих. Урок 5.
4. JavaScript: Первые шаги. Урок 5.
5. Секреты Windows: Системный реестр.
6. Защита программ от взлома. Урок 1.
7. Программирование на Delphi: Получение слова под курсором мыши.
8. Как с нами связаться.
1. Вступление.
Мы легко забываем свои ошибки, когда они известны лишь нам одним
Франсуа де Ларошуко
Здравствуйте, уважаемые читатели. Сегодня перед вами пятый выпуск рассылки "Программирование во всем великолепии". Как всегда, продолжение статей по Assembler, Delphi, JavaScript. Также вы узнаете несколько интересных Секретов Windows.
В нашей рассылке пополнение - Fess. Он представит на ваш суд статьи по наболевшему, на наш взгляд, вопросу "Защита программ от взлома". Если у вас возникнут какие-либо вопросы, то пишите ему на lomovskih@yandex.ru
Вновь надеемся, что вся опубликованная в этом выпуске информация будет полезна для вас и интересна.
2. Программирование на Assembler: Assembler для начинающих. Урок 5.
автор: Вий
Здравствуйте, уважаемые подисчики! Сегодня мы сделаем обзор команд пересылки данных. Это MOV, XCHG, XLAT, LEA, LDS, LES.
Команда MOV:
Осуществляет передачу содержимого второго операнда в первый. Может применяться следующим образом:Формат: Пример: mov Регистр1, Регистр2 mov ax, dx mov Регистр, Память mov ax, word ptr _memory mov Регистр, СегмРегистр mov ax, ds mov Регистр, Константа mov cx, 12 mov Память, Регистр mov byte ptr _memory, al mov Память, СегмРегистр mov word ptr _memory, es mov Память, Константа mov word ptr _memory, 12h mov СегмРегистр, Регистр mov ds, ax mov СегмРегистр, Память mov es, word ptr _memoryРегистр флагов после выполнения команды не изменяется.
В последних двух командах нельзя использовать регистр cs.
Команда XCHG:
Обменивает содержимое первого и второго операндов. В качестве операндов не могут использоваться сегментные регистры.После выполнения команды регистр флагов не изменяется.
Команда XCHG AX, AX используется в качестве пустой команды. А-ля NOP.
Команда XLAT:
Заменяет содержимое регистра al на значение, выбираемое из таблицы, на которую указывает регистр bx. Содержимое регистра al интерпретируется как индекс выбираемого байта в этой таблице.Команда XLAT очень удобна для проведения табличных преобразований. Пусть в DS:BX содержится адрес на некоторую таблицу байт. В al помещается номер байта в таблице. В результате выполнения команды XLAT в al будет помещен байт с заданным номером.
Регистр флагов после выполнения команды не изменяется.
Команда LEA:
Загружает в первый операнд эффективный адрес памяти, который вычисляется в соответствии с указанным режимом адресации второго операнда. В качестве первого операнда можно использовать регистры общего назначения, а в качестве второго адрес ячейки памяти.После выполнения команды регистр флагов не изменяется.
Во многих случаях команда LEA идентична команде MOV с непосредственным операндом. Например:
LEA dx, _var_ <=> MOV dx, OFFSET _var_
Команда LDS:
Загружает в первый операнд (обычно SI) значение смещения, расположенное по адресу второго операнда, а в регистр DS загружает значение сегмента, расположенное по адресу второго операнда+2.Регистр флагов не модифицирует.
Используется в формате LDS Регистр, Память
Команда LES:
Загружает в первый операнд (обычно DI) значение смещения, расположенное по адресу второго операнда, а в регистр ES загружает значение сегмента, расположенное по адресу второго операнда+2.Регистр флагов не модифицирует.
Используется в формате LES Регистр, Память
Ну и в завершении, вот вам маленькая программка. Кто разберется, пишите мне. Впрочем, если не разберетесь, тоже пишите на veei@km.ru.
;---------------< convert.asm >--< begin >---------------------------- .186 code segment assume cs:code, ds:code, ss:code org 100h start: mov ah, 4eh ;Ищем первый файл lea dx, filename mov cx, 0eh ;Все файлы, кроме каталогов int 21h jc exit ;Если не нашли ни одного файла, выходим openfile: mov ax, 3d02h ;Пытаемся открыть файл для чтения/записи mov dx, 80h+1eh ;В dx адрес имени найденного файла int 21h jc exit ;Ошибка! Ищем дальше xchg bx, ax ;Сохраняем хэндл в bx mov cx, 0 ;Сохраняем в стеке позицию файла, пока 0 push cx cx encriptfile: mov ah, 3fh ;Считываем blocksize байт в buffer mov cx, blocksize ;Запрашиваем блок размером blocksize lea dx, buffer int 21h cmp ax, 0 ;Конец файла, выходим je closefile call encript ;Иначе перекодируем содержимое буфера pop dx cx ;Восстановим позицию в файле push ax ;Сохраним пока размер буфера mov ax, 4200h int 21h pop cx ;Размер буфера в CX add ax, cx ;Увеличиваем позицию в файле на размер буфера jnc setpointer inc dx setpointer: push dx ax ;Сохраняем позицию lea dx, buffer ;Записываем уже перекодированный буфер mov ah, 40h int 21h jmp encriptfile ;Продолжаем читать из файла closefile: mov ah, 3eh ;Закрываем файл, в BX - хэндл int 21h nextfile: mov ah, 4fh int 21h jc exit jmp openfile exit: int 20h ;Выходим encript proc pusha ;Сохраним все регистры в стеке lea si, buffer ;Из буфера загружаем, перекодировываем lea di, buffer ; и суем обратно lea bx, table localloop: lodsb ;Загружаем cmp al, 192 jb echar1 sub al, 192 xlat jmp endloop echar1: cmp al, 184 ;Это буква ё? jne echar2 mov al, 241 echar2: cmp al, 168 ;Это буква Ё? jne endloop mov al, 240 endloop: stosb ;Засовываем loop localloop ;Обрабатываем весь буфер popa ;Восстановим регистры ret ;Возврат из процедуры encript endp table db "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" filename db '*.txt',0 blocksize dw 1024 buffer db ? code ends end start ;---------------< convert.asm >--< end >------------------------------Всего хорошего. До скорых, надеюсь, встреч!
3. Программирование на Delphi: Delphi для начинающих. Урок 5.
автор: Rasa
Здравствуйте, уважаемые читатели! Сегодня мы рассмотрим операции, числовые и символьные типы данных.
Операции: В Object Pascal определены следующие операции:
унарные not, @; мультипликативные *, /, div, mod, and, shl, shr; аддитивные +, -, or, xor; отношения =, <>, <, >, <=, >=, in;Приоритет операций убывает в указанном порядке - то есть наивысшим приотритем обладают унарные операции. Объяснение действия каждой из них заняло бы много времени - я уточню, что not - это логическое отрицание, div - целочисленное деление, mod - остаток от деления, and - логическое "И", shl и shr - левый и правый сдвиг соответственно, or - логическое "ИЛИ", xor - исключительное "ИЛИ". Операция отношения in - применяется к двум операндам. Все это нам пока не нужно - вспомним об этом попозже! :)
В прошлом выпуске я кратенько написал о типах переменных - сегодня мы рассмотрим их более подробно. Как я и говорил, строка
var MyVariable: Integerговорит компилятору о том, что имя переменной - MyVariable, а ее тип - Integer.
Попробую объяснить попроще: Integer - значит целый - то есть переменная, тип которой (Integer) есть ничто иное, как число в дипазоне от -2147483648 до 2147483647. Вывод: это число может быть как отрицательным, так и положительным (или равно 0).
К примеру, переменная типа Cardinal может быть только не отрицательным числом (от 0 до 4294967295). В программе мы сможем присвоить им значения, например так:
MyVariable := 12345; // Целое число, без апострофовКроме того, бывают еще и символьные типы - например, String. Переменные символьного типа могут быть не только числами, но и буквами и различными символами (заключаются в апострофы).
Приведу пример таких переменных:
var MyStringVariable: string;В программе мы сможем присвоить им значения, например так:
MyStringVariable := 'Моя первая строковая переменная';попытка же присвоить такой переменной число окончится неудачей. Попытка присвоить числовому типу символы также не "прокатит". :) Вообще-то типов данных немало, перечисление их - дело долгое и скучное ;)
Хорошо, попробуем реализовать парочку способов в своей программе: между строчками
var Form1: TForm1;и
implementationопределим три новых переменных - получится так:
var Form1: TForm1; MyVar1: Integer; MyVar3, MyVar4: String;Переменные, конечно получилсь глобальными, но на первый раз это простительно. На форму бросим кнопку и в обработчике ее события (нажатие) напишем следующий код:
begin MyVar1 := 5; MyVar3 := 'Программирование '; MyVar4 := 'во всем великолепии '; end;Теперь сделаем так, чтобы, при нажатии на эту кнопку, нашим переменным не только присваивались бы и значения, но и выводился бы результат сложения или вычитания. Выведем результат, к примеру, в заголовке окна.
Для этого межжу
MyVar2 := 2;и
end;дописываем такие строчки:
Form1.Caption := MyVar3 + MyVar4 + IntToStr(MyVar1); // Form1.Caption - это свойство формы, которое // содержит в себе текст заголовка окна // IntToStr - стандартная процедура, которая // преобразует числовое значение в символьноеВ результате, после запуска программы, и нажатии на кнопку, в заголовке окна появится такой текст:
Программирование во всем великолепии 5
Значения символьных переменных можно складывать между собой также, как и значения числовых.
Что ж. Думаю, у вас есть вопросы - пишите на rasa@fromru.com! Удачи!
4. JavaScript: Первые шаги. Урок 5.
автор: UniQ
Здравствуйте уважаемые подписчики! Темой нашего сегодняшнего урока будут функции. Этот материал важен, его необходимо хорошо усвоить. Начнём. Функции, в большинстве случаев, используются для объединения нескольких команд. Давайте рассмотрим пример:
<html> <script language="JavaScript"> <!-- скрываем скрипт document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>"); document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>"); document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>"); document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>"); --> </script> </html>Этот скрип просто выводит текст:
Привет! Это JScript! Это снова Я!четыре раза. Если посмотреть на скрипт, то можно увидеть что
document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>");повторяется 4 раза. Может возникнуть мысль, а не проще ли ОБЪЕДИНИТЬ повторяющийся кусок кода в одно единое? Вот мы и подошли вплотную к теме сегодняшнего урока! Нужно написать функцию, которая выводила бы повторяющийся кусок кода. Например, так:
<html> <script language="JavaScript"> <!-- скрываем скрипт function WriteIt() { document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>"); } WriteIt(); WriteIt(); WriteIt(); WriteIt(); --> </script> </html>И что мы видим в результате выполнения скрипта? А то же, что и в первом примере! Но в отличие от первого примера, второй имеет меньший размер и, следовательно, грузится быстрее. Теперь давайте разберём следующую часть кода:
function WriteIt() { document.write("Привет! Это JScript!<br>"); document.write("Это снова Я!<br>"); }И так, видно, что определение функции начинается с ключевого слова - function за которым следует имя функции. Замечу, что на имя функции накладываются те же ограничения, что и на имена переменных, которые мы рассмотрели на предыдущем уроке. Всё тело функции заключается в фигурные скобки - {}. Теперь мы получили новую, пользовательскую, функцию, которая объединяет в себе несколько стандартных функций. Далее в скрипте:
WriteIt(); WriteIt(); WriteIt();Здесь, мы три раза вызываем нашу функцию. Таким образом, мы получаем тот же результат, что и в первом примере. Возможно, после прочтения этого материала, полезность использования функций представляется смутно. Да, действительно, мало пользы от таких функций! Но функции могут иметь параметры! Именно возможность передачи переменных при вызове функции делает наши скрипты действительно гибкими. Пример:
<html> <script language="JavaScript"> <!-- скрываем скрипт function WriteIt(strVar1,strVar2) { document.write("<h1><font color='#0000FF'>"+strVar1+"</h1></font><br>"); document.write("<h2><font color='#00FF00'>"+strVar2+"</h2></font><br>"); } WriteIt("Привет! Это JScript!","Это снова Я!"); --> </script> </html>В этом примере пользовательская функция WriteIt принимает два параметра:
function WriteIt(strVar1,strVar2)Параметры разделяются запятой. Параметры обрабатываются внутри функции и выводятся на экран. Вообще параметров у функции может быть и куда больше двух (на самом деле не более 255)! Но иногда возникают такие ситуации когда количество передаваемых параметров может варьироваться, не проблема если их становится меньше, а если больше? На самом деле и эту проблему можно решить довольно изящно, следующий пример иллюстрирует это:
<html> <script language="JavaScript"> <!-- скрываем скрипт function WriteIt() { var strParam = WriteIt.arguments; for(var i=0; i<strParam.length; i++) { document.write("Параметр "+i+": "+strParam[i]+"<br>"); } } document.write("Здесь <strong>WriteIt()</strong> принимает 2 параметра:<br><br>"); WriteIt("Привет!Это JScript!","Это снова Я!"); document.write("<br>Здесь <strong>WriteIt()</strong> принимает уже 7 параметров:<br><br>"); WriteIt("Каждый","Охотник","Желает","Знать","Где","Сидит","Фазан"); --> </script> </html>Вот она настоящая гибкость JScript! Не отчаивайтесь если Вам здесь, что-то не понятно. Со временем Вы всё поймёте. А пока займёмся изучением примера. С циклами мы с вами познакомились на прошлом уроке, здесь всё должно быть понятно. Ключом к пониманию этого примера являются строки:
var strParam = WriteIt.arguments; for(var i=0; i<strParam.length; i++)
Здесь переменная strParam будет будет содержать массив параметров, переданных функции, а обращение: strParam.length даёт нам количество этих параметров. Вот вроде бы и всё что касается функций. И так мы выяснили, что функции могут объединять в себе несколько команд, могут принимать и обрабатывать параметры. А так же выяснили как поступить если количество параметров заранее не известно.
На этом я заканчиваю сегодняшний урок. Если у Вас возникли вопросы, обращайтесь: post-master@rambler.ru Дорогу осилит идущий.
До свидания!
5. Секреты Windows: Системный реестр.
автор: Rasa
Здравствуйте, дорогие читатели!
Сегодня, в этой статье, я расскажу вам о том, как можно создать свой объект на Рабочем столе или в папке Мой компьютер. Процесс это несложный - потребуется лишь немного терпения. Разработчики Windows 98 не предусмотрели создание объектов силами самой операционной системы - возможно, они посчитали, что пользователям это не нужно. Ошибались они или нет, судить вам, читатель.
Для начала приведу несколько примеров объектов:
На Рабочем столе - Корзина, Сетевое окружение, Входящие, Мои документы и другие. В папке Мой компьютер - Назначенные задания, Удаленный доступ к сети, Web Folders и т.д. Прочитав эту статью вы сможете создавать новые и удалять существующие объекты. Но мы рассмотрим только первый вариант ;-)
Давайте запустим редактор реестра и откроем ветку
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorerУже на этом этапе предстоить выбрать, где мы будем создавать объект: на Рабочем столе или в папке Мой компьютер. Если вы выбрали первое (кстати, гораздо удобнее), то открываем подразделы Desktop\NameSpace, то есть переместимся в ветвь реестра
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Desktop\NameSpaceесли же вы решили создать объект в папке Мой компьютер, то перейдите в раздел
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\MyComputer\NameSpaceостальные все наши действия будут абсолютно одинаковыми для обоих разделов.
В качестве примера я выбрал Рабочий стол.
В разделе NameSpace вы увидите GUID'ы объектов. Посмотрите их
значения по умолчанию:
для Корзины (GUID - {645FF040-5081-101B-9F08-00AA002F954E}),
для папки Мои документы (GUID - {450d8fba-ad25-11d0-98a8-0800361b1103})
и т. д.
Теперь нам надо придумать новый GUID (строку типа {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}, где X ≈ это любая цифра или латинская буква от A до F). Придумывать долго не придется - тем не менее, если вы считаете, что придумаете уже существующий GUID :), рекомендую вам воспользоваться утилитой GUIDgen, поставляемой с Visual Basic (папка \COMMON\TOOLS\VB\IDGEN). Выбрав опцию 'Формат реестра' нажимаем 'Новый GUID'. Полученную строку мы и будем использовать далее. А что же делать, если таких утилит нет под рукой? В таком случае я предлагаю следующий метод: открываете раздел реестра HKEY_CLASSES_ROOT\CLSID, выбираете любой GIUD, меняете в нем несколько символов - и новый, уникальный GUID готов!
К примеру, пусть наш GUID будет {C3C52282-C9D2-11d6-BFB9-0040951B9402}. Тогда в ветви
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Desktop\NameSpaceмы создаем подветвь с именем нашего GUID. Параметр по умолчанию созданной ветки будет отображаться под нашим объектом на Рабочем столе (то есть будет его именем). Напишем туда 'Мой объект!'
Теперь перемещаемся в раздел GUID'ов, то есть в HKEY_CLASSES_ROOT\CLSID и в нем тоже создаем раздел с именем {C3C52282-C9D2-11d6-BFB9-0040951B9402} (параметр по умолчанию укажем 'Мой объект!'). Также в этой ветке создайте строковый параметр 'InfoTip' и напишите в него 'Всплывающая подсказка к моему объекту'.
Параметр InfoTip содержит в себе текст, который будет показан в момент, когда курсор мыши задержался над нашим объектом.
Теперь укажем значок для нашего объекта. В созданной нами ветви HKEY_CLASSES_ROOT\CLSID\{C3C52282-C9D2-11d6-BFB9-0040951B9402} создаем подраздел с именем DefaultIcon и в параметре по умолчанию указываем путь к иконке, например C:\Main\Icons\obj.ico,0. (вспомните, как назначали свою иконку диску в одном из прошлых выпусков - точно так же!)
Теперь назначим команду, которая будет выполняться при щелчке на наш объект. В ветви HKEY_CLASSES_ROOT\CLSID\{C3C52282-C9D2-11d6-BFB9-0040951B9402} создадим раздел Shell, в нем подраздел Open, а в ветви Open создадим раздел Command. Получиться у вас должна такая ветвь:
HKEY_CLASSES_ROOT\CLSID\{C3C52282-C9D2-11d6-BFB9-0040951B9402}\Shell\Open\Command(у нас уже были раньше подобные примеры :) )
Ну, и в параметре по умолчанию укажем путь к запускаемой программе. Минимальная установка оюъекта на Рабочий стол закончена! :) Для того, чтобы запретить удалять наш объект с Рабочего стола, создайте раздел
HKEY_CLASSES_ROOT\CLSID\{C3C52282-C9D2-11d6-BFB9-0040951B9402}\ShellFoldersи в нем создайте параметр двоичного типа с именем Attributes. Установите его значение в 40 00 00 00.
Если вы внимательно читали предыдущие выпуски, то должны были догадаться, что в контекстное меню нашего объекта можно добавлять и другие свои пункты. Если же вы хотите, чтобы при щелчке на наш объект не запускалась программа, а открывалась определенная папка, то в параметре по умолчанию ветви
HKEY_CLASSES_ROOT\CLSID\{C3C52282-C9D2-11d6-BFB9-0040951B9402}\Shell\Open\Commandукажите C:\Windows\Explorer.exe C:\MyFolder. C:\Windows\Explorer.exe - путь к проводнику Windows, а C:\MyFolder - путь к вашей папке и ее имя.
Тему закрыть на этом невозможно, могу лишь перефразировать известное выражение - "Пути Windows неисповедимы" :) Так что - экспериментируйте, добавляйте что-то свое и анализируйте полученный результат!
Если у вас вдруг возникнут какие-либо вопросы, то пишите мне на e-mail: rasa@fromru.com - я обязательно отвечу на ваши вопросы! До свидания!
6. Защита программ от взлома. Урок 1.
автор: Fess
Привет народы! Меня зовут Fess, я уже несколько лет занимаюсь крэком. По этому я буду вести здесь раздел по защите ваших творений от меня и моих собратьев. Первая статья будет общей и вводной, поэтому не ищите в ней ответ на вопрос "Как защититься от Soft Ice?" его тут нет, он будет рассмотрен в следующих моих статьях. Поехали.
Перво-наперво скажу главное: "Сломать можно любую программу", как бы вы не изгалялись и не протирали буквы на клавиатуре. Всегда найдется тот, кто сможет порушить вашу защиту, как карточный домик. При разработке своей защиты обратите внимание на следующие моменты: полезность вашей программы, цена программы, исходя из этого, должна строится тактика защиты. Почти все крэкеры исходят из стратегии полезность + цена / время взлома, если виртуальное число больше единицы, то ломать будут, иначе нет, разве что просто так.
Этап оценки. Внимательно взгляните на свою чудо программу, объективно прикиньте, сколько человек захотят ею воспользоваться, и кто эти люди. Если она предназначена для деловых людей, то имеет смысл цену дать повыше (у нас в стране не так-то много деловых людей с деньгами), если же она для рядового пользователя, то цену надо делать поменьше, иначе ее никто не купит. Вывод: чем меньше цена, тем легче пользователю купить программу, а не искать к ней кряк.
Этап разработки защиты. Вспомните, сколько примерно часов вы потратили на написание программы, затем умножьте на 0.05 и получите число часов нужных для разработки достаточной защиты.
Теперь посмотрите на список всех известных мне на данный момент способов защиты своего программного обеспечения. Стойкость рассчитывалась как время нахождения правильного ключа, при условии, что вы знаете, что делаете.
Ну, вот и все на сегодня. В следующих статьях мы постепенно с примерами будем разбирать каждый из приведенных типов защиты. Плюс, какой-нибудь один способ уберечь свои драгоценные творения. Если что-то вас интересует, то пишите мне на e-mail: lomovskih@yandex.ru.1) Все возможные коды находятся в программе.
Описание: Не нужно. Время написания: 10 минут Стойкость: нулевая Заметки: Такие защиты крэкеры называют "Худшая защита месяца"2) Комбинация имя-ключ
Описание: Берем вводимое имя и с помощью специального алгоритма генерируем по нему ключ. Время написания: 20 минут - 3 часа Стойкость: маленькая - средняя Заметки: Стойкость зависит от сложности алгоритма генерации ключа. Настоящий можно будет подсмотреть в самой программе, при проверке с введенным. Чтобы этого не произошло, я рекомендую поступать следующим образом: генерировать из кода и имени по ключу, а уж потом их и сравнивать. Или сравнивать побайтно.3) Комбинация код-ключ
Описание: По коду, сгенерированному на основе системных требований, делается ключ, который и сравнивается с введенным Время написания: 50 минут - 8 часов Стойкость: выше маленькой - выше средней Заметки: Позволяет получить дополнительное преимущество, присланный ключ не будет работать на машинах с другой конфигурацией.4) Ввод только ключа
Описание: По ключу генерируется контрольная сумма, которая сравнивается с кодом, записанным в программе. Время написания: 30 минут - 8 часов Стойкость: средняя - выше средней Заметки: Все зависит от процедуры генерации, если она хорошая, то новички сразу отпадают.5) Ключ в реестре или ключевой файл
Описание: В файле или реестре создается длиннющая строка символов, по которой генерируется контрольная сумма, которая сравнивается с правильной. В этих комбинациях возможен контроль на ограниченный период. Время написания: 1 час - 20 часов Стойкость: средняя - высокая Заметки: Сразу скажу, что ключевой файл это самый сложный тип защиты, если сделано все хорошо, то и нормальные крэкеры отпадают.6) Навески, протекторы, паковщики
Описание: Комплекс отдельных программ, которые, пристыковавшись к вашей (как вирус) программе выполняют определенные функции, такие как защита от отладки, защита от патча, защита от изменения файла, а так же могут запаковывать программу - делать ее меньше. Время написания: 5 минут - 5 суток. Стойкость: ? - высокая Заметки: Все зависит от того, используете ли вы чужие программы подобного типа, или же пишите свои. Во втором случае защита скорее всего будет высокой.7) Демо-версия
Время написания: 20 минут - 2 часа. Стойкость: максимальная (при условии, что функции физически удалены). Заметки: Самый надежный тип защиты. Единственный недостаток, только в отправке полноценной версии адресату.
Совет: настоятельно рекомендую перед бросанием свой программы на "рынок", показать ее защиту знакомому крэкеру с просьбой сломать. Если он нормально в этом разбирается и не осилит, то можете смело ее выкладывать.
7. Программирование на Delphi: Получение слова под курсором мыши.
Идея: Rasa
Реализация: Вий
Создавая HTML-редактор, я решил сделать его таким же удобным, как и редактор кода Delphi. Одной из проблем стало нахождение слова под курсором мыши. То есть, чтобы при наведении на слово, всплывала подсказка с информацией о данном, допустим, теге. Сделал я это следующим образом:
Так-с... Для нашего примера надо будет создать форму с компонентом TMemo и TLabel.
Ну, во-первых, что можно считать словом? Напрашивается ответ "Последовательность букв, ограниченная разделителями слов...". Для этого в программе я определил множество допустимых для слова символов:
... var Form1: TForm1; Chars : set of Char = ['A'..'z', 'А'..'Я', 'а'..'я', '-', '@', '&']; ...Далее, организуем обработчик события OnMouseMove для Memo1. Остальное смотрите в субботу в 18:00 на канале НТВ... :):
... procedure TForm1.Memo1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var i : integer; b, e : integer; //Начало и конец слова begin (* Для получения индекса символа в Memo посылаем ему сообщение EM_CHARFROMPOS. wParam равен нулю, lParam равен MAKELPARAM(X, Y), где X и Y - координаты точки относительно левого верхнего угла компонента Memo. SendMessage возвратит в младшем слове индекс символа, а в старшем - номер линии, в которой находится этот символ. Если ошибка (а-ля точка за пределами клиентской области Memo), то результатом выполнения функции будет -1. Номер линии нам сейчас не нужен. *) b := SendMessage(Memo1.Handle, EM_CHARFROMPOS, 0, MAKELPARAM(X, Y)); (* Итак, если нет ошибки, то смотрим, что там за слово. *) if b<>-1 then begin b := b and $FFFF; //Нам надо только младшее слово e := b; //Конец слова пока равен его началу //Пока слово не начиается раньше самого текста и первый символ // слова может использоваться в слове, индекс начала слова // уменьшаем на единицу while (b>0) and (Memo1.Text[b] in Chars) do dec(b); //С концом слова примерно то же самое... i := length(Memo1.Text); while (e<i) and (Memo1.Text[e] in Chars) do inc(e); //Дальше из Memo копируем искомое слово Label1.Caption := copy(Memo1.Text, b+1, e-b-1); end else Label1.Caption := 'Fuck!!!'; //Для души... %) end; ...Ну вот, вроде бы и все. Надеюсь, что вы разобрались с исходником. Если не понятно, пишите.
8. Как с нами связаться.
Возможно у Вас есть пожелания по улучшению рассылки или Вы, на
страницах нашей рассылки, хотели бы увидеть материалы по другим
областям программирования, предлагайте, мы рассмотрим и учтём их.
Ведь эти статьи пишутся программистами для программистов!
Ждем ваших отзывов.
Rasa: rasa@fromru.com
Fess: lomovskih@yandex.ru
UniQ: post-master@rambler.ru
Рассылка может отображаться некорректно в программе The Bat! Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+
http://subscribe.ru/
E-mail: ask@subscribe.ru |
Отписаться
Убрать рекламу |
В избранное | ||