Introduction au Reverse engineering

Présentation

 


Nofix

Qu'est ce que le Reverse engineering?

#include <stdio.h>
#include <stdlib.h>

void hello(char* str){
    printf("%s\n", str);
}

int main(char** argv, int argc){
    char* str = "Hello from the stack!";

    hello(str);

    return EXIT_SUCCESS;
}

Architectures

  • x86
  • x64-86
  • ARM
  • MIPS

Composition d'un programme

  • Processeur (registres)

  • Mémoire

 

Composition d'un programme

En x86 :

  • EAX, ECX, EDX, EBX
  • ESP, EBP
  • ESI, EDI
  • EIP (ou PC ou RIP pour Register Instruction Pointer)

Le proceseur

Registres processeur

32 bits EAX
16 bits
8 bits
AX
AH AL

Exemple de l'accumulateur (EAX)

mov eax, 4
mov al, 4

Les syntaxes

AT&T

INTEL

mov $5, %eax
mov eax, 5
movb $5, %eax
mov al, 5

Configuration

echo "set disassembly-flavor intel" >> ~/.gdbinit

echo "set pagination off" >> ~/.gdbinit

Le .gdbinit

La mémoire

Les segments

  • Beaucoup de segments
  • Repartis en plusieurs parties
$ readelf -l a.out
Correspondance section/segment :
  Sections de segment...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym 
          .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init 
          .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .jcr .dynamic .got 

La mémoire

  • Beaucoup de segments
  • Repartis en plusieurs parties
#include <stdio.h>
#include <stdlib.h>

char* strBss = "Hello from bss!"; //initialised -> .data section

int variable; //Not initialised -> .bss section

void hello(char* str){
    printf("%s\n", str);
}

int main(char** argv, int argc){
    char* str = "Hello from the stack!"; //Stack
    
    char* strFromHeap = malloc(sizeof(char) * 21); //Heap
    sprintf(strFromHeap, "Hello from the Heap!");

    hello(str);

    free(strFromHeap); //Always free() dynamically allocated var
    return 1;
}

La mémoire

La pile et le tas

Quelques instructions essentielles

mov <destination> <source>
mov eax, 4 ;met la valeur 4 dans le registre EAX

add <destination> <source>
add eax, 4 ;ajoute 4 à EAX

sub <destination> <source>

push <source>
push eax ; pousse la valeur EAX sur la pile

pop <destination>
pop eax ; retire la dernière valeur de la pile et la place dans EAX

jmp <addr>
jmp eax ; jmp à l'adresse EAX (équivalent du GOTO)

Quelques instructions essentielles

mov <destination> <source>
mov eax, 4 ;met la valeur 4 dans le registre EAX

add <destination> <source>
add eax, 4 ;ajoute 4 à EAX

sub <destination> <source>

push <source>
push eax ; pousse la valeur EAX sur la pile

pop <destination>
pop eax ; retire la dernière valeur de la pile et la place dans EAX

jmp <addr>
jmp eax ; jmp à l'adresse EAX (équivalent du GOTO)

Autres accès aux valeurs

mov eax, [esp + 4]

;met la valeur à l'adresse pointé par ESP + 4 dans EAX

Les conditions en assembleur

mov <destination> <source>
mov eax, 4 ;met la valeur 4 dans le registre EAX

add <destination> <source>
add eax, 4 ;ajoute 4 à EAX

sub <destination> <source>

push <source>
push eax ; pousse la valeur EAX sur la pile

pop <destination>
pop eax ; retire la dernière valeur de la pile et la place dans EAX

jmp <addr>
jmp eax ; jmp à l'adresse EAX (équivalent du GOTO)

Retour à l'exemple

void hello(char* str){
    printf("%s\n", str);
}
$ gcc example.c
$ peda a.out
gdb-peda$ disas hello
Dump of assembler code for function hello:

   0x0804841d <+0>:	push   ebp
   0x0804841e <+1>:	mov    ebp,esp             ;On prépare la pile
   0x08048420 <+3>:	sub    esp,0x18            ;On alloue de la place sur la pile
   0x08048423 <+6>:	mov    eax,DWORD PTR [ebp+0x8]
   0x08048426 <+9>:	push   eax                 ;On push le pointeur vers notre chaine
   0x08048429 <+12>:	call   0x80482f0 <puts@plt>;Appel à la fonction puts de libc
   0x0804842e <+17>:	leave  
   0x0804842f <+18>:	ret    

End of assembler dump.
void hello(char* str){
   printf("%s\n", str);
} 
push   ebp
mov    ebp,esp        
sub    esp,0x18            
mov    eax,DWORD PTR [ebp+0x8]
push   eax                 
call   0x80482f0 <puts@plt>
leave  
ret  

Introduction au Reverse

By Nofix

Introduction au Reverse

  • 286