Электронно-цифровая подпись

Разработка программы реализующей алгоритм ЭЦП методом RSA. Структура и организация файловой системы диска (Floppy 3.5), работа с ним операционных систем MS-DOS и Windows 9.x. Характеристика методов взлома информации. Тестирование метода защиты информации.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 09.03.2009
Размер файла 49,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

2

Министерство образования и науки Украины

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовому проекту

На тему: "Электронно-цифровая подпись"

по курсу "Кодирование и защита информации"

2002

Содержание

Введение

1. Обзор методов взлома информации

2. Алгоритм реализованного метода

3. Тестирование метода защиты информации от копирования

3.1 Метод первый. Восстановлении служебной информации дискеты

3.2 Метод второй. Взлом защиты со скрытой частью

3.3 Метод третий. Взлом дискеты при создании дополнительной дорожке на дискете

Библиографический список

Заключение

Приложение

Введение

Целью данного курсового проектирования является разработка программы реализующей алгоритм ЭЦП методом RSA. Кодирование является сегодня актуальной проблемой, для тех кто хочет защитить информацию, так как какая не была бы защита ее можно взломать. В курсовом проекте я реализовал довольно примитивный взлом защищенной дискеты.

Для реализации данного метода необходимо изучить структуру и организацию файловой системы диска (Floppy 3.5), и работу с ним операционных систем MS-DOS и Windows 9.x.

1. Обзор метода RSA

Существует два метода шифрования. Одним из методов так называемого шифрования является RSA . Данный метод шифрования происходит с помощью нахождения открытого и закрытого ключей, затем находим остальные параметры.

Теперь перейдем к нашей теме, в которой указано, что ломать надо именно дискеты. В настоящее время вообще зашита дискет уже не используется, а если и используется, то всеми методами извесными взломщику. Конечно те кто ставит защиту делают акцент на обычных пользователей, а для людей занимавшихся взломами это не составит труда.

Дело в том что взлом связан непосредственно с защитой, т.к. сначала идет защита а заткем уже взлом этой защиты, поэтому я буду пользоваться этими словами, как с `синонимами'.

Защита дискет осуществляется многими способами. Можно полностью отрезать возможность открытия дискеты, для этого нужно всего лишь изменить первый байт, первой дорожки первого секторы, эта дорожка является информационной, и поэтому, если информация будет повреждена, то при открытии дискеты ОС выдаст сообщение, что дискета неотформатированна. Аналогично взлом в этом случае очень прост, т.е. мы помещаем на это место законный байт со стандартной инфой $EB.

Другой метод предполагает защиту со скрытой частью. В конце файла всегда есть пустое место со всяким мусором, потому что маловероятно, что файл займет количество секторов кратное размеру одного кластера, но даже если и так то это не составит никакой проблемы. Мы в это пустое место помещаем какую-нибудь информацию, и при запуске программы будет проверяться наличие информации, если ее не окажется, то программа не будет работоспособной. Для этого способа защиты существует несколько методов взлома. К первому методу относится чтение с дискеты поблочно, ко второму возможность дизассемблирования файла и ликвидацию проверки наличия информации.

Я использовал несколько способов взлома к различного рода защите.

Первый способ это восстановление служебной информации находящейся на дискете. Это осуществляется посредством прерывания $13.

Функция $02 - чтение сектора диска

Функция $02 - запись сектора диска

Далее перечислим регистры которые заполняются для выполнения функций чтения и записи:

Для чтения:

AL - Количество секторов нужно прочитать

CH - Номер дорожки

CL - Номер сектора

DH - Номер дорожки

Dl - Адрес устройства

[ES:BX] - буфер, в который осуществляется чтение сектора.

Для записи:

Функция 03h - запись сектора на диск, где

AL - Количество секторов нужно записать

CH - Номер дорожки

CL - Номер сектора

DH - Номер дорожки

Dl - Адрес устройства

[ES:BX] - буфер с данными, которые записываются в сектор диска

2. Алгоритм реализованного метода

2

2

2

2

3. Тестирование метода взлома информации с целью нелегального пользования

3.1 Метод первый. Восстановлении служебной информации дискеты

Программа испытывалась в операционных системах MS-DOS и Windows 9.x. При заблокировании дискеты с помощь программы legal.exe мы считываем boot sector и определяем, что произошло изменение служебной информации дискеты. Затем запускаем программу grabber.exe и тем самым восстанавливаем дискету. И теперь информацией расположенной на дискетете можно пользоваться.

3.2 Метод второй. Взлом защиты со скрытой частью

На дискете имеется программ а в скрытой части находится какая либо информация. Если скачать файл с дискеты на диск то скопированная программа будет не рабочей. Для того чтобы сделать скопированную версию рабочей, сначалы мы читаем информацию, которая находится в конце файла на дискете, а затем записываем ее в конец файла копии программы. Либо можно воспользоваться системной утилитой DiskCopy.

Также в стационарную программу можно записать дату изготовления ПЗУ, при перенесении этой программы на другую машину будет проверяться дата ПЗУ и если это не легальная копия, то программа будет недееспособной. Поэтому мы при перенесении копии на другую машину соответственно в срытую часть запишем дату ПЗУ текушей машины.

3.3 Метод третий. Взлом дискеты при создании дополнительной дорожке на дискете

На стандартной дискете находится 80 дорожек по 18 секторов на каждой. Но для защиты можно создать дополнительную дорожку при этом ее не будет видно, т.е. в служебной части по-прежнему будет находиться информация о 80 дорожках. Допустим, что в эту дополнительную часть можно поместить данные лимита установок с дискеты на HD. При последующей установке просто уменьшать счетчик. А стационарную программу защищать уже известным нам способом со крытой частью.

Со взломом стационарной копии мы уже умеем справляться, а для взлома мобильной копии нужно просто запустить программу disketta.exe. И пользуетесь нелегальным программным обеспечение сколько угодно, если лимит закончился, то снова запускаем программу disketat.exe. Т.е. эта программа выступает в качестве патча.

Заключение

В заключении курсового проектирования можно отметить, что поставленная задача была выполнена. Полученные результаты показали, что защита информации от копирования является сегодня важной проблемой, которая не имеет на данный момент универсального решения, которое можно было бы применять во всех сферах информационных систем. Большое количество частных решений проблемы, дает возможность лишь частичной защиты информации от копирования, но при объединении методов защиты от копирования и шифровальных методов, получение несанкционированного доступа к информации сильно затрудняется.

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

Библиографический список

1.Турбо Паскаль 7.0 - Практика программирования. Форонов В.В.

2. Конспект лекций по дисциплине «Кодирование и защита информации», СевНТУ, Василенко В.А.

Приложение

Метод первый. Восстановлении служебной информации дискеты

VAR

CarrySet, InfoAvail: boolean;

bufer:array[1..512] of byte;

Items:Byte;

f:file of byte;

i:Integer;

{ ---------------------------------------------------------------- }

Procedure ResetDrive; {Reset Controler}

var R: Registers;

Begin

R.DL:=0; {Creating parametrs int 13h for function 00h}

R.AH:=0;

Intr($13,R);

End;

{ ---------------------------------------------------------------- }

Procedure ReadSectors(Drive,Track,Head,Sect,N: byte; var Buf);

var R: Registers;

begin

with R do

begin

AH:=2; {Number of function , 02h- is a reading sectors}

DL:=Drive; {Current Drive}

DH:=Head; {Curent Head of Floppy}

CH:=Track; {Curent Track of Floppy}

CL:=Sect; {Curent sectors of Floppy}

AL:=N; {Numbers of Sectors reading}

ES:=Seg(Buf); BX:=Ofs(Buf); {Creating Buffer for data}

end;

Intr($13,R);

if R.Flags and FCarry <> 0 then CarrySet:=true

else CarrySet:=false;

end;

{ ---------------------------------------------------------------- }

Procedure WriteSectors(Drive,Track,Head,Sect,N: byte; var Buf);

var R: Registers;

begin

with R do

begin

AH:=3; {Number of function , 03h- is a writing sectors}

DL:=Drive; {Current Drive}

DH:=Head; {Curent Head of Floppy}

CH:=Track; {Curent Track of Floppy}

CL:=Sect; {Curent Sector of Floppy}

AL:=N; {Numbers of Sectors reading}

ES:=Seg(Buf); BX:=Ofs(Buf);{Creating Buffer For DAtA}

end;

Intr($13,R);

if R.Flags and FCarry <> 0 then CarrySet:=true

else CarrySet:=false;

end;

Procedure LockedDisk; {Locked disk}

var

i: Word;

Begin

ClrScr;

ReadSectors(0,0,0,1,1,Bufer);

for i:= 1 to 512 do

Bufer[i]:=$00;

WriteSectors(0,0,0,1,1,Bufer);

End;

{ ---------------------------------------------------------------- }

procedure Crack; forward;

Function UnlockedDisk:Boolean; {Unlocked Disk}

Begin

ClrScr;

Crack;

WriteSectors(0,0,0,1,1,Bufer);

End;

procedure Veiw;

begin

ReadSectors(0,0,0,1,1,Bufer);

Assign(f,'c:\boot.dat');

rewrite(f);

For i:=1 to 512 do

Begin

Write(f,Bufer[i]);

End;

Close(f);

end;

procedure Crack;

begin

Assign(f,'c:\boot.dat');

reset(f);

For i:=1 to 512 do

Begin

Read (f,Bufer[i]);

End;

Close(f);

end;

{ ---------------------------------------------------------------- }

Begin

ClrScr;

Writeln('1-Видим диск А');

Writeln('2-Не видим диск А');

Writeln('3-Просмотр служебной информации');

Readln(Items);

Case Items of

1: UnlockedDisk;

2: LockedDisk;

3: Veiw;

End;

End.

Метод второй. Взлом защиты со скрытой частью.

Программа защиты

Var

F: file;

L:LongInt;

S:string;

begin

S:= '1234567';

Assign(F,ParamStr(1));

reset(F,1);

L:= FileSize(F);

Seek(F,L);

BlockWrite(F,S,succ(Length(S)));

seek(F,L);

truncate(F);

end.

Программа взлома

var

L,Buf: Longint;

F:file;

S:string;

begin

Assign(F,'a:\vzlom.exe');

reset(F,1);

L:= FileSize(F);

seek(F,L+256); {Увеличиваем длинну файла

на 256 байт, чтобы исключить

исключить ошибку чтения из

хвоста файла}

BlockWrite(F,S,1);

seek(F,L);

BlockRead(F, S, 256);

seek(F,L);

truncate(F);

Close(F);

writeln(S);

if S<>'1234567' then begin

Writeln('Нелегальная копия');

Readln;

Exit;

end

else

Writeln('Это легальная копия');

end.

Третий метод. Создание дополнительной дорожки

Модуль F_Disk для работы с дискетами на физическом уровне

UNIT F_Disk;

{Модуль содержит подпрограммы для гибкой работы с дисками.

Во всех подпрограммах параметр DISK относится к логическим

дискам: 0=А, 1=В, 2=С, 3=D и т.д. Параметр SEC - относительный номер сектора: 0 = загрузочный сектор, далее по

секторам до конца дорожки, по головкам, по цилиндрам. }

INTERFACE

Type

{Информация из ВРВ загрузочного сектора:}

BPB_Type = record

SectSiz: Word; {Количество байт в секторе}

ClustSiz: Byte; {Количество секторов в кластере}

ResSecs:Word; {Количество секторов перед FAT}

FatCnt:Byte; {Количество FAT}

RootSiz:Word; {Количество элементов корневого каталога}

TotSecs:Word; {Количество секторов на диске}

Media:Byte; {Дескриптор носителя}

FatSize:Word; {Количество секторов в FAT}

end;

{Дополнительная информация из загрузочного сектора:}

Add_BPB_Type = record

TrkSecs: Word; {Количество секторов на дорожке для разделов меньше 32 Мбайт или 0}

HeadCnt: Word; {Количество головок}

HidnSecLo: Word; {Количество спрятанных секторов для разделов меньше 32 Мбайт}

HidnSecHi: Word; {Вместе в HidnSecLo дает количество спрятанных секторов для разделов больше 32 Мбайт}

LargSectors: Longint; {Общее количество секторов для разделов больше 32 Мбайт}

end;

{Элемент дискового каталога:}

Dir_Type = record case Byte of 1: (

Name: array [1..8] of Char; {Имя файла или каталога}

Ext: array [1..3] of Char; {Расширение}

FAttr: Byte; {Атрибуты файла}

Reserv: array [1..10] of Byte; {Резервное поле}

Time: Word; {Время создания}

Date: Word; {Дата создания}

FirstC: Word; {Номер первого кластера}

Size: Longint {Размер файла в байтах});

2:(NameExt: array [1..11] of Char)

end;

{Описатель логического раздела}

PartType = record

Act: Boolean; {Флаг активности раздела}

BegHead: Byte; {Головка начала раздела}

BegSC: Word; {Сектор/цилиндр начала}

SysCode: Byte; {Системный код}

EndHead: Byte; {Головка конца раздела}

EndSC: Word; {Сектор/цилиндр конца}

RelSect: Longint; {Относительный сектор начала}

FoolSiz: Longint {Объем в секторах}

end;

{Загрузочный сектор диска}

PBoot = ^TBoot; TBoot = record case Byte of 0: (

a: array [1..11] of Byte;

BPB: BPB_Type;

Add: Add_BPB_Type;

c: array [1..+$1BE-(SizeOf(BPB_Type)+SizeOf(Add_BPB_Type)+11) ] of Byte;

Par: array [1..4] of PartType);

1: (b: array [1..512] of Byte)

end;

{Описатель диска по структуре IOCTL}

IOCTL_Type = record

BuildBPB:Boolean; {Строить BPB}

TypeDrv:Byte; {Тип диска}

Attrib:Word; {Атрибуты диска}

Cylindrs:Word; {Число цилиндров}

Media:Byte; {Тип носителя}

BPB: BPB_Type;

Add: Add_BPB_Type;

Reserv: array [1..10] of Byte;

end;

{Описатель диска}

TDisk = record

Number:Byte; {Номер диска 0=A,...}

TypeD:Byte; {Тип диска}

AttrD:Word; {Атрибуты диска}

Cyls:Word; {Число цилиндров на диске}

Media:Byte; {Дескриптор носителя}

SectSize:Word; {Количество байт в секторе}

TrackSiz:Word; {Количество секторов на дорожке}

TotSecs:Longint;{Полная длина в секторах}

Heads:Byte; {Количество головок}

Tracks:Word; {Число цилиндров на носителе}

ClusSize:Byte; {Количество секторов в кластере}

MaxClus:Word; {Максимальный номер кластера}

FATLock:Word; {Номер 1-го сектора FAT}

FATCnt:Byte; {Количество FAT}

FATSize:Word; {Длина FAT в секторах}

FAT16:Boolean;{Признак 16-битового элемента FAT}

RootLock:Word; {Начало корневого каталога}

RootSize:Word; {Количество элементов каталога}

DataLock:Word; {Начальный секторов данных}

end;

{Список описателей диска}

PListDisk = ^TListDisk;

TListDisk = record

Disklnfo: TDisk; {Флаг ошибки}

NextDisk: PListDisk; {Код ошибки}

end;

var

Disk_Error:Boolean;

Disk_Status:Word;

const

Disks: PListDisk = nil;{Начало списка описателей диска}

Function ChangeDiskette(Disk: Byte): Boolean;

{Возвращает TRUE, если изменялось положение запора на указанном приводе гибкого диска}

Procedure FreeListDisk(var List: PListDisk);

{Удаляет список описателей дисков}

Procedure GetAbsSector(Disk,Head: Byte; CSec: Word; var Buf);

{Читает абсолютный дисковый сектор с помощью прерывания $13}

Function GetCluster(Disk: Byte;Sector: Word): Word;

{Возвращает номер кластера по заданному номеру сектора}

Function GetDefaultDrv: Byte;

{Возвращает номер диска по умолчанию}

Procedure GetDirItem(FileName: String; var Item: Dir_Type);

{Возвращает элемент справочника для указанного файла}

Procedure GetDirSector(Path: String; var Disk: Byte; var Dirs,DirSize: Word);

{Возвращает адрес сектора, в котором содержится: начало нужного каталога, или 0, если каталог не найден.

Вход:

PATH - полное имя каталога С, если каталог текущий.

DISK - номер диска;

DIRS - номер первого сектора каталога или 0;

DIRSIZE- размер каталога (в элементах DIR_TYPE)}

procedure GetDiskInfo (Disk: Byte; var Disklnfo: TDisk);

{Возвращает информацию о диске DISK}

function GetDiskNumber (c: Char): Byte;

{Преобразует имя диска A...Z в номер 0...26. Если указано недействительное имя, возвращает 255}

Function GetFATItem(Disk: Byte; Item: Word): Word;

{Возвращает содержимое указанного элемента FAT}

Procedure GetIOCTLInfo (Disk: Byte; var IO: IOCTL_Type) ;

{Получить информацию об устройстве согласно общему вызову IOCTL}

Procedure GetListDisk (var List: PListDisk);

{Формирует список описателей дисков}

Procedure GetMasterBoot (var Buf );

{Возвращает в переменной Buf главный загрузочный сектор}

Function GetMaxDrv: Byte;

{Возвращает количество логических дисков}

Function GetSector (Disk: Byte;Cluster: Word): Word;

{Преобразует номер кластера в номер сектора}

Function PackCylSec (Cyl, Sec: Word): Word;

{Упаковывает цилиндр и сектор в одно слово для прерывания $13}

Procedure ReadSector (Disk: Byte; Sec: Longint; NSec: Word; var Buf);

{Читает сектор (секторы) на указанном диске}

Procedure SetAbsSector (Disk, Head: Byte; CSec: Word; var Buf);

{Записывает абсолютный дисковый сектор с помощью прерывания $13}

Procedure SetDefaultDrv (Disk: Byte);

{Устанавливает диск по умолчанию}

Procedure SetFATItem(Disk: Byte;Cluster, Item: Word);

{Устанавливает содержимое ITEM в элемент CLUSTER таблицы FAT}

Procedure SetMasterBoot (var Buf);

{Записывает в главный загрузочный сектор содержимое Buf}

Procedure UnPackCylSec (CSec: Word; var Cyl, Sec: Word);

{Декодирует цилиндр и сектор для прерывания $13}

Procedure WriteSector (Disk: Byte; Sec: Longint; NSec: Word; var Buf);

{Записывает сектор (секторы) на указанный диск}

IMPLEMENTATION

Uses DOS;

var

Reg: registers;

Procedure Output;

{Формирует значения Disk_Status и Disk_Error}

begin

with Reg do

begin

Disk_Error:= Flags and FCarry = 1;

Disk_Status:= ax;

end

nd;

Function ChangeDiskette (Disk: Byte): Boolean;

{Возвращает TRUE, если изменялось положение запора на указанном приводе гибкого диска}

begin

with Reg do

begin

AH:= $16;

DL:= Disk;

Intr($13, Reg);

Output;

ChangeDiskette:= Disk_Error and (AH=6)

end

end;

Procedure FreeListDisk (var List: PListDisk);

{Удаляет список дисковых описателей}

var

P: PListDisk;

begin

while List <> NIL do

begin

P:= List^.NextDisk;

Dispose (List) ;

List:= P

end

end;

Procedure GetAbsSector (Disk, Head: Byte; CSec: Word; var Buf ) ;

{Читает абсолютный дисковый сектор с помощью прерывания $13}

begin

with Reg do

begin

ah:=2; {Операция чтения}

dl:=Disk; {Номер привода}

dh:=Head; {Номер головки}

cx:=CSec; {Цилиндр/сектор}

al:=1; {Читать один сектор}

es:=seg(Buf);

bx:=ofs(Buf);

Intr($13,Reg);

Output

end

end;

Function GetCluster(Disk: Byte; Sector: Word): Word;

{Возвращает номер кластера по заданному номеру сектора}

var

DI: TDisk;

Begin

GetDiskInfo(Disk,DI);

if not Disk_Error then

with DI do

if (Sector-DataLock >= 0) and (TotSecs-Sector >= 0) then

GetCluster:= (Sector-DataLock) div ClusSize+2

else

GetCluster:= 0 {Неверный номер сектора}

else

GetCluster:= 0 {Неверный номер диска}

end;

Function GetDefaultDrv: Byte;

{Возвращает номер диска по умолчанию}

begin

with Reg do

begin

AH:= $19;

MSDOS(Reg);

GetDefaultDrv:= AL

end

end;

Procedure GetDirItem (FileName: String; var Item: Dir_Type) ;

{Возвращает элемент справочника для указанного файла}

var

Dir: array [1..16] of Dir_Type; {Буфер на 1 сектор каталога}

Path: DirStr; {Маршрут поиска}

NameF: NameStr; {Имя файла}

Ext: ExtStr; {Расширение файла}

Disk: Byte; {Номер диска}

Dirs: Word; {Номер сектора}

DirSize: Word; {Размер каталога}

Find: Boolean; {Флаг поиска}

j: Integer; {Номер элемента каталога}

Procedure FindItem;

{Ищет нужный элемент в секторах каталога}

var

k, i: Integer;

m: array [1..11] of Char; {Массив имени}

Clus: Word; {Номер кластера}

DI: TDisk;

begin

GetDiskInfo (Disk, DI) ; {Получаем длину кластера}

ReadSector (Disk, Dirs, 1, Dir) ; {Читаем первый сектор}

k:= 0; {Количество просмотренных элементов}

j:= 1; {Текущий элемент каталога}

{Готовим имя и расширение для поиска}

FillChar (m, 11, ' ');

Move (NameF [1] ,m[1] , Length (NameF) ) ;

if ext<>'' then

Move (Ext [2] ,m[9] , Length (ext) -1);

Find:= False;

{Цикл поиска}

repeat

if Dir[j].Name[1]=#0 then

exit; {Обнаружен конец списка}

if (Dir[j].FAttr and $18) = 0 then

begin {Проверяем очередное имя в каталоге}

Find:= True;

i:= 1;

While Find and (i<=11) do begin

Find:= m[i]=Dir[j].NameExt[i];

inc(i)

end;

end;

if not Find then inc(j);

if j = 17 then

begin

inc(k,16);

if k >= DirSize then

exit; {Дошли до конца каталога}

j:= 1; {Продолжаем с 1-го элемента следующего сектора}

if (k div 16) mod DI .ClusSize=0 then

if succ(Dirs)<DI.DataLock then

inc(Dirs) {Корневой каталог}

else

begin {Конец кластера}

{Новый кластер}

Clus:= GetFATItem (Disk, GetCluster (Disk, Dirs));

{Новый сектор};

Dirs:= GetSector(Disk, Clus)

end

else {Очередной сектор - в кластере}

inc (Dirs) ;

ReadSector (Disk, Dirs, 1, Dir)

end

until Find

end;

begin

{Готовим имя файла}

FileName:= FExpand (FileName) ;

FSplit (FileName, Path, NameF, Ext);

{Искать каталог}

GetDirSector(Path, Disk, Dirs, DirSize) ;

Find:= Dirs<>0; {Dirs=0 - ошибка в маршруте};

if Find then

FindItem; {Ищем нужный элемент}

if Find then

begin

{Переносим элемент каталога в Item}

Move (Dir [j ], Item, SizeOf (Dir_Type) );

{Сбросить ошибку}

Disk_Error:= False

end

else

begin {Файл не найден}

Disk_Error:= True;

Disk_Status:= $FFFF

end

end;

Procedure GetDirSector (Path: String; var Disk: Byte; var Dirs, DirSize: Word);

{Возвращает адрес сектора, в котором содержится начало

нужного каталога, или 0, если каталог не найден.

Вход:

PATH - полное имя каталога С', если каталог - текущий).

Выход:

DISK - номер диска;

DIRS - номер первого сектора каталога или 0;

DIRSIZE - размер каталога (в элементах DIR_TYPE) . }

var

i,j,k: Integer; {Вспомогательные переменные}

Find: Boolean; {Признак поиска}

m: array [1..11] of Char; {Массив имени каталога}

s: String; {Вспомогательная переменная}

DI: TDisk; {Информация о диске}

Dir: array [1..16] of Dir_Type; {Сектор каталога}

Clus: Word; {Текущий кластер каталога}

label

err;

begin

{Начальный этап: готовим путь к каталогу и диск}

if Path = '' then {Если каталог текущий,}

GetDir(0,Path); {дополняем маршрутом поиска}

if Path[2] <> ':' then {Если нет диска,}

Disk:= GetDefaultDrv {берем текущий}

else

begin {Иначе проверяем имя диска}

Disk:= GetDiskNumber(Path[1]);

if Disk=255 then

begin {Недействительное имя диска}

Err: {Точка выхода при неудачном поиске}

Dirs:= 0; {Нет сектора}

Disk_Error:= True; {Флаг ошибки}

Disk_Status:= $FFFF; {Статус $FFFF}

exit

end;

Delete(Path,1,2) {Удаляем имя диска из пути}

end;

{Готовим цикл поиска}

if Path[1]='\' then {Удаляем символы \}

Delete(Path,I,1); {в начале}

if Path[Length (Path)] = '\' then

Delete(Path,Length(Path),1); {и конце маршрута}

GetDiskInfo(Disk,DI); with DI do begin

Dirs:= RootLock; {Сектор с каталогом}

DirSize:= RootSize {Длина каталога}

end;

ReadSector(Disk,Dirs,1,Dir); {Читаем корневой каталог}

Clus:= GetCluster(Disk,Dirs); {Кластер начала каталога}

{Цикл поиска по каталогам}

Find:= Path=''; {Path='' - конец маршрута}

while not Find do

begin

{Получаем в S первое имя до символа \}

s:= Path;

if pos('\',Path) <> 0 then

s[0]:= chr(pos('\',Path)-1); {Удаляем выделенное имя из маршрута}

Delete(Path,1,Length(s));

if Path[1]='\' then

Delete (Path,1,1); {Удаляем разделитель \}

{Говиы массив имени}

FillChar(m,11,' ');

move(s[1] ,m,ord(s[0])) ;

{Просмотр очередного каталога}

k:= 0; {Количество просмотренных элементов каталога}

j:= 1; {Текущий элемент в Dir}

repeat {Цикл поиска в каталоге}

if Dir[j].Name[1]=#0 then {Если имя}

Goto Err; {начинается с 0 - это конец каталога}

if Dir[j].FAttr=Directory then

begin

Find:= True;

i:= 1;

while Find and (i<=11) do

begin {Проверяем имя}

Find:= m[i]=Dir[j].NameExt[i];

inc(i);

end

end;

if not Find then inc(j);

if j = 17 then

begin {Исчерпан сектор каталога}

j:= 1; {Продолжаем с 1-го элемента следующего сектора }

inc(k,16); {k - сколько элементов просмотрели}

if k >= DirSize then

goto err; {Дошли до конца каталога}

if (k div 16) mod DI.ClusSize=0 then

begin {Исчерпан кластер - ищем следующий}

{Получаем новый кластер}

Clus:= GetFATItem (Disk, Clus) ;

{Можно не проверять на конец цепочки,т.к. каталог еще не исчерпан}

{Получаем новый сектор}

Dirs:= GetSector (Disk, Clus)

end

else {Очередной сектор -}

inc(Dirs); {в текущем кластере}

ReadSector (Disk, Dirs, 1, Dir) ;

end

until Find; {Наден каталог для очередного имени в маршруте}

Clus:= Dir [ j ] .FirstC; {Кластер начала}

Dirs:= GetSector (Disk, Clus) ; {Сектор}

ReadSector (Disk, Dirs, 1, Dir) ;

Find:= Path = '' {Продолжаем поиск, если не исчерпан путь}

end

end;

Procedure ReadWriteSector(Disk: Byte;Sec: Longint; NSec: Word; var Buf; Op: Byte); forward;

Procedure GetDiskInfo(Disk: Byte; var Disklnfo: TDisk) ;

{Возвращает информацию о диске DISK}

var

Boot: TBoot;

IO: IOCTL_Type;

p: PListDisk;

label

Get;

begin

Disk_Error:= False;

if (Disk<2) or (Disks=NIL) then

goto Get; {He искать в списке, если дискета или нет списка}

{Ищем в списке описателей}

p:= Disks;

while (p^.Disklnfo.Number<>Disk) and (p^.NextDisk<>NIL) do

p:= p^.NextDisk; {Если не тот номер диска}

if p^.Disklnfo. Number=Disk then

begin {Найден нужный элемент - выход}

Disklnfo:= p^.Disklnfo;

exit

end;

{Формируем описатель диска с помощью вызова IOCTL}

Get:

IO.BuildBPB:= True;

GetIOCTLInfo(Disk, IO);

if Disk_Error then

exit;

{Формируем описатель}

with Disklnfo, IO do begin

Number:= Disk;

TypeD:= TypeDrv;

AttrD:= Attrib;

Cyls:= Cylindrs;

Media:= BPB.Media;

SectSize:= BPB.SectSiz;

TrackSiz:= Add.TrkSecs;

TotSecs:= BPB.TotSecs;

if TotSecs=0 then

begin {Диск большой емкости}

ReadWriteSector(Number,0,1,Boot,2); {Читаем загрузочный сектор}

TotSecs:= Boot.Add.LargSectors;

end;

Heads:= Add.HeadCnt;

Tracks:= (TotSecs+pred(TrackSiz)) div (TrackSiz*Heads);

ClusSize:= BPB.ClustSiz;

FATLock:= BPB.ResSecs;

FATCnt:= BPB.FatCnt;

FATSize:= BPB.FatSize;

RootLock:= FATLock+FATCnt*FATSize;

RootSize:= BPB.RootSiz;

DataLock:= RootLock+(RootSize*SizeOf(Dir_Type)) div SectSize;

MaxClus:= (TotSecs-DataLock) div ClusSize+2;

FAT16:= (MaxClus > 4086) and (TotSecs > 20790)

end

end;

Function GetDiskNumber(c: Char): Byte;

{Преобразует имя диска A...Z в номер 0...26. Если указано недействительное имя, возвращает 255}

var

DrvNumber: Byte;

begin

if UpCase(c) in ['A'..'z'] then

DrvNumber:= ord(UpCase(c))-ord('A')

else

DrvNumber:= 255;

if DrvNumber>GetMaxDrv then

DrvNumber:= 255;

GetDiskNumber:= DrvNumber

end;

function GetFATItem(Disk: Byte;Item: Word): Word; {возвращает содержимое указанного элемента FAT}

var

DI:TDisk;

k,j,n:Integer;

Fat: record

case Byte of

0: (w: array [0..255] of Word);

1: (b: array [0..512*3-1] of Byte);

end;

begin

GetDiskInfo(Disk,DI) ;

If not Disk_Error then with DI do

begin

if (Item > MaxClus) or (Item < 2) then

Item:= $FFFF {Задан ошибочный номер кластера}

else

begin

if FAT16 then

begin

k:= Item div 256;{Нужный сектор FAT}

j:= Item mod 256;{Смещение в секторе}

n:= 1 {Количество читаемых секторов}

end

else

begin

k:= Item div 1024; {Нужная тройка секторов FAT}

j:= (3*Item) shr 1-k*1536; {Смещение в секторе}

n:= 3; {Количество читаемых секторов}

end;

{Читаем 1 или З сектора FAT}

ReadSector(Disk,FATLock+k*n,n, Fat);

if not Disk_Error then begin

if FAT16 then

Item:= Fat.w[j]

else

begin

n:= Item; {Старое значение Item для проверки четности}

Item:= Fat.b[j]+Fat.b[j+1] shl 8;

if odd(n) then

Item:= Item shr 4

else

Item:= Item and $FFF;

if Item > $FF6 then

Item:= $F000+Item

end;

GetFatItem:= Item

end

end

end

end;

Procedure GetIOCTLInfo(Disk: Byte; var IO: IOCTL_Type);

{Получает информацию об устройстве согласно общему вызову IOCTL}

begin

with Reg do begin

ah:= $44; {Функция 44}

al:= $0D; {Общий вызов IOCTL}

cl:= $60; {Дать параметры устройства}

ch:= $8; {Устройство - диск}

bl:= Disk+1; {Диск 1=А,..}

bh:= 0;

ds:= seg(IO);

dx:= ofs (IO);

MSDOS(Reg);

Output

end

end;

Procedure GetListDisk(var List: PListDisk);

{Формирует список дисковых описателей}

var

Disk: Byte;

DI: TDisk;

P,PP: PListDisk;

Begin

Disk:= 2; {Начать с диска С:}

List:= NIL;

repeat

GetDiskInfo(Disk,DI);

if not Disk_Error then

begin

New(P);

if List=NIL then

List:= P

else

PP^.NextDisk:= P;

with P^ do

begin

Disklnfo:= DI;

NextDisk:= NIL;

inc(Disk);

PP:= P

end

end

until Disk_Error;

Disk_Error:= False

end;

Procedure GetMasterBoot(var Buf);

{Возвращает в переменной Buf главный загрузочный сектор}

begin

GetAbsSector($80,0,1,Buf)

end;

Function GetMaxDrv:Byte;

{Возвращает количество логических дисков}

const

Max: Byte = 0;

begin

if Max=0 then with Reg do

begin

ah:= $19;

MSDOS(Reg);

ah:= $0E;

dl:= al;

MSDOS(Reg);

Max:= al

end;

GetMaxDrv:= Max

end;

function GetSector(Disk: Byte; Cluster: Word): Word;

{Преобразует номер кластера в номер сектора}

var

DI: TDisk;

begin

GetDiskInfo(Disk,DI);

if not Disk_Error then with DI do

begin

Disk_Error:= (Cluster > MaxClus) or (Cluster < 2);

if not Disk_Error then

GetSector:= (Cluster-2)*ClusSize +DataLock

end;

if Disk_Error then

GetSector:= $FFFF

end;

Function PackCylSec(Cyl,Sec: Word): Word;

{Упаковывает цилиндр и сектор в одно слово для прерывания $13}

begin

PackCylSec:= Sec+(Cyl and $300) shr 2+(Cyl shl 8)

end;

Procedure ReadWriteSector(Disk:Byte;Sec: LongInt; NSec: Word; var Buf; Op: Byte);

{Читает или записывает сектор (секторы): Op = 0 - читать; 1 - записать (малый диск)

= 2 - читать; 3 - записать (большой диск)}

type

TBuf0 = record

StartSec: LongInt;

Sees: Word;

AdrBuf: Pointer

end;

var

Buf0: TBuf0;

S: Word;

O: Word;

begin

if Op>1 then with Buf0 do

begin

{Готовим ссылочную структуру для большого диска}

AdrBuf:= Ptr(Seg(Buf) ,Ofs(Buf) );

StartSec:= Sec;

Sees:= NSec;

S:= Seg(Buf0);

O:= Ofs (Buf0);

asm

mov CX,$FFFF

mov AL,Op

shr AX,1

mov AL, Disk

push DS

push BP

mov BX,0

mov DS,S

jc @1

int 25H

jmp @2

@1: int 26H

@2: pop DX

pop BP

pop DS

mov BX, 1

jc @3

mov BX,0

xor AX,AX

@3: mov Disk_Error,BL

mov Disk_Status,AX

end

end

else {Обращение к диску малой емкости}

asm

mov DX, Word Ptr Sec {DX:= Sec}

mov CX,NSec {CX:= NSec}

push DS {Сохраняем DS - он будет испорчен}

push BP {Сохраняем ВР}

lds BX,Buf {DS:BX - адрес буфера}

mov AL,Op {AL:= Op}

shr AX,1 {Переносим младший бит Op в CF}

mov AL,Disk {AL:= Disk}

jc @Write {Перейти, если младший бит Ор<>0}

int 25H {Читаем данные}

jmp @Go {Обойти запись}

@WRITE:

int 26H {Записываем данные}

@GO:

pop DX {Извлекаем флаги из стека}

pop BP {Восстанавливаем ВР}

pop DS {Восстанавливаем DS}

mov BX,1 {BX:= True}

jc @Exit {Перейти, если была ошибка}

mov BX,0 {ВХ: = False}

xor AX,AX {Обнуляем код ошибки}

@Exit:

mov Disk_Error,BL {Флаг ошибки взять из ВХ}

mov Disk_Status,AX {Код ошибки вять из АХ}

end

nd;

Procedure ReadSector(Disk: Byte; Sec: Longint; NSec: Word; var Buf);

{Читает сектор (секторы) на указанном диске}

var

DI: TDisk;

begin

GetDiskInfo(Disk,DI);

if DI.TotSecs > $FFFF then {Диск большой емкости?}

ReadWriteSector(Disk,Sec,Nsec,Buf,2) {-Да: операция 2}

else

ReadWriteSector (Disk,Sec,Nsec,Buf,0){-Нет: операция 0}

end;

Procedure SetAbsSector(Disk,Head: Byte; CSec: Word; var Buf);

{Записывает абсолютный дисковый сектор с помощью прерывания $13}

begin

with Reg do

begin

ah:= 3;

dl:= Disk;

dh:= Head; {Номер головки}

cx:= CSec; {Цилиндр/сектор}

al:= 1; {Читаем один сектор}

es:= seg(Buf) ;

bx:= ofs (Buf) ;

Intr($13,Reg);

Output

end

end;

Procedure SetDefaultDrv(Disk: Byte);

{Устанавливает диск по умолчанию}

begin

if Disk <= GetMaxDrv then with Reg do

begin

AH:= $E;

DL:= Disk;

MSDOS(Reg)

end

end;

Procedure SetFATItem(Disk: Byte;Cluster,Item: Word);

{Устанавливает содержимое ITEM в элемент CLUSTER таблицы FAT} var

DI: TDisk;

k, j , n: Integer;

Fat: record

case Byte of

0: (w: array [0..255] of Word);

1: (b: array [0..512*3-1] of Byte);

end;

begin

GetDiskInfo(Disk,DI); if not Disk_Error then with DI do

begin

if (Cluster <= MaxClus) and (Cluster >= 2) then

begin

if FAT16 then

begin

k:= Cluster div 256; {Нужный сектор FAT}

j:= Cluster mod 256; {Смещение в секторе}

n:= 1

end

else

begin

k:= Cluster div 1024; {Нужная тройка секторов FAT}

j:= (3*Cluster) shr 1-k*1536;

n:= 3

end;

ReadSector(Disk,FATLock+k*n,n,Fat);

if not Disk_Error then

begin

if FAT16 then

Fat.w[j]:= Item

else

begin

if odd(Cluster) then

Item:= Item shl 4 +Fat.b[j] and $F

else

Item:= Item*(Fat.b[j+1] and $F0) shl 12;

Fat.b[j]:= Lo(Item) ;

Fat.b[j+1]:= Hi(Item)

end;

if not FAT16 then

begin {Проверяем "хвост" FAT}

k:= k*n; {k - смещение сектора}

while k+n > FatSize do dec(n)

end;

inc (FATLock,k) ; {FATLock - номер сектора в FAT}

{Записываем изменение в FatCnt копий FAT}

for k:= 0 to pred(FatCnt) do

WriteSector(Disk,FATLock+k*FatSize,n,Fat)

end

end

end

end;

Procedure SetMasterBoot (var Buf);

{Записывает в главный загрузочный сектор содержимое Buf}

begin

with Reg do

begin

ah:= 3; {Операция записи}

al:= 1; {Кол-во секторов}

dl:= $80; {1-й жесткий диск}

dh:= 0; {Головка 0}

cx:= 1; {1-й сектор 0-й дорожки}

es:= seg(Buf);

bx:= ofs (Buf) ;

Intr ($13, Reg) ;

Disk_Error:= (Flags and FCarry <> 0);

if Disk_Error then

Disk_Status:= ah

else

Disk_Status:= 0

end

end;

Procedure UnpackCylSec (CSec: Word; var Cyl,Sec: Word);

{Декодирует цилиндр и сектор для прерывания $13}

begin

Cyl:= (CSec and 192) shl 2+CSec shr 8;

Sec:= CSec and 63

end;

Procedure WriteSector (Disk: Byte; Sec: Longint; NSec: Word; var Buf);

{Записывает сектор (секторы) на указанный диск}

var

DI: TDisk;

begin

GetDiskInfo (Disk, DI) ;

if DI.TotSecs > $FFFF then

ReadWriteSector (Disk, Sec, Nsec, Buf, 3)

else

ReadWriteSector (Disk, Sec, Nsec, Buf, 1) ;

end;

end.

Программа защиты detect

Uses DOS, F_disk,crt;

const

TRK = 80; {Номер нестандартной дорожки}

DSK = 0; {Номер диска}

SIZ = 1; {Код размера сектора}

SEC = 1; {Номер сектора}

HED = 0; {Номер головки}

type

TDate = array [1..4] of Word;

PDBT_Type =^DBT_Type; {Указатель на ТПД}

{Таблица параметров дискеты}

DBT_Type = record

Reserv1: array [0..2] of Byte;

SizeCode: Byte; {Код размера сектора}

LastSect: Byte; {Количество секторов на дорожке}

Reserv2: array [5..7] of Byte;

FillChar: Char; {Символ-заполнитель форматирования}

Reserv3: Word

end;

F_Buf = record

Track: Byte; {Номер дорожки}

Head: Byte; {Номер головки}

Sect: Byte; {Номер сектора}

Size: Byte {Код размера}

end;

var

Old: PDBT_Type; {Указатель на исходную ТПД}

Buf: Byte;

E: array [1..2] of Byte;

i:integer;

var

k,N: Integer; {Счетчик цикла}

R: registers; {Регистры}

DBT: PDBT_Type; {Указатель на новую ТПД}

C,D:Byte;{Буферы чтения/ записи}

Size: Word; {Длина сектора}

Info: TDisk;

Function LegalDiskett: Boolean; forward;

Function SetOnHD: Integer;

{Устанавливает стационарную копию на жесткий диск. Возвращает:

-1 - не вставлена дискета;

-2 - не мастер-дискета;

-3 - защита от записи или ошибка записи ГД;

-4 - программа не скопирована на ЖД;

-5 - ошибка доступа к ЖД;

-6 - исчерпан лимит установок;

-7 - программа уже установлена .

>=0 - количество оставшихся установок}

type

TDate = array [1..4] of Word;

var

F: file; {Файл с программой}

Date:^TDate; {Дата ПЗУ}

NameF: String; {Имя файла с программой}

W: array [1..5] of Word; {Заголовок файла}

n: Word; {Счетчик}

L: Longint; {Файловое смещение}

Inst: Byte; {Количество установок}

dat:array [0..7] of Byte;

begin

{Проверяем резидентность программы}

NameF:= FExpand(ParamStr(1));

if NameF[1] in ['A','B'] then

begin

SetOnHD:= -4;

Exit

end;

{Проверяем дискету}

if not LegalDiskett then

begin

case DSK of

2: SetOnHD:= -1;

else

SetOnHD:= -2;

end;

end;

if E[1] <= 0 then

begin {Исчерпан лимит установок}

SetOnHD:= -6;

Exit

end;

{Запоминаем дату изготовления ПЗУ}

for n:= 0 to 7 do

Dat[n]:= Mem[$F000:$FFF5+n];

Old:= ptr(MemW[0:$1E*4+2],MemW[0:$1E*4]);

New(DBT);

DBT^:= Old^; {Получаем копию ТПД в ОЗУ}

SetIntVec($1E,DBT); {Изменяем ссылку на ТПД}

with DBT^ do

begin

SizeCode:= SIZ;

LastSect:= 18;

FillChar:= '+'

end;

{Открываем файл с программой}

Assign(F,NameF);

Reset(F,1); {Читаем заголовок файла}

{Ищем в файле положение Hard}

L:= FileSize(f);

Seek(F,L) ; {Записываем в файл}

BlockWrite(F,Dat, SizeOf(Dat));

Seek(F,L) ; {Записываем в файл}

truncate(F);

E[1]:= E[1] - 1;

with R do

begin

ah:= 3;

al:= 1;

ch:= TRK;

cl:= SEC;

dh:= HED;

dl:= DSK;

es:= seg(E);

bx:= ofs (E);

Intr($13,R);

end;

{Нормальное завершение}

SetOnHD:= E[1];

SetIntVec($1E,Old);

Close(F)

end;

Function LegalHD: Boolean;

{Проверяет легальность стационарной копии}

var

Date:^TDate;

L:LongInt;

F:file;

Dat,Det:array [0..7] of Byte;

n:Byte;

begin

{Проверяем дату изготовления ПЗУ}

for n:= 0 to 7 do

Dat[n]:= Mem[$F000:$FFF5+n];

Old:= ptr(MemW[0:$1E*4+2],MemW[0:$1E*4]);

New(DBT);

DBT^:= Old^; {Получаем копию ТПД в ОЗУ}

SetIntVec($1E,DBT); {Изменяем ссылку на ТПД}

with DBT^ do

begin

SizeCode:= SIZ;

LastSect:= 18;

FillChar:= '+'

end;

Assign(F,ParamStr(0));

Reset(F,1); {Читаем заголовок файла}

L:= FileSize(f);

Seek(F,L+256) ;

BlockWrite(F,Det,1);

seek(F,L);

BlockRead(F,Det,SizeOf(Det));

seek(F,L);

truncate(F);

for n:= 0 to 7 do

LegalHD:= Dat[n]=Det[n];

close(F);

end;

Procedure Intr13(var R: registers; S: String);

{Обращается к прерыванию 13 и анализирует ошибку (CF=1 - признак ошибки).

Если ошибка обнаружена, печатает строку S и завершает работу программы}

begin

Intr($13,R);

if R. Flags and FCarry<>0 then

if R.ah <> 6 then {Игнорируем ошибку от смены типа дискеты}

begin

WriteLn (S) ;

SetIntVec($1E,Old) ; {Восстанавливаем старую ТПД}

Halt

end

end;

Function LegalDiskett: Boolean;

begin

if Disk_Error then

begin

WriteLn ('Ошибка доступа к диску');

Halt

end;

{Получаем длину сектора в байтах}

case SIZ of

0: Size:= 128;

1: Size:= 256;

2: Size:= 512;

3: Size:= 1024

else

WriteLn('Недопустимый код длины сектора')

end;

{Корректируем таблицу параметров дискеты. Поскольку исходная ТПД мохе в ПЗУ, делаем ее копию в ОЗУ и изменяем нужные элементы}

Old:= ptr(MemW[0:$1E*4+2],MemW[0:$1E*4]);

New(DBT);

DBT^:= Old^; {Получаем копию ТПД в ОЗУ}

SetIntVec($1E,DBT); {Изменяем ссылку на ТПД}

with DBT^ do

begin

SizeCode:= SIZ;

LastSect:= 18;

FillChar:= '+'

end;

D:= 0;

with R do

begin

{Сбрасываем дисковод}

ax:= 0;

dl:= DSK;

Intr13(R,'Ошибка доступа к диску');

ah:= $02; {Код операции чтения}

al:= 1;

ch:= TRK;

cl:= 1;

dh:= 0;

dl:= DSK;

es:= seg(E); {Адрес буфера D для чтения}

bx:= ofs(E);

Intr13(R,'Ошибка чтения')

end;

SetIntVec($1E,Old);

if E[1] > 0 then LegalDiskett:= true

else

begin

LegalDiskett:= false;

Exit

end;

end;

Function ParStr: String;

{Возвращает параметр вызова (заглавными буквами)}

var

S: String;

k: Byte;

begin

S:= ParamStr(2);

for k:= 1 to Length(S) do S[k]:= UpCase(S[K]); ParStr:= S

end;

var

Ind: integer;

Name:string;

BEGIN

if ParStr='/SET' then begin

Ind:= SetOnHD;

clrscr;

WriteLn('Установка на ЖД:');

case Ind of

1: Writeln('не вставлена дискета');

2: Writeln('не мастер-дискета');

3: Writeln('защита от записи или ошибка записи ГД');

4: Writeln('программа не скопирована на ЖД');

5: Writeln('ошибка доступа к ЖД');

6: Writeln('исчерпан лимит установок');

7: Writeln('программа уже установлена');

end;

if Ind >= 0 then Writeln('Осталось установок: ',Ind);

end;

Name:= ParamStr(0);

writeln(Name[1]);

if (ParamStr(1) = '')and(not (Name[1] in ['a','A'])) then

if LegalHd then

writeln('Копия легальна')

else begin

writeln('Копия не легальна');

Exit

end

END.

Программа diskette для взлома

Program Diskett;

Uses DOS, F_disk;

const

TRK = 80; {Номер нестандартной дорожки}

DSK = 0; {Номер диска}

SIZ = 1; {Код размера сектора}

type

PDBT_Type =^DBT_Type; {Указатель на ТПД}

{Таблица параметров дискеты}

DBT_Type = record

Reserv1: array [0..2] of Byte;

SizeCode: Byte; {Код размера сектора}

LastSect: Byte; {Количество секторов на дорожке}

Reserv2: array [5..7] of Byte;

FillChar: Char; {Символ-заполнитель форматирования}

Reserv3: Word

end;

{Элемент буфера форматирования}

F_Buf = record

Track: Byte; {Номер дорожки}

Head: Byte; {Номер головки}

Sect: Byte; {Номер сектора}

Size: Byte {Код размера}

end;

var

Old: PDBT_Type; {Указатель на исходную ТПД}

Procedure Intr13(var R: registers; S: String);

{Обращается к прерыванию 13 и анализирует ошибку (CF=1 - признак ошибки).

Если ошибка обнаружена, печатает строку S и завершает работу программы}

begin

Intr($13,R);

if R. Flags and FCarry<>0 then

if R.ah <> 6 then {Игнорируем ошибку от смены типа дискеты}

begin

WriteLn (S) ;

SetIntVec($1E,Old) ; {Восстанавливаем старую ТПД}

Halt

end

end;

Function AccessTime(DSK,TRK: Byte): Real;

{Измеряет время доступа к дорожке и возвращает его своим результатом (в секундах) }

var

E: array [1..9*512] of Byte;

t,k: Longint;

R: registers;

begin

t:= MemL[0:$046C] ;

while t=MemL[0:$046C] do;

for k:= 1 to 10 do with R do

begin

ah:= 2;

al:= 9;

ch:= TRK;

cl:= 1;

dh:= 0;

dl:= DSK;

es:= seg(E);

bx:= ofs(E);

Intr13(R,'Error');

end;

AccessTime:= (MemL [0:$046C]-t-1)*0.055

end;

ar

B: array [1..18] of F_Buf; {Буфер для форматирования}

k,N: Integer; {Счетчик цикла}

R: registers; {Регистры}

DBT: PDBT_Type; {Указатель на новую ТПД}

C,D:Byte;{Буферы чтения/ записи}

Size: Word; {Длина сектора}

Info: TDisk;

egin {Главная программа}

{Проверяем доступ к диску и настраиваем драйвер}

GetDiskInfo (DSK, Info) ;

if Disk_Error then

begin

WriteLn ('Ошибка доступа к диску');

Halt

end;

Получаем длину сектора в байтах}

case SIZ of

0: Size:= 128;

1: Size:= 256;

2: Size:= 512;

3: Size:= 1024

else

WriteLn('Недопустимый код длины сектора')

end;

{Корректируем таблицу параметров дискеты. Поскольку исходная ТПД мохе в ПЗУ, делаем ее копию в ОЗУ и изменяем нужные элементы}

Old:= ptr(MemW[0:$1E*4+2],MemW[0:$1E*4]);

New(DBT);

DBT^:= Old^; {Получаем копию ТПД в ОЗУ}

SetIntVec($1E,DBT); {Изменяем ссылку на ТПД}

with DBT^ do

begin

SizeCode:= SIZ;

LastSect:= 18;

FillChar:= '+'

end;

with R do

begin

{Сбрасываем дисковод}

ax:= 0;

dl:= DSK;

Intr13(R,'Ошибка доступа к диску');

{Готовим буфер форматирования с обратным фактором чередования секторов}

for k:= 1 to 18 do {Для каждого из 9 секторов:}

with B[k] do

begin

Track:= TRK; {указываем номер дорожки}

Head:= 0; {номер головки}

Sect:= 18-k; {номер сектора в обратной последовательности}

Size:= SIZ {и код размера}

end;

{Форматируем дорожку}

ah:= $05; {Код операции форматирования}

al:= 18; {Создаем 9 секторов}

ch:= TRK; {на дорожке TRK}

cl:= 1; {начиная с сектора 1}

dh:=0; {на поверхности 0}

dl:= DSK; {диска DSK}

es:= seg(B); {ES:BX - адрес буфера}

bx:= ofs (B) ;

Intr13(R,'Ошибка форматирования'); {Заполняем сектор случайными числами}

{Запрашиваем количество инсталляций на ЖД}

Write ('Кол-во установок на ЖД: ');

ReadLn(C) ;

{Записываем сектор}

ah:= $03; {Код операции записи}

al:= 1; {Записать 1 сектор}

ch:= TRK; {На дорожке TRK}

cl:= 1; {Начиная с сектора 1}

dh:= 0; {На поверхности 0}

dl:= DSK; {Диск DSK}

es:= seg(C); {Адрес буфера С для записи}

bx:= ofs(C);

Intr13(R, 'Ошибка записи');

{Читаем сектор}

ah:= $02; {Код операции чтения}

al:= 1;

ch:= TRK;

cl:= 1;

dh:= 0;

dl:= DSK;

es:= seg(D); {Адрес буфера D для чтения}

bx:= ofs(D);

Intr13(R,'Ошибка чтения')

end;

{Восстанавливаем старую ТПД}

writeln('read: ',D);

SetIntVec($1E,Old)

end.


Подобные документы

  • Требования к криптографическим системам защиты информации и их возможности. Условия, которым должна удовлетворять хеш-функция. Алгоритм цифровой подписи Эль-Гамаля (ЕGSА), ее формирование и проверка. Интерфейс программы, реализующей ЭЦП по ЕGSА.

    курсовая работа [1,6 M], добавлен 27.11.2014

  • Анализ программы "Проводник". Понятие операционной системы (ОС). Достоинства и недостатки файловых систем. Исследование методов запуска программы "Проводник", работа с файловой структурой в программе "Проводник" ОС Windows. Приемы работы с объектами.

    курсовая работа [32,7 K], добавлен 13.09.2009

  • Функции ОС по обслуживанию файловой системы. Комплекс операций над файлами и папками, дисками в Windows 98. Форматирование жесткого диска. Работа в текстовом процессоре Microsoft Word: создание текстового документа с таблицей списка учебной группы.

    контрольная работа [17,7 K], добавлен 02.12.2013

  • Получение конфигурации компьютера. Установка обновления Microsoft Windows. Просмотр файловой системы компьютера и информация о ней. Алгоритм запуска программы PowerShell с заданными скриптами из Visual C#. Стандартные утилиты управления Microsoft Windows.

    курсовая работа [703,8 K], добавлен 22.05.2013

  • Понятие и физическая структура диска, описание способности системы хранить данные. Рассмотрение особенностей файловой системы FAT16. Выявление связи между размером кластера и потерями дискового пространства. Пример создания программы файлового обмена.

    курсовая работа [146,1 K], добавлен 26.10.2015

  • Виды информационных систем и защита информации в них. Проблемы, возникающие в процессе защиты ИС различных видов. Электронная цифровая подпись и ее применение для защиты информационной системы предприятия. Анализ защищенности хозяйствующего субъекта.

    дипломная работа [949,0 K], добавлен 08.11.2016

  • Разъяснения по использованию систем цифровой подписи в связи с ведением закона "Об электронной цифровой подписи". Пример практического применения механизма электронно-цифровой подписи: программа контроля подлинности документов, хранимых в базе данных.

    контрольная работа [180,1 K], добавлен 29.11.2009

  • Способы и средства защиты информации от несанкционированного доступа. Особенности защиты информации в компьютерных сетях. Криптографическая защита и электронная цифровая подпись. Методы защиты информации от компьютерных вирусов и от хакерских атак.

    реферат [30,8 K], добавлен 23.10.2011

  • Классификация методов защиты информации по стоимости, распространенности, предотвращению взлома; классы, описание систем: программные, электронные ключи; смарт-карты, USB-токены, защищенные флэш-накопители, персональные средства криптографической защиты.

    реферат [34,7 K], добавлен 12.05.2011

  • Основные понятия об операционных системах. Виды современных операционных систем. История развития операционных систем семейства Windows. Характеристики операционных систем семейства Windows. Новые функциональные возможности операционной системы Windows 7.

    курсовая работа [60,1 K], добавлен 18.02.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.