IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Calculer son propre checksum


Sujet :

C

  1. #1
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut Calculer son propre checksum
    Bonjour,

    J'aimerais que mon programme calcul son propre checksum (section .text et .rodata).
    J'ai fait un petit code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <inttypes.h>
    #include <stdio.h>
     
    static uint32_t checksum32(const void * start,const void * stop)
    {
        uint32_t sum = 0;
        const uint32_t n_iter = ((uint32_t)stop - (uint32_t)start)/sizeof(uint32_t);
        const uint32_t * pc = (const uint32_t *)start;  /* emulate Program Counter as 32bit integer pointer*/
     
        for(uint32_t i = 0 ; i < n_iter ; i++)
        {   /* compute the sum of the program*/
            sum += pc[i];
        }
        return sum;
    }
     
    int main()
    {
     
        printf("CHECKSUM:0x%"PRIx32,checksum32(??????,??????));
        return 0;
    }
    J'aimerais savoir ce qu'il faut je mette comme paramètre à ma fonction checksum32 pour faire comprendre au compilo (GCC) que je veux calculer le checksum du programme qu'il est en train de compiler...

    Mercid de votre aide.

  2. #2
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Sans trop me mouiller, je pense pouvoir avancer que tu ne peux pas faire ça. EDIT : Hé ben si

    Il faut que tu considères l'exécutable comme un fichier et que tu l'ouvres en mode binaire. Mais il faut donc que tu connaisses son nom, ce qui ne devrait pas spécialement poser de problème

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2009
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2009
    Messages : 172
    Points : 191
    Points
    191
    Par défaut
    En fait ça risque d'être beaucoup plus compliqué que ce que tu as fait jusqu'à maintenant. Comme l'a dit Trademark, le plus simple serait d'ouvrir l'exécutable car si tu veux utiliser les segments de mémoire pour calculer ton checksum il faudra d'abord trouver où le loader a charger chaque segment/sections de ton exécutable. Et je ne sais pas si c'est possible! (pour éviter les attaques comme la return-to-libc. Regardes ce lien si tu veux en savoir plus : http://en.wikipedia.org/wiki/Address..._randomization)

    Deuxièmement, il te faudra extraire les segments de ton exécutable qui t'intéressent. Donc vu ta fonction checksum il faudra faire un mmap de l'exécutable, lire les headers (qui dépendent du format de l'exécutable) et obtenir la taille et l'offset des sections .text et .data, puis passer les addresses à ta fonction checksum.

    Mais Si ça peut te simplifier la vie, certains formats d'exécutable intègrent déjà une signature numérique de leur contenu (dont ELF et PE. Je suppose que ton programme rentre dans l'une de ces 2 catégorie)

    Cordialement

  4. #4
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut
    Salut,

    Mais Si ça peut te simplifier la vie, certains formats d'exécutable intègrent déjà une signature numérique de leur contenu (dont ELF et PE. Je suppose que ton programme rentre dans l'une de ces 2 catégorie)
    Effectivement mon exécutable se présente sous la forme d'un fichier .elf. As-tu plus d'information sur la signature numérique de ce format?

    Merci.

  5. #5
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Peut-être un début de piste par là.

    Ton compilo (le linker) place ton code grace à un "script" : un ld script, du nom du linker ld si tu utilises la chaine gnu.

    Tu peux par exemple taper :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -Wall -Wl,-verbose -o test test.c
    et tu verras le code du script qui est utilisé.

    Ce script défini des symboles qui contiennent des adresses (par exemple, on peut utiliser __end pour gérer le tas).

    Par exemple, le code suivant te permet d'afficher une adresse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    extern void * __executable_start;
     
    int main(int argc, char **argv)
    {
      fprintf(stdout, "%p\n", __executable_start);
      return 0;
    }
    Maintenant il faut voir si on peut trouver là dedans le début et la fin de la plage mémoire qui t'intéresse.
    Le cas échéant voir comment modifier le script pour les définir.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut
    Effectivement dans mon environnement gcc utilise un script de "linckage" qui s'appelle linker.x. Celui-ci défini 4 variable inintéressantes :
    _start,_end,__ram_rodata_start,__ram_rodata_end


    j'ai donc fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    extern const void _start;
    extern const void _end;
    extern const void __ram_rodata_start;
    extern const void __ram_rodata_end;
     
    static uint32_t checksum32(const void * start,const void * stop)
    {
        uint32_t sum = 0;
        const uint32_t n_iter = ((uint32_t)stop - (uint32_t)start)/sizeof(uint32_t);
        const uint32_t * pc = (const uint32_t *)start;  /* emulate Program Counter as 32bit integer pointer*/
     
        for(uint32_t i = 0 ; i < n_iter ; i++)
        {   /* compute the sum of the program*/
            sum += pc[i];
        }
        return sum;
    }
     
     
     
    int main()
    {
     
        printf("CHECKSUM:0x%"PRIx32,checksum32(&_start,&_end) + checksum32(&__ram_rodata_start,&__ram_rodata_end));
        return 0;
    }
    }
    Ca marche !!!

    Merci pour votre aide

  7. #7
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Attention, il me semble que start et end définissent les limites du tas... je trouve bizarre que vous vouliez calculer son checksum.

    Vous êtes vous documenté sur ces variables pour être sûr de ce qu'elles définissent comme limites. Quel doc avez vous utilisé ? Votre environnement est-il un quelconque système embarqué sur lequel le script de link a été fait spécialement pour ce système ?

  8. #8
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut
    Exacte _end indique la fin du tas. Dans mon system les sections .text et .rodata son consecutives donc il me suffit de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("CHECKSUM:0x%"PRIx32"\n",checksum32(&_start,&__ram_rodata_end));
    Et j'ai vérifié l'adressage des sections en faisant un objdump du .elf

    Merci

  9. #9
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2009
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2009
    Messages : 172
    Points : 191
    Points
    191
    Par défaut
    Ouaouh ravi que tu aies pu trouver une réponse beaucoup plus simple que celle que j'allais te donner qui nécessitait de triffouiller dans les headers!

    Je tenais quand même à rectifier l'ânerie que j'ai sortie concernant la signature numérique de certains format exécutable. En fait ils requierent des extensions ou programme tiers spécialisés genre elfsign. Autant pour moi

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 15
    Dernier message: 04/01/2007, 11h15
  2. Créer son propre LayoutManager
    Par tomburn dans le forum Agents de placement/Fenêtres
    Réponses: 9
    Dernier message: 17/03/2005, 16h15
  3. créer son propre protocole
    Par matthew_a_peri dans le forum Développement
    Réponses: 11
    Dernier message: 04/03/2005, 14h16
  4. Création de son propre message dans un formulaire
    Par androme dans le forum C++Builder
    Réponses: 17
    Dernier message: 06/02/2005, 23h13
  5. [C#] Ajouter son propre composant dans Design de VS.Net
    Par yannick_sch dans le forum Windows Forms
    Réponses: 2
    Dernier message: 26/08/2004, 11h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo