Электронно-цифровая подпись
Разработка программы реализующей алгоритм ЭЦП методом 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