Contourner le 'Sefmentation Fault'

a marqué ce sujet comme résolu.

Bonjour,

j’aimerai faire un programme qui lit la RAM à partir d’un endroit. Quelque sorte du genre :

1
2
3
4
int * pnt;
for(int i=0; i<1000; i++){
    printf("%c",*(pnt++));
}

Évidemment, j’obtiens un SegFault. Question : est-il possible d’executer ce programme de tel sorte à ce que l’OS lui permette cela ? Je suis sous Linux.

Merci d’avance !

Salut !

Je vais me permettre une question intrusive : pourquoi tu veux faire ça ? Juste par curiosité simple ? Tu espères découvrir quoi en mémoire ?

Je me permets d’un peu d’auto-publicité : https://zestedesavoir.com/articles/97/introduction-a-la-retroingenierie-de-binaires/

Cela t’offrira peut-être une piste et des perspectives intéressantes, même si ça ne répond pas à ta question de base.

Sinon, regarde du côté des appels systèmes ptrace et mmap. Je pourrais peut-être t’aiguiller si j’en sais un peu plus sur ce que tu cherches à faire.

Edit : lien

+2 -0

Merci Hugo, j’avais attrapé l’adresse privée du contenu, visiblement…

Edit : curiosité, bien. :)

Tu peux commencer par récupérer de manière intelligente une adresse mémoire qui correspond à une position dans la pilce d’exécution et, selon l’architecture cible sur laquelle ton binaire est compilé, faire un masque pour aligner les adresses mémoire jusqu’à tomber sur ton en-tête ELF.

Pour éviter de te faire jeter par un segfault, tu pourrais écrire un handler de signal qui fait que ton programme ignore les accès invalides en lecture et continue de scanner la mémoire. Mmmh… Je vais essayer de te faire un PoC. Ça n’aura pas d’intérêt mais ça sera un début de piste.

+1 -0

C’est encore moi !

J’ai fait un PoC inutile qui scanne sa propre mémoire jusqu’à trouver le mot magique qui indique qu’on a un ELF. Tu peux me dire ce que tu obtiens sur ta machine ?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <linux/elf.h>

void sigsegv_handler(int signal);
uint64_t* pointer = NULL; // Our pointer to browse memory

int main(int argc, const char* argv[])
{
    signal(SIGSEGV, sigsegv_handler);

    pointer = (uint64_t*)main; // Why not? :P
    printf("[*] main is at %p\n", main);

    // Align the address
    pointer = (uint64_t*)((uint64_t)(pointer) & 0xfffffffffffffff0);
    printf("[*] Align address is %p\n", pointer);

    while(pointer != NULL && memcmp(pointer, ELFMAG, sizeof(uint32_t)))
    {
        pointer--;
    }

    printf("[!] Elf header is at %p\n", pointer);

    return EXIT_SUCCESS;
}


void sigsegv_handler(int signal) {
    printf("Invalid read at %p. Skipping.\n", pointer);
}

Chez moi :

1
2
3
4
ge0@ventari /tmp » gcc -o autoscan autoscan.c
ge0@ventari /tmp » ./autoscan 
[*] main is at 0x5555555546da
[!] Elf header is at 0x555555554000

Si tu affiches la mémoire à 0x555555554000, tu y trouveras la valeur de ELFMAG telle que définie ici : https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h#L342 :)

J’ai lancé le PoC en désactivant l’ASLR sur mon système, mais en l’activant ça ne change rien, c’est juste les bits de poids fort des adresses qui changent aléatoirement à chaque exécution pour des raisons de sécurité.

À voir ce que tu veux vraiment faire…

+2 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte