Packer sans ta mère level II prerequis II le PEB

Il y a 5 mois que je vous ai laissé tomber au milieu de cette série de post. Je me rend compte qu’il faut y avancer un peu car sinon tenter d’expliquer le dernier packer au plus grand nombre sans perdre quelques personne ne sera pas aisé.

On avait précédemment regardé comment était emmanché un exécutable dans la mémoire d’un Windows et survolé le concept d’EAT et IAT. Aujourd’hui on va voir une structure rigolote et indispensable le PEB.

Le PEB alias Process Environnement Bloc est une structure dite opaque (en clair peu documenté officiellement, voir documentée sur le tard, où normalement un programme normal est pas supposé s’y pointer).

C’est un pan de mémoire maintenu par windows pour chacun des process et qui va donner des informations vaste et variées. On peut par exemple trouver l’offset qui nous dira où est mappé en mémoire notre exécutable. On peut aussi savoir si le processe est débuggé ou pas. etc…

L’offset de la PEB  est toujours disponible en regardant dans FS[0x30]  en 32 bits ou GS[0x60] en 64 bits. A chaque instant il suffit de lire ce dword/qword et on connait l’adresse du PEB. Généralement en 32bits vers 7FFDxxxx tachez d’arriver à repérer un offset de cette trempe.

Microsoft documente un peu le PEB dans son MSDN mais c’est assez minable. Heureusement en 32 bits Ollydbg connait cette structure à fond. Elle est directement visible dans Olly depuis la fenêtre de memory map (Alt+M).

Screen Shot 2014-05-24 at 0.16.11

Et il sait aussi décoder cette structure ce qui est TRÈS pratique.

Screen Shot 2014-05-24 at 0.19.31

Donc que peut t’on faire concrètement avec cet structure ? Premièrement de l’anti-debug avec l’info qui traine dans ce PEB. Il y a deux grand classique;

mov ebx,fs[0x30] ; PEB offset dans EBX
cmp byte ptr [ebx+2], 0 ; Beingdebugged = False ? 
jne .processisdebugged  ; Sinon débuggé !!!

C’est pareil que d’appeler la fonction de kernel32 IsDebuggerPresent, sauf que là, pas besoin de la déclarer une fonction et pas besoin non plus d’appeler une fonction ! tout n’est qu’access mémoire.

Le second anti-débug possible est plus étrange;

mov ebx,fs[0x30] ; PEB offset dans EBX
cmp byte ptr [ebx+0x68], 0x70 ; les Debug Flags sont là ? 
je .processisdebugged  ; Sinon débuggé !!!

Celui la se base sur le fait qu’un process débuggé à normalement 3 flags de mis dans le PEB

  • 0x10 pour HEAP_ENABLE_TAIL_CHECK
  • 0x20 pour HEAP_ENABLE_FREE_CHECK
  • 0x40 pour HEAP_VALIDATE_PARAMETERS

Pour être au top sur ces anti debug, je vous invite a lire le chapitre 2.1 et 2.2 de “The Art of Unpacking” de Mark Vincent Yason;

Bien sur généralement l’accès à fs[0x30] est caché de toutes les façons du monde, petit exemple :

push ss
mov eax, 6  
push fs
shl eax, 3   ; EAX = 6*8 = 0x30
pop ss
mov ebx,ss[eax] ; ebx = PEB
pop ss

On peut trouver aussi l’offset du PEB par une autre méthode, il est laissé par windows dans le registre EBX à l’entry point d’un programme x32.

Mais le PEB ne sert pas qu’a tester de debugging;

Il contient des infos sur le nombre de CPU (si c’est 1.. en 2014, c’est probablement une VM !). Il peut servir pour déterminer la version de windows(+0xA4 et +0xA8), il contient l’adresse de base de l’exécutable (+0x8) et enfin l’adresse d’une structure nommée LoaderData ou PPEB_LDR_DATA (en +0xC)

Cette dernière structure va nous permettre de retrouver l’offset où est mappé en mémoire les DLL nécessaire à notre exécutable. (A minima kernel32 et ntdll).

Vous l’aurez compris grâce à cela, on va pouvoir parser l’EAT de ces DLL et retrouver les offset des fonctions en mémoire afin de pourvoir les appeller sans avoir à les déclarer dans l’IAT de notre programme, bref un GetProcAddresseA mais totalement discret.

On verra cela la prochaine fois. mais retenez, si vous voyez passer un FS[0x30] ou un GS[0x60] Inquiétez vous !

This entry was posted in Reverse, Windows and tagged , , . Bookmark the permalink.

2 Responses to Packer sans ta mère level II prerequis II le PEB

  1. Phil says:

    Bonsoir, merci pour ces articles. Une question sur l’embrouillage de fs[0x30] : vu qu’il y a shr eax, 3 je ne comprends pas comment on arrive à 6*8… (lien référence de mon côté : https://www.aldeid.com/wiki/X86-assembly/Instructions/shr ). Merci !

    • thanatos says:

      Oup’s coquille, Well done, un qui suis… L pas R.. !!

      On met 6 dans EAX, et on décale avec SHL de 3 bit tout vers la gauche..
      EAX = 6 donc. Je fait que “al” en binaire hein… tu m’excusera… 00000110
      SHL 1, x2 = 00001100
      SHL 2, x4 = 00011000
      SHL 3, x8 = 00110000

      Et paf… 00110000 ca fait 48 donc 0x30 en hexa… il a corrigé, grand merci.

Leave a Reply

Your email address will not be published. Required fields are marked *

AlphaOmega Captcha Classica  –  Enter Security Code