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 :

Rechercher une chaine hexadécimale dans un fichier


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Hobbiste
    Inscrit en
    Juin 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Hobbiste
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2020
    Messages : 4
    Points : 9
    Points
    9
    Par défaut Rechercher une chaine hexadécimale dans un fichier
    Bonjour à tous,

    Je suis débutant en C#. Je me casse la tête sur un problème qui semble pourtant assez simple, et j'aimerai avoir
    votre aide. Voici mon problème.

    Je dois chercher dans un fichier de petite taille une chaine de caractère hexadécimale (que je spécifie en dur). Je procède comme
    suit:

    1) J'ouvre le fichier (pas de problème)
    2) J'alloue la mémoire et copie le fichier dans un buffer (pas de problème)
    3) Je spécifie ma chaine hexadécimale par exemple "0x484e4f505152"

    Ma question est comment faire pour rechercher dans le buffer créé cette chaine hexa ? J'ai essayé de faire comme cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int index = 0;
    while (index < buffer_size) {
        if ((buffer[index + 0] == 0x48)
               && (buffer[index + 1] == 0x4e)
               && (buffer[index + 2] == 0x4f)
               && (buffer[index + 3] == 0x50))
        {
            printf("Valeur se trouve a: %d\n", index);
        }
        index++;
    }

    Cela ne fonctionne pas. Bref, de base quelle méthode me conseillez vous pour rechercher une valeur hexa dans un buffer ?
    Je pense que le buffer peut-être traité comme un tableau après memcpy mais peut-être faut-il recopier le buffer dans un
    tableau avant ? (procédure que je ne vois pas comment réaliser).


    Merci pour vos conseils et désolé si ces questions sont naïves.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par HeinCode Voir le message
    Bonjour à tous,
    Bonjour à toi

    Citation Envoyé par HeinCode Voir le message
    Je suis débutant en C#.
    C'est super. Ben ici c'est du C. Donc déjà soit tu te trompes de forum, soit tu ne connais pas le langage que tu utilises. Dans tous les cas ça part mal et moi ça me met de mauvaise humeur.

    Citation Envoyé par HeinCode Voir le message
    Je dois chercher dans un fichier de petite taille une chaine de caractère hexadécimale (que je spécifie en dur).
    Là c'est un peu pareil. Tu as la chaine, pourquoi tu veux la rechercher dans le fichier ? Est-ce pour savoir si le fichier la contient ? Est-ce pour une autre raison ?
    Bien nous identifier le problème, et surtout ne pas venir nous poser comme problème ce qui est pour toi une solution à un problème plus profond que tu nenous exposes pas ici, sinon on tombe dans le cas du problème XY et on perd du temps.

    Citation Envoyé par HeinCode Voir le message
    2) J'alloue la mémoire et copie le fichier dans un buffer (pas de problème)
    Pourquoi faire ? Tu as déjà les données dans le fichier, pourquoi les recopier ailleurs ?

    Citation Envoyé par HeinCode Voir le message
    3) Je spécifie ma chaine hexadécimale par exemple "0x484e4f505152"
    Ma question est comment faire pour rechercher dans le buffer créér cette chaine hexa ?
    fgets() pour lire une ligne du fichier, puis strstr() pour chercher une chaine dans la ligne.

    Citation Envoyé par HeinCode Voir le message
    J'ai essayé de faire comme cela:

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int index = 0;
    while (index < buffer_size) {
        if ((buffer[index + 0] == 0x48)
               && (buffer[index + 1] == 0x4e)
               && (buffer[index + 2] == 0x4f)
               && (buffer[index + 3] == 0x50))
        {
            printf("Valeur se trouve a: %d\n", index);
        }
        index++;
    }
    Tu confonds la chaine "48" et la valeur numérique 0x48 (qui peut aussi se voir comme la valeur 72).

    Citation Envoyé par HeinCode Voir le message
    Cela ne fonctionne pas. Bref, de base quelle méthode me conseillez vous pour rechercher une valeur hexa dans un buffer ?
    Le souci c'est que ce que tu nous montres comme une valeur hexa n'est en réalité que la chaine représentant la valeur hexa. Or une chaine représentant une valeur ce n'est pas la valeur. Exemple char s[]="1234" contiendra en réalité {'1', '2', '3', '4', '\0'} soit {48, 49, 50, 51, 0} (ou alors en représentation hexa {0x30, 0x31, 0x32, 0x33, 0}). Mais s[0] n'est pas égal à "0x30". Il est égal à '0', ou bien égal à 48, ou bien égal à 0x30.
    Et (accessoirement parce que je sens que tu vas bientôt l'écrire) on ne compare pas des strings avec "==" (mais peut-être que c'est le cas en C#)

    Citation Envoyé par HeinCode Voir le message
    Je pense que le buffer peut-être traité comme un tableau après memcpy mais peut-être faut-il recopier le buffer dans un
    tableau avant ?
    Ben oui. Et ensuite on n'a qu'à recopier le tableau dans un autre tableau plus petit. Puis de là encore le recopier dans un tableau encore plus petit. Quand on sera arrivé au caractère, peut-être qu'on pourra regarder s'il vaut cette chaine...

    Citation Envoyé par HeinCode Voir le message
    (procédure que je ne vois pas comment réaliser).
    Parce que tu emploies différents mots pour la même chose. En C, un caractère c'est juste le nombre de la valeur ascii représentant ce caractère. Un buffer c'est un tableau de caractères, et une chaine de caractères c'est un tableau de caractères contenant impérativement un caractère '\0' à une position de ce tableau.
    Tout le reste n'est donc que de la manipulation de tableau, manipulations déjà codées dans les différentes fonctions telles que strcpy(), memcpy(), strcmp(), memcmp(), etc.
    Un buffer, ou un tableau, c'est pareil.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Hobbiste
    Inscrit en
    Juin 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Hobbiste
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2020
    Messages : 4
    Points : 9
    Points
    9
    Par défaut
    Bonjour à toi

    Citation Envoyé par Sve@r Voir le message
    C'est super. Ben ici c'est du C. Donc déjà soit tu te trompes de forum, soit tu ne connais pas le langage que tu utilises. Dans tous les cas ça part mal et moi ça me met de mauvaise humeur.
    Merci à toi, et désolé de te mettre de mauvaise humeur. Oui c'est bien du C dont il s'agit et pas autre chose. Je n'ai effectivement aucune expérience en C mais j'essaye d'apprendre. Je n'ai pas l'habitude
    de ce type de langage étant habitué à l'assembleur. Encore une fois, je me doute que les questions peuvent paraître iconoclastes lorsqu'on l'habitude du C (ce qui n'est pas du tout mon cas). Si j'ai posté
    ici (rubrique débutant), c'est que je n'arrivais pas à faire ce que je voulais, ce n'est pas faute d'avoir cherché.

    Citation Envoyé par Sve@r Voir le message
    Là c'est un peu pareil. Tu as la chaine, pourquoi tu veux la rechercher dans le fichier ? Est-ce pour savoir si le fichier la contient ? Est-ce pour une autre raison ?
    Bien nous identifier le problème, et surtout ne pas venir nous poser comme problème ce qui est pour toi une solution à un problème plus profond que tu nenous exposes pas ici, sinon on tombe dans le cas du problème XY et on perd du temps.
    Tu as raison, je veux chercher dans un buffer (comprendre un espace mémoire que j'ai réservé et où j'ai stocké mes données). Je veux juste rechercher à une adresse mémoire particulière celle de mon buffer (où mes données sont stockées), si il y a la "chaine" expression hexa spécifiée. Pas plus, pas moins.

    Citation Envoyé par Sve@r Voir le message
    Pourquoi faire ? Tu as déjà les données dans le fichier, pourquoi les recopier ailleurs ?
    On oublie le fichier ou alors parce que tel est mon bon plaisir. Plus sérieusement, peu importe la source, c'est vraiment ce qu'il y a dans le buffer qui m'intéresse.

    Citation Envoyé par Sve@r Voir le message
    fgets() pour lire une ligne du fichier, puis strstr() pour chercher une chaine dans la ligne.


    Tu confonds la chaine "48" et la valeur numérique 0x48 (qui peut aussi se voir comme la valeur 72).

    Le souci c'est que ce que tu nous montres comme une valeur hexa n'est en réalité que la chaine représentant la valeur hexa. Or une chaine représentant une valeur ce n'est pas la valeur. Exemple char s[]="1234" contiendra en réalité {'1', '2', '3', '4', '\0'} soit {48, 49, 50, 51, 0} (ou alors en représentation hexa {0x30, 0x31, 0x32, 0x33, 0}). Mais s[0] n'est pas égal à "0x30". Il est égal à '0', ou bien égal à 48, ou bien égal à 0x30.
    Et (accessoirement parce que je sens que tu vas bientôt l'écrire) on ne compare pas des strings avec "==" (mais peut-être que c'est le cas en C#)

    Ben oui. Et ensuite on n'a qu'à recopier le tableau dans un autre tableau plus petit. Puis de là encore le recopier dans un tableau encore plus petit. Quand on sera arrivé au caractère, peut-être qu'on pourra regarder s'il vaut cette chaine...
    Merci c'est très clair, et pédagogique. Je comprends mieux maintenant l'origine de mon erreur.

    Citation Envoyé par Sve@r Voir le message
    Parce que tu emploies différents mots pour la même chose. En C, un caractère c'est juste le nombre de la valeur ascii représentant ce caractère. Un buffer c'est un tableau de caractères, et une chaine de caractères c'est un tableau de caractères contenant impérativement un caractère '\0' à une position de ce tableau.
    Tout le reste n'est donc que de la manipulation de tableau, manipulations déjà codées dans les différentes fonctions telles que strcpy(), memcpy(), strcmp(), memcmp(), etc.
    Un buffer, ou un tableau, c'est pareil.
    Merci encore pour tes précieuses remarques et commentaires. Cela me permet d'avancer (un peu) et encore désolé pour les noeuds à l'estomac que tu
    as pu ressentir en lisant mon message. Cela n'était pas intentionnel.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par HeinCode Voir le message
    Merci encore pour tes précieuses remarques et commentaires. Cela me permet d'avancer (un peu) et encore désolé pour les noeuds à l'estomac que tu
    as pu ressentir en lisant mon message. Cela n'était pas intentionnel.
    ok, c'est pas grave (ça c'est ma réponse)

    Citation Envoyé par HeinCode Voir le message
    On oublie le fichier ou alors parce que tel est mon bon plaisir. Plus sérieusement, peu importe la source, c'est vraiment ce qu'il y a dans le buffer qui m'intéresse.
    D'accord, c'est ton droit absolu. Donc à condition que ton buffer soit une chaine, c'est à dire que tu puisses garantir par n'importe quel moyen qu'elle contient un '\0' (quitte au pire des cas à le mettre toi-même), alors tu peux chercher une chaine dans ce buffer en utilisant strstr().

    PS: ne t'inquiète pas pour la garantie car le truc est bien rodé. Si tu pars d'une chaine au départ (ex char s[]="1234") alors le compilo rajoute automatiquement un '\0' dans "s" (voir mon post précédent). Ensuite toutes les fonctions de traitement de strings qui utiliseront cette chaine pour la copier ou autre opération de création rajoutent elles-même le '\0'. Idem si tu récupères cette chaine depuis un fichier via fgets(). Bref toute fonction qui a pour but de créer une chaine (à l'exception de strncpy() ou strncat() dans un certain cas mais pour l'instant t'en es pas là) rajoute toujours le '\0' qu'il faut.
    Le seul moment où tu n'es pas certain du '\0', c'est quand tu récupères un flot d'octets brut via (par exemple) fread(). Mais dans ce cas, comme la fonction te renvoie le nb d'octets récupérés, tu as alors parfaitement le droit d'utiliser ce nombre pour aller placer le '\0' manuellement au bon endroit.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Hobbiste
    Inscrit en
    Juin 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Hobbiste
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2020
    Messages : 4
    Points : 9
    Points
    9
    Par défaut
    Merci pour ces éléments. Je n'ai aucune garantie que mon buffer se termine par '\0'. Je ne connais que la taille de mon fichier. Pour être totalement transparent, voici exactement ce que je fais:

    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
    FILE* fp1 = fopen(argv[1], "r")
     
    // calcule la taille du fichier
    fseek(fp1, 0L, SEEK_END);
    long int file_size = ftell(fp1);
     
    // allocation de la mémoire
    fseek(fp1, 0L, SEEK_SET);
    char *buffer;
    buffer = (char*)calloc(file_size, sizeof(char));
     
    // copie du fichier dans un buffer
    fread(buffer, sizeof(char), file_size, fp1);
     
    // fermeture du fichier
    fclose(fp1);

    Le dump de mon fichier en hex est du type:
    14000000001C00028600000000F00042282400401410FF6224DC00A98F000000001800 ...............B($.@...b$..........
    09011250000000000000000000001A004A0002004015000000000D000700FFFF012404 ...P............J...@............$.
    0041150080013C02004114000000000D00060012100000000000000100422418004900 .#.D.#.d...........................
    12180000000000000000000018006800121800009800A3AF0C0002969800A4971C0003 ....A.A.B(..........A..............

    Ce dump est dans mon buffer. Je voudrais savoir si la séquence "0041150080013C0" (début de la troisième ligne)
    est dans mon buffer.

    Tu me conseilles d'utiliser (strstr). J'ai essayé de faire cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     char* valeur = "0041150080013C0";
    char *index = strstr(buffer, valeur);
    index devrait retourner NULL ou la position dans le buffer, mais cela ne semble pas fonctionner. Le problème
    est que je ne comprends pas comment indiquer simplement la variable valeur à str.
    Peux-tu me dire ou ça déconne ? Ce genre de truc me semble pourtant très simple.
    Merci pour tes éventuels retours.

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par HeinCode Voir le message
    Merci pour ces éléments. Je n'ai aucune garantie que mon buffer se termine par '\0'. Je ne connais que la taille de mon fichier. Pour être totalement transparent, voici exactement ce que je fais:

    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
    FILE* fp1 = fopen(argv[1], "r")
     
    // calcule la taille du fichier
    fseek(fp1, 0L, SEEK_END);
    long int file_size = ftell(fp1);
     
    // allocation de la mémoire
    fseek(fp1, 0L, SEEK_SET);
    char *buffer;
    buffer = (char*)calloc(file_size, sizeof(char));
     
    // copie du fichier dans un buffer
    fread(buffer, sizeof(char), file_size, fp1);
     
    // fermeture du fichier
    fclose(fp1);
    Effectivement, tu crées un buffer de "exactement" la même taille que le fichier puis tu lui mets tout le fichier. Donc ton buffer n'est pas une chaine.
    Mais c'est pas compliqué à remedier. Te suffit de créer un buffer de "un octet" de plus, et mettre cet octet à 0. En théorie tu n'es même pas obligé de mettre le buffer à 0 via calloc puisque le buffer est chargé avec le contenu du fichier, seul le caractère "en plus" doit être à 0. Mais si, comme beaucoup de débutants, tu es inquiet sur ce point, alors on peut lasiser calloc c'est pas grave. Mais il faut impérativement cet octet en plus => buffer = calloc(file_size + 1, sizeof(char)). Maintenant tu es assuré que buffer est une string.

    Citation Envoyé par HeinCode Voir le message
    Le dump de mon fichier en hex est du type:
    14000000001C00028600000000F00042282400401410FF6224DC00A98F000000001800 ...............B($.@...b$..........
    09011250000000000000000000001A004A0002004015000000000D000700FFFF012404 ...P............J...@............$.
    0041150080013C02004114000000000D00060012100000000000000100422418004900 .#.D.#.d...........................
    12180000000000000000000018006800121800009800A3AF0C0002969800A4971C0003 ....A.A.B(..........A..............

    Ce dump est dans mon buffer. Je voudrais savoir si la séquence "0041150080013C0" (début de la troisième ligne)
    est dans mon buffer.
    Hum, au départ il n'était pas censé être question de fichier, seulement d'un buffer texte. On voit ici que le fichier a son importance. Dis-moi, ce fichier est-il un fichier texte (un truc affichable à l'écran et lisible par un humain) ou bien un fichier binaire (un truc qui ne peut être compris que par un programme) ?
    Je pense pour le binaire parce que si c'était un fichier texte, le dump montrerait alors des mots, des phrases, ou même simplement des lettres. Là on ne voit que des "."
    Or (et on revient encore au même point), la chaine "0041150080013C0" n'est que la représentation "humaine" de la valeur 0041150080013C0 (qui n'est en fait même pas une valeur car un fichier ne contient que des octets, donc il y a l'octet de valeur 0x00, l'octet de valeur 0x41, l'octet de valeur 0x15, etc.
    Et donc (je vais réduire un peu) la chaine "004115" (qui est en fait la chaine {'0', '0', '4', '1', '1', '5', '\0'} ou alors en hexa {0x30, 0x30, 0x34, 0x31, 0x31, 0x35, 0x00} n'est pas égale à la valeur 004115

    Citation Envoyé par HeinCode Voir le message
    Tu me conseilles d'utiliser (strstr). J'ai essayé de faire cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     char* valeur = "0041150080013C0";
    char *index = strstr(buffer, valeur);
    Oui, car tu nous as dit que tu partais d'un texte, donc une suite de caractères "human readable". strstr() fonctionne pour des chaines textuelles (exemple strstr("barbapapa", "pa") retournera l'adresse située à 3 rangs de l'adresse de début de "barbapapa"). Mais ça ne fonctionne pas pas si le truc dans lequel on cherche ce n'est pas du texte. A la limite, je vois dans ton dump la suite "B($" donc (juste pour te montrer que strstr() fonctionne) tu peux écrire char *index = strstr(buffer, "B($") mais il te faut avoir bien conscience que cette méthode ne te permettra pas de chercher ta suite binaire dans ton fichier binaire.
    Syndrome du problème XY dont j'ai parlé ce matin. Au lieu de nous exposer ton problème initial, tu nous as exposé les difficultés à mettre en place une solution de ton cru qui n'est pas adaptée au problème.

    Citation Envoyé par HeinCode Voir le message
    Ce genre de truc me semble pourtant très simple.
    Très simple oui. Quand tu as les données dans le bon format. Sinon il faut faire de la conversion, soit dans un sens, soit dans l'autre. Et ça devient de suite moins simple.

    PS: tu l'auras bien compris, si ton fichier est binaire, alors le buffer dans lequel tu le charges n'a pas besoin d'être une string donc le "+1" dont je parle au tout début de ce post ne sert plus
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Hobbiste
    Inscrit en
    Juin 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Hobbiste
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2020
    Messages : 4
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Effectivement, tu crées un buffer de "exactement" la même taille que le fichier puis tu lui mets tout le fichier. Donc ton buffer n'est pas une chaine.
    Mais c'est pas compliqué à remedier. Te suffit de créer un buffer de "un octet" de plus, et mettre cet octet à 0. En théorie tu n'es même pas obligé de mettre le buffer à 0 via calloc puisque le buffer est chargé avec le contenu du fichier, seul le caractère "en plus" doit être à 0. Mais si, comme beaucoup de débutants, tu es inquiet sur ce point, alors on peut lasiser calloc c'est pas grave. Mais il faut impérativement cet octet en plus => buffer = calloc(file_size + 1, sizeof(char)). Maintenant tu es assuré que buffer est une string.
    Ok c'est bon à savoir.

    Hum, au départ il n'était pas censé être question de fichier, seulement d'un buffer texte. On voit ici que le fichier a son importance. Dis-moi, ce fichier est-il un fichier texte (un truc affichable à l'écran et lisible par un humain) ou bien un fichier binaire (un truc qui ne peut être compris que par un programme) ?
    Je pense pour le binaire parce que si c'était un fichier texte, le dump montrerait alors des mots, des phrases, ou même simplement des lettres. Là on ne voit que des "."
    Or (et on revient encore au même point), la chaine "0041150080013C0" n'est que la représentation "humaine" de la valeur 0041150080013C0 (qui n'est en fait même pas une valeur car un fichier ne contient que des octets, donc il y a l'octet de valeur 0x00, l'octet de valeur 0x41, l'octet de valeur 0x15, etc.
    Et donc (je vais réduire un peu) la chaine "004115" (qui est en fait la chaine {'0', '0', '4', '1', '1', '5', '\0'} ou alors en hexa {0x30, 0x30, 0x34, 0x31, 0x31, 0x35, 0x00} n'est pas égale à la valeur 004115
    On est bien d'accord merci. Je n'ai peut-être pas été assez clair effectivement mais il s'agit d'un fichier .bin (un dump de mémoire) et non un fichier texte.

    Oui, car tu nous as dit que tu partais d'un texte, donc une suite de caractères "human readable". strstr() fonctionne pour des chaines textuelles (exemple strstr("barbapapa", "pa") retournera l'adresse située à 3 rangs de l'adresse de début de "barbapapa"). Mais ça ne fonctionne pas pas si le truc dans lequel on cherche ce n'est pas du texte. Syndrome du problème XY dont j'ai parlé ce matin. Au lieu de nous exposer ton problème initial, tu nous as exposé les difficultés à mettre en place une solution de ton cru qui n'est pas adaptée au problème.

    Le fichier n'est pas "human readable", peut-être "alien readable" tout au plus. Je cherche dans le fichier binaire les opcodes d'instructions
    en assembleur (Motorola 680x0 / MIPS par exemple).

    Très simple oui. Quand tu as les données dans le bon format. Sinon il faut faire de la conversion, soit dans un sens, soit dans l'autre. Et ça devient de suite moins simple.
    PS: tu l'auras bien compris, si ton fichier est binaire, alors le buffer dans lequel tu le charges n'a pas besoin d'être une string donc le "+1" dont je parle au tout début de ce post ne sert plus
    Au moins une bonne nouvelle. Pas de +1, pas de strstr() mais c'est simple. Merci pour tes conseils avisés. Du reste, je ne vois toujours pas comment résoudre mon problème "simple", je reste
    donc preneur de pistes. Merci.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par HeinCode Voir le message
    Du reste, je ne vois toujours pas comment résoudre mon problème "simple", je reste donc preneur de pistes.
    Comme je l'ai dit, il faut convertir les données dans un sens, ou dans l'autre. Je pense que convertir ta chaine de recherche est ce qu'il y a de plus facile plutôt que de convertir un dump entier.

    Mais bien que ce soit le plus facile des deux, c'est pas évident

    Ci-joint un exemple sur un dump qui contient ceci (je mets en rouge ce que je cherche)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 03 00 3e 00 01 00 00 00 20 11 00 00 00 00 00 00 40 00 00 00 00 00 00 00 68 3c 00 00 00 00 00 00 00 00 00 00 40 00 38 00 0b 00 40 00 1e 00 1d 00 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 68 02 00 00 00 00 00 00 68 02 00 00 00 00 00 00 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 a8 02 00 00 00 00 00 00 a8 02 00 00 00 00 00 00 a8 02 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 08 00 00 00 00 00 00 f0 08 00 00 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 05 00 00 00 00 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 ad 03 00 00 00 00 00 00 ad 03 00 00 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 04 00 00 00 00 20 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 20 00 00 00 00 00 00 70 01 00 00 00 00 00 00 70 01 00 00 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 06 00 00 00 e8 2d 00 00 00 00 00 00 e8 3d 00 00 00 00 00 00 e8 3d 00 00 00 00 00 00 b0 02 00 00 00 00 00 00 e8 02 00 00 00 00 00 00 00 10 00 00 00 00 00 00 02 00 00 00 06 00 00 00 f8 2d 00 00 00 00 00 00 f8 3d 00 00 00 00 00 00 f8 3d 00 00 00 00 00 00 e0 01 00 00 00 00 00 00 e0 01 00 00 00 00 00 00 08 00 00 00 00 00 00 00 04 00 00 00 04 00 00 00 c4 02 00 00 00 00 00 00 c4 02 00 00 00 00 00 00 c4 02 00 00 00 00 00 00 44 00 00 00 00 00 00 00 44 00 00 00 00 00 00 00 00
    Et le programme qui me permet de chercher ce que je veux dans ce dump et qui m'affiche sa position. Il m'a fallu constuire tous les outils un à un
    Code c : 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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
     
    // Affichage buffer à l'écran (juste pour vérifier)
    void hexdump(unsigned char *buffer, unsigned long n) {
    	unsigned char *pt;
    	unsigned long i;
    	for (i=0, pt=buffer; i < n; i++, pt++)
    		printf("%02x ", *pt);
    	fputc('\n', stdout);
    }
     
    // Conversion d'un caractère "hexa" en valeur hexa
    unsigned short car2hex(unsigned char c) {
    	// Le caractère '0' (ascii 48) vaut 0 (donc il vaut '0' - '0')
    	if isdigit(c) return c - '0';
     
    	// Le caractère 'a' (ascii 97) vaut 10 (donc il vaut 'a' - 'a' + 10)
    	return tolower(c) - 'a' + 10;
    }
     
    // Recherche d'une chaine dans un dump
    unsigned char* findDump(unsigned char *buffer, unsigned short n, unsigned char *str) {
    	// Conversion de la string représentant de l'hexa en vrai hexa
    	// Il est impératif que la chaine soit de taille paire, sinon perte dernier octet
    	// D'abord, mémoire pour récupérer la conversion
    	size_t len=strlen(str);
    	unsigned char *hexa=malloc((len/2) * sizeof(unsigned char));
     
    	// Maintenant conversion caractère vers hexa
    	for (size_t i=0; i < len; i+=2) {
    		hexa[i/2]=car2hex(str[i]) * 0x10 + car2hex(str[i+1]);
    		//printf("i=%lu, (%c %c), %02x\n", i, str[i], str[i+1], hexa[i/2]);
    	}
    	// hexdump(hexa, len/2);
     
     
    	// On a maintenant une valeur hexa (binaire) à trouver dans un buffer binaire
    	// Bizarrement memmem (qui sert à ça) ne fonctionne pas (en plus mon compilo me dit qu'il ne la connait pas)
    	// Dommage, car suffisait d'écrire directement return memmem(buffer, n, hexa, len/2)
    	// Pas grave, on va se taper le balayage du buffer à la mano
    	unsigned long i;
    	unsigned char *pt;
    	for (i=0, pt=buffer; i < n; i++, pt++) {
    		if (memcmp(pt, hexa, len/2) == 0) {
    			//printf("%p, %p, %hu\n", buffer, pt, pt-buffer);
    			free(hexa);
    			return pt;
    			break;
    		}
    	}
     
    	// Pas trouvé
    	free(hexa);
    	return NULL;
    }
     
    int main() {
    	unsigned char buffer[1000];
    	unsigned long nb;
    	FILE *fp=fopen("client", "r");
    	nb=fread(buffer, sizeof(unsigned char), 1000, fp);
    	fclose(fp);
    	printf("nb=%lu\n", nb);
    	// hexdump(buffer, nb);
    	printf("%hu\n", findDump(buffer, nb, "002011") - buffer);			// Ici, affichage 23 qui est bien la 24° position de la chaine "002011" dans le dump (la première position commence à 0)
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 551
    Points
    1 551
    Par défaut
    Hello,

    memcmp() me parait convenir ici.

    Edit: ouups, je viens de voir que Sve@r en a déjà parlé.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

Discussions similaires

  1. Rechercher une valeur hex dans un fichier
    Par NicCo dans le forum Débuter
    Réponses: 26
    Dernier message: 01/04/2014, 09h48
  2. recherche d'une chaine caractère dans un fichier
    Par maitre.dohko dans le forum VBScript
    Réponses: 6
    Dernier message: 21/04/2010, 12h13
  3. Réponses: 2
    Dernier message: 02/09/2008, 14h17
  4. Comment chercher une chaine hexa dans un fichier ?
    Par marchphi dans le forum Langage
    Réponses: 4
    Dernier message: 26/02/2008, 07h59
  5. Réponses: 9
    Dernier message: 07/09/2006, 13h47

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