русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Защита, опирающаяся на жесткий диск

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

Методы получения некопируемых меток на жестких магнитных дисках (ЖМД) Особенностями жесткого магнитного диска являются:

  • недоступность рабочих поверхностей ЖМД, в силу чего исключено нанесение физической метки;
  • большой объем информационного поля — поэтому затруднено копирование «диск в диск».

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

  • сохранность метки при операциях реорганизации диска, например, с использованием средства SpeedDisk;
  • невидимость метки или .ее неповторимость на другом диске;
  • сохранность метки при уничтожении защищенной от копирования информации (программ) на ЖМД в целях создания архивных копий.

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

Не рекомендуется «привязывать» программы и данные к их местоположению на винчестере, поскольку реорганизация диска либо будет неэффективна (если информация помечена как неперемещаемая), либо защищенные программы будут восприниматься как нелегальные копии, так как их местоположение на диске изменится.

Неиспользуемые области диска

На уровне BIOSа есть две неиспользуемые области почти на любом жестком диске: в самом начале диска и в самом конце. Первый сектор каждого жесткого диска (по меньшей мере, исключая SCSI или ESDI) используется под таблицу разделов, тогда как другие сектора нулевого цилиндра на дорожке 0 не используются по схеме расположения разделов фирм IBM и Microsoft. Однако эта область может быть использована программами, осуществляющими собственное разбиение на разделы. К примеру, DiskManager (dmdrvr.bin) использует сектор 0/0/8 для расширенной таблицы разделов, Olivetty MS-DOS начинает первый раздел DOS с сектора 0/0/2, и т.д.

Вторая неиспользуемая область состоит из пользовательского диагностического цилиндра, который является следующим после последнего цилиндра диска на AT и последним на машинах типа находится PS/2. (Но они все же совместимы, не так ли?) Все записанное здесь имеет очень небольшие шансы на долгое существование, поскольку любая низко-уровневая тестовая программа имеет право распоряжаться этой дорожкой, как ей нужно. (Norton DiskTreet и Gibbson Research's SpinRite определяют оптимальное значение параметра чередования здесь).

Использование операций длинного чтения/записи

Следующим способом простановки некопируемых меток является применение операций длинного чтения и длинной записи.
Эти операции выполняются только на жестком диске и работают с расширенной до 516 байтов (512 + 4) длиной сектора. Следовательно, если произвести операцию длинной записи, а затем операцию обычного чтения, то дополнительные 4 байта информации не будут обнаружены.

Считать записанную информацию полностью можно только операцией длинного чтения. Кроме того, обычная запись сектора не разрушает дополнительной информации в 4 байтах, поэтому метка может быть скрыта под обычной информацией.
Однако, использовать один или несколько секторов для хранения метки недостаточно, поскольку информация в дополнительных байтах может быть легко обнаружена путем поиска по всему винчестеру.

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

; Компиляция в СОМ-файл.
Org 100h
Start :
Push cs              ; DS = CS
pop ds
; ah = 2 – функция обычного чтения
mov ah , 2
; al – сколько секторов считать
mov al , 1
; смещение буфера с информацией
mov bx , offset bf
; ch – дорожка, cl – сектор
mov cx , 0003h
; сегмент буфера
mov dx , ds
mov es , dx
; dh – головка, dl – идентификатор дисковода для жёсткого диска
; dl = 80h, если их два, то 80h и 81h соответственно
mov dx , 0080h
int 13h
; ah = 0Bh – функция длинной записи
mov ah , 0Bh
mov al , 1
; смещение буфера с информацией
mov bx , offset bf
; ch – ..., cl – сектор
mov  cx , 0003h
; сегмент буфера
mov dx , ds
mov es , dx
; dh - головка, dl – идентификатор дисковода
mov dx , 0080h
int 13h
; обнулим дополнение в 4 байта
mov  word ptr dop , 0
mov word ptr dop + 2 , 0
; ah = 0Ah – функция длинного чтения
; контрольное чтение
mov ah , 0Ah
mov al , 1
; смещение буфера с информацией
mov bx , offset bf
; ch – дорожка, cl – сектор
mov cx , 0003h
; сегмент буфера
mov dx , ds
mov es , dx
; dh – головка, dl – идентификатор дисковода
mov dx , 0080h
int 13h
; вывод на экран дополнительных байт
mov ah , 09h
mov dx , offset dop
int 21h
mov ax , 4C00h
int 21h
; буфер – 512 + 4 + символ окончания печати
bf   db 512 dup (0)
dop  db ‘ABCD’
db ‘S’
end start

Неиспользуемые (вследствие округления кластера) области диска

Поскольку DOS распределяет дисковое пространство покластерно (каждый кластер содержит 2^N секторов), а размер файла измеряется в байтах, большинство файлов имеет неиспользуемый (и обычно невидимый на уровне файловой системы) хвост, который может быть использован для целей защиты. Странная накладка в DOS, которая позволяет просмотреть (функция DOS 42h) данные за концом файла, делает доступ к этому хвосту файла достаточно простым для высокоуровневых языков.

//Доступ к данным за концом файла
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#define GRANULARITY     (512)
#define ID_LENGTH       30
int main( int argc, char *argv[] )
{       int     handle ;
long    length ;
char    buf[ ID_LENGTH + 1 ] ;
int     size ;
if( ( handle = open( argv[ 0 ], O_RDWR | O_BINARY ) ) == -1 ){
perror( argv[ 0 ] ) ;
return -1 ;
}
length = filelength( handle ) ;
if( GRANULARITY - length % GRANULARITY < ID_LENGTH ){
printf( "File %s has no sufficient tail !\n", argv[ 0 ] ) ;
close( handle ) ;
return -1 ;
}
if( argc == 2 ){        /* Write to tail */
lseek( handle, 0, SEEK_END ) ;
size = min( strlen( argv[ 1 ] ) + 1, ID_LENGTH ) ;
if( write( handle, argv[ 1 ], size ) != size ){
perror( argv[ 0 ] ) ;
close( handle ) ;
return -1 ;
}
}
else {
lseek( handle, ID_LENGTH, SEEK_END ) ;
write( handle, " ", 1 ) ;
lseek( handle, length, SEEK_SET ) ;
read( handle, buf, ID_LENGTH ) ;
printf( "File tail is \"%s\"\n", buf ) ;
}
chsize( handle, length ) ;
close( handle ) ;
return 0 ;
}

Привязка к местоположению BAD-кластеров (пометка ложных BAD-кластеров)

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

PROGRAM  SearchBadKlaster;
Uses Dos;
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,           {Номер дорожки}
Head,            {Номер головки}
Sect,             {Номер сектора}
Size: byte;     {Код размера сектора}
     end;
TrackType = array [0..1024] of byte;
Const
Dsk = 0;   {Номер диска}
Var
Info: Tdisk;      {Информация о диске}
Old,              {Указатель на исходную таблицу параметров диска}
Dbt: PDBT_Type;   { Указатель на новую таблицу параметров диска }
Trk,                 {Количество дорожек}
Ns: word;         {Количество секторов на дорожке}
i,                      {Счетчик поверхностей}
j,                      {Счетчик секторов}
k,                     {Счетчик дорожек}
nn:integer;        {Номер сектора в цилиндре}
P: ^TrackType;  {Буфер чтения/записи}
R: registers;       {Регистры центрального процессора}
Bf: array [0..20] of F_Buf;   {Буфер для форматирования}
Begin
{Определяем количество дорожек, головок и секторов на дорожке}
GetDiskInfo(Dsk, Info);
If Disk_Error Then
begin
WriteLn(‘Ошибка доступа к диску.’);
Halt
end;
Trk:= Info.Tracks;
Ns:= Info.TrackSize;
{Резервируем память для буфера}
GetMem(P,2*Ns*512);
{Готовим нужную таблицу параметров диска}
Old:= Ptr(MemW[0:$1E*4+2], MemW[0:$1E*4] );
New(Dbt);
Dbt^:= Old^;   {Получаем копию таблицы параметров диска в ОЗУ}
SetIntVec($1E,Dbt);   {Изменяем ссылку на таблицу параметров диска }
Dbt^.LastSect:= Ns;   {Устанавливаем нужное количество секторов на дорожке}
{Цикл проверки дорожек}
    For k:=0 to Trk-1 do
With R do
begin
Ah:= 2;    {Код операции чтения}
Al:= 2*Ns;    {Количество секторов чтения}
Ch:= k;     {Номер дорожки}
Cl:= 1;      {Начать с первого сектора}
Dh:= 0;     {Начать с нулевой поверхности}
Dl:= Dsk;  {Номер диска}
Es:= seg(P^);
Bx:= ofs(P^);
Intr($13,R);     {Читаем всю дорожку}
If (Flags and Fgarry) <> 0 Then
begin       {Обнаружена сбойная дорожка}
{Читаем дорожку по секторам}  
For i:=0 to 1 do         {2 поверхности}
For j:=1 to Ns do
begin
Ah:= 2;    {Код операции чтения}
Al:= 1;     {Читаем один сектор}
Ch:= k;     {Номер дорожки}
Cl:= j;      {Номер сектора}
Dh:= i;     {Номер головки}
Dl:= Dsk;  {Номер диска}
Nn:= i*Ns+pred(j);
Es:= seg(P^[nn*512] );
Bx:= ofs(P^[nn*512] );
Intr($13,R);     {Читаем сектор}
end;
{Форматируем дорожку}
For i:=0 to 1 do
                            begin   {Цикл по головкам}
For j:=1 to Ns do
With Bf[j] do
begin    {Готовим буфер}
Track: = k;
Sect: = j;
Head: = i;
Size: = Old^.SizeCode
end;
Ah:= 5;    {Код операции форматирования}
Al:= 2*Ns;    {Количество секторов чтения}
Ch:= k;     {Номер дорожки}
Cl:= 1;      {Начать с первого сектора}
Dh:= i;     {Номер головки}
Dl:= Dsk;  {Номер диска}
Es:= seg(Bf);
Bx:= ofs(Bf);
Intr($13,R);     {Читаем поверхность}
                            end;
{Восстанавливаем содержимое дорожки и заново проверяем секторы}
For i:=0 to 1 do    {2 поверхности}
For j:= 1 to Ns do
begin
{Восстанавливаем содержимое сектора}
Ah:= 3;    {Код операции записи}
Al:= 1;    {Записываем первый сектор}
Ch:= k;     {Номер дорожки}
Cl:= 1;      {Номер сектора}
Dh:= 0;     {Номер головки}
Dl:= Dsk;  {Номер диска}
Nn:= i*Ns+pred(j);
Es:= seg(P^[nn*512] );
Bx:= ofs(P^[nn*512] );
Intr($13,R);    
{Читаем сектор}
Ah:= 2;    {Код операции чтения}
Al:= 1;     {читаем первый сектор}
Ch:= k;    {Номер дорожки}
Cl:= 1;     {Номер сектора}
Dh:= 0;    {Номер головки}
Dl:= Dsk;  {Номер диска}
Es:= seg(P^[nn*512] );
Bx:= ofs(P^[nn*512] );
Intr($13,R);    
If (Flags and Fcarry) <>0 Then
WriteLn(‘Дефектный сектор‘,(k*2+i)*Ns+j)
end
end
end;
SetIntVec($1E,Old) {Восстанавливаем прежнюю таблицу параметров диска}   
End.

Необходимо заметить, что простановка ложных BAD-кластеров может быть замечена пользователем защиты, особенно, если до начала эксплуатации защищенной программы у него их не было.

Поэтому, проставлять ложный BAD-кластер необходимо либо в первое от начала FAT свободное место (вероятность, что при переносе на другую ПЭВМ этот кластер будет занят, велика, а редактировать цепочки FAT рискнет не всякий), либо в самый конец FAT, так чтобы его не показывали средства типа SpeedDisk.

Просмотров: 16729


Вернуться воглавление




Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.