9.Листинг программы «Diskett.exe».
program diskett;
uses dos,f_disk,crt;
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);
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;
{----------------------------------------------}
var
b:array [1..36] of f_buf;
k,n:integer;
r:registers;
dbt:pdbt_type;
c,d:array [1..256] of byte;
size:word;
info:tdisk;
begin
clrscr;
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:=36;
fillchar:='+';
end;
with r do
begin
ax:=0;
dl:=dsk;
intr13(r,'Ошибка доступа к диску');
for k:=1 to 36 do
with b[k] do
begin
track:=trk;
head:=0;
sect:=37-k;
size:=siz;
end;
ah:=$05;
al:=36;
ch:=trk;
cl:=1;
dh:=0;
dl:=dsk;
es:=seg(b);
bx:=ofs(b);
intr13(r,'Ошибка форматирования');
randomize;
for k:=0 to 255 do
c[k]:=random(256);
c[100]:=11;
ah:=$03;
al:=1;
ch:=trk;
cl:=1;
dh:=0;
dl:=dsk;
es:=seg(c);
bx:=ofs(c);
intr13(r,'Ошибка записи');
ah:=$02;
al:=1;
ch:=trk;
cl:=1;
dh:=0;
dl:=dsk;
es:=seg(d);
bx:=ofs(d);
intr13(r,'Ошибка чтения');
end;
for k:=1 to size do
if c[k]<>d[k] then
begin
writeln('Несовпадение данных');
setintvec($1E,old);
end;
writeln('Создана и проверена',TRK+1,’-я доржка с секторами по ’,SIZE,’байт');
end.
10.Листинг программы «Main.exe.»
program Main;
uses F_PR,crt;
procedure alarm;far;
begin
writeln('Нелегальная копия');
end;
{-------------------------------------------}
procedure norma;far;
begin
writeln('Легальная копия');
end;
{-------------------------------------------}
function parstr:string;
var
s:string;
k:byte;
begin
s:=paramstr(1);
for k:=1 to length(s) do
s[k]:=upcase(s[k]);
parstr:=s;
end;
{-------------------------------------------}
var
p1,p2:pointer;
d:integer;
dsk:byte;
begin
p1:=@norma;
p2:=@alarm;
begin
protcheck(p1,p2,d);
end;
end.
В данной программе происходит обращение к модулю F_PR , текст которого:
{*************************}unit f_pr;{*****************************}
INTERFACE
PROCEDURE protcheck(var p1,p2; var res: integer);
IMPLEMENTATION
USES DOS,F_Disk,crt,pd;
type
tbuf=array [1..256] of byte;
const
dsk=0;
pdbt_type = ^dbt_type;
dbt_type = record
sizecode:byte;
lastsect:byte;
fillchar:char;
var
info:Tdisk;
p:pointer;
buf:tbuf;
r:registers;
old,dbt:pdbt_type;
procedure intr13(var r:registers; s:string);
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 prov:boolean;
var
k,n:integer;
r:registers;
dbt:pdbt_type;
c,d:array [1..256] of byte;
size:word;
info:tdisk;
begin
clrscr;
getdiskinfo(dsk,info);
if disk_error then
begin
writeln('Ошибка доступа к диску ');
halt;
end;
old:=ptr(memw[0:$1E*4+2],memw[0:$1E*4]);
new(dbt);
dbt^:=old^;
setintvec($1e,dbt);
with dbt^ do
begin
sizecode:=1;
lastsect:=36;
fillchar:='+';
end;
with r do
begin
ax:=0;
dl:=dsk;
intr13(r,'Ошибка доступа к диску');
ah:=$02;
al:=1;
ch:=trk;
cl:=1;
dh:=dsk;
dl:=0;
es:=seg(d);
bx:=ofs(d);
intr13(r,'Ошибка чтения');
end;
setintvec($1E,old);
if d[100]=11 then prov:=true else prov:=false;
end;
{---------------------------------------------------}
procedure protcheck(var p1,p2; var res:integer);
type
ptype = procedure;
var
norma:ptype absolute p1;
alarm:ptype absolute p2;
dsk:byte;
label
l1,l2;
BEGIN
res:=1;
if prov then
begin
l1:
norma;
res:=0;
end
else
begin
l2:
alarm;
res:=1
end
END;
{---------------------------------------------------}
END.
Основной процедурой модуля является процедура Protcheck- осуществляющая контроль копии. В теле процедуры параметры-переменные Norma и Alarm трактуются, как параметры процедурного типа т.е. являются адресами двух процедур без параметров. Процедура Alarm вызывается в случае, если программа обнаружила признаки нелегального копирования, а Norma- если эти признаки отсутствуют. Функция Prov- имеет тип Boolean. Она читает 81-ю доржку, возвращает True – если на ней установлена метка, и False-если метки нет.
11.Принцип работы программы.
Программы при форматировании 81-ой дорожки, при записи и проверки метки используют один и тот же принцип. Объявляется структура, описывающая параметры записи/форматирования. Объявляются стандартные структуры, описывающие регистры микропроцессора (uses Dos, R:registers). Затем эти структуры заполняются: параметрами записи/форматирования и значениями, описывающими необходимое состояние микропроцессора. Далее происходит вызов соответствующего прерывания (запись/форматирование), номер которого содержат только что заполненные регистры (функция intr(13,5;13,3;13,5:R). Происходит вызов специальной функции, которая обрабатывает вызванное прерывание, и таким образом решается требуемая задача.
См. Приложение «Программа Diskett.exe» и «Программа Main.exe».
Заключение.
Итак, в результате проделанной работы было освещено множество различных методов защиты дискеты от копирования, выяснены их достоинства и недостатки, в результате были выбраны и программно реализованы методы сигнатуры внутренней дорожки (81-ая дорожка), с нестандартным размером и фактором чередования секторов. Программы «Diskett.exe» и «Main.exe» реализуют эти методы. Первая программа нестандартно форматирует 81-ую дорожку и ставит метку в виде случайного числа. Вторая программа проверяет эту метку, если метка метка верна, то разрешается корректно скопировать файл с гибкого диска, если нет- мы имеем дело с нелегальной копией.