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

 Delphi Discussion :

Rechercher une valeur hex dans un fichier


Sujet :

Delphi

  1. #1
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut Rechercher une valeur hex dans un fichier
    Bonjour
    Je suis en train d'essayer de faire quelque chose mais j'avoue pour le moment n'arriver à rien.
    Je voudrais ouvrir un fichier en hexadécimal et rechercher à l'intérieur de ce fichier la valeur hexa 'CA 32 18 1A 30' par exemple. Je recherche également la même chose pour rechercher une chaîne cette fois ASCII.
    Pour être plus précis, je souhaite ouvrir un fichier de taille importante (> à 10Go), le parcourir et quand je trouve la chaîne en hexa souhaitée je voudrais récupérer la chaîne de 8 caractères qui suit.
    Est-ce possible ?
    Est-ce que le fichier de 10Go ne va pas être chargé entièrement en mémoire (auquel cas je n'aurais pas assez de RAM) ?
    Auriez-vous des exemples pour réaliser ces fonctions ?
    Merci !

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 92
    Points : 159
    Points
    159
    Par défaut
    alors pour commencer, le fichier doit être ouvert avec un tfilestream.
    le tfilestream te permettra d'ouvrir le fichier et de le lire morceau par morceau.
    si tu utilises le tmemorystream, il va te mettre tout ton fichier en mémoire (déconseiller dans ton cas)
    la lecture du fichier avec le tfilestream se fera avec readbuffer avec une taille ni trop grande ni trop petite ( trop grande : prends de la place en mémoire, trop petit : nbreux accés disque et donc performance moindre) tu peux partir sur un multiple de 1024 : 4096 / 8192 ...

    ensuite concernant la recherche :
    tu vas lire la donnée telle quelle est dans ton fichier.
    si tu utilises un buffer brute ( array of byte ), il va falloir que tu transformes ta donnée en hexa et en string pour faire tes 2 recherches.
    si tu utilises un buffer de caractere (array of char), il faudra aussi transformer ta donnée

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    Voici des sujets qui pourrait te plaire :
    - comment chercher une valeur hex dans un fichier binaire "file of byte" faut juste remplacer dans cette version if iCountFound = Threshold then par if Result = Threshold then.
    - Utilisation de SearchInBinaryFile
    - Variante SearchBinaryInBinary

    Tu as aussi les variantes SearchStringInFile et SearchStringInBigFile, la première utilisant BlockRead et l'autre directement FileRead, c'était le Eof qui pouvait être faux sur un fichier de plus de 2Go !

  4. #4
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Merci pour vos réponses, je vais jeter un oeil sur tout ca

    Par contre petite question peut être stupide au niveau du readbuffer : est-ce qu'il lit par exemple 1024 octets du fichier puis les 1024 octets suivants etc etc ? Dans ce cas, si la chaine que je cherche est à cheval entre la fin du 1er bloc de 1024 et le début du 2nd, il n'y aura pas de problème ?

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    Si si cela pose problème et c'est géré dans SearchInBinaryFile, on en avait même discuté

    Citation Envoyé par Gilbert Geyer Voir le message

    Citation Envoyé par ShaiLeTroll Voir le message
    C'est la difficulté, faut gérer la possibilité d'avoir un mot a cheval sur deux buffers (, si j'ai le temps, j'essayerais de faire une SearchStringsInBigFile, c'est juste qu'il faut gérer un tableau d'offset pour chaque mot à chercher et la boucle risque de se complexifier ... mais justement c'est bien tout l'intéret de cet algo ..
    ... je viens de m'en rendre compte car je viens de tester une variante utilisant un FileSream + 1 buffer et en envoyant à l'algo d'Edam la chaîne s:=string(buff); il me manquait au comptage quelques mot-cibles à cheval sur la fin du buffer [0..4096] et même en prenant un buffer [0..65535] ça n'y a rien changé je pensais réduire ainsi la probabilité de se trouver à cheval
    Par contre, cela ne fonctionne pas si l'on cherche une chaine plus longue que le buffer (du moins, je crois, je n'ai jamais testé)

  6. #6
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Merci pour l'explication

    Donc la fonction SearchInBinaryFile gère les chevauchements, SearchStringInFile gère aussi cette particularité ?

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    Oui, c'est le même algo, juste quelques spécificités sur les string comme la comparaison avec ou sans casse !
    Attention, je les ai codé et tester en D6 et D7 donc des fichiers ANSI et des AnsiChar !
    Pense à forcer le type AnsiString et AnsiChar si tu veux les utiliser sur un Delphi Unicode !

    Citation Envoyé par NicCo Voir le message
    Donc la fonction SearchInBinaryFile gère les chevauchements, SearchStringInFile gère aussi cette particularité ?
    D'ailleurs, si cela ne le gérait pas ces fonctions n'aurait aucun intérêt !

  8. #8
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Je vais regarder ca vu que je suis en Delphi XE2.

    Je suis en train d'essayer de les faire marcher mais il faut encore que je glane quelques informations par ci par là, pour le moment je n'arrive pas à les utiliser.

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    Fournit ton code d'appel, comme je les ai écrites, je suis le mieux placés pour te dire comment les utiliser

    Attention, fait bien la différence entre une valeur hexa et sa représentation texte !

    ne cherche pas 'FF CC' via SearchStringInFile mais bien $FFCC comme buffer de SearchInBinaryFile (S[0] := $FF et S[1] := $CC);

    J'ai utilisé un TByteDynArray pour forcer l'utilisation du tableau !
    mes premières versions utilisait un pointeur, j'avais eu la mauvaise idée de chercher un integer et d'oublier le LittleEndian !
    le TByteDynArray c'est plus chiant à remplir mais évite que l'on se trompe !

  10. #10
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Merci pour la proposition, pour le moment je n'ai pas de code d'appel, j'essaye de comprendre comment ca fonctionne au niveau des paramètres à renseigner

    Si j'ai bien compris, je n'ai pas besoin de fonction annexe à SearchInBinaryFile, j'ai juste à l'appeler ? Je bloque au niveau des types TByteDynArray et TInt64DynArray que je ne connaissais pas, j'ai déjà vu qu'il faut ajouter le uses Types pour pouvoir les utiliser donc ca c'est OK, mais comment se présente l'attribution d'une valeur à une variable TByteDynArray et TInt64DynArray ?

    Si je n'utilise pas le keepOffset, la fonction sert simplement à renvoyer le nombre d’occurrences trouvées, et si je l'utilise je pourrai relire toutes ces occurences dans mon tableau Offsets ? Le threshold je n'en ai pas besoin, l'overlap non plus donc pas de souci de ce côté là.

    Je tomberai sur quelque chose comme cela (en simplifié mais avec une déclaration incorrecte je pense pour Recherche) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var
      Fichier: string;
      Recherche: TByteDynArray;
      Positions: TInt64DynArray;
    begin
      Fichier:='C:\MonFichier.txt';
      Recherche:=StringToByteArray('32CA50FF');
      SearchBinaryInFile(Fichier, Recherche, Positions, True, 0, False);
    end;
    Ce qui lancerait une recherche sur tout le fichier et au final m'indiquerait la position des éléments recherchés, mais ensuite comment parcourir le tableau Positions pour continuer mon traitement (récupérer les 12 valeurs qui suivent, etc...) ?

    Désolé je suis un peu perdu :-/

    Edit : J'ai trouvé cette fonction pour la conversion de string vers TByteDynArray, j'ai modifié mon code ci-dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function StringToByteArray(const S: AnsiString): TByteDynArray; 
    var 
      Len: Integer; 
    begin 
      Len := Length(S); 
      SetLength(Result, Len); 
      Move(S[1], Result[0], Len); 
    end;

  11. #11
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 874
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Recherche:=StringToByteArray('32CA50FF');
    Va donner un tableau de longueur 8 octets ($33 $32 $43$41...) alors que tu pourrais vouloir chercher la suite de 4 octets $32 $CA $50 $FF, non ?

  12. #12
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Exact la conversion n'est pas bonne, j'ai donc continué sur plus simple et je suis passé au test de la fonction SearchStringInFile.
    Comme je suis sous Delphi XE2, j'ai modifié les 2 string (du const FileName, SearchString et du UpSearchString) en AnsiString et le char du SearchBuf en AnsiChar, j'appelle la fonction et c'est OK, j'ai bien un résultat en retour de la fonction.
    Je ne sais pas encore comment exploiter le tableau d'offsets mais ca avance. Je préfèrerais également utiliser une recherche en binaire plutôt qu'en string (à priori ca devrait être plus simple si j'arrive à déclarer le tableau de Byte

  13. #13
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Bon petit à petit j'avance mais c'est pas encore parfait.
    Sur le même fichier, je recherche via la chaine : 11105 résultats et via le binary : 1 résultat
    J'ai déclaré le TByteDynArray de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      SetLength(Recherche, 4);
      Recherche[1]:=$4F;
      Recherche[2]:=$46;
      Recherche[3]:=$4D;
      Recherche[4]:=$44;
    J'ai également modifié le string en AnsiString dans SearchBinaryInFile

    Edit : Je me suis peut être trompé sur le 1er élément du tableau, j'ai mis 1 au lieu de 0, je vais tester ca tout à l'heure

  14. #14
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    Citation Envoyé par NicCo Voir le message
    Edit : Je me suis peut être trompé sur le 1er élément du tableau, j'ai mis 1 au lieu de 0, je vais tester ca tout à l'heure
    Oui tableau en base 0

    Pour le FileName, normalement, cela fonctionne avec un type TFileName, cela évitera des warnings vu qu'au final cela utilise System.SysUtils.FileOpen


    UpSearchString dans SearchBinaryInFile ne sert à rien,
    un vieux reste sur cette version lors du passage de SearchStringInBigFile adapté en SearchBinaryInFile

    OffSets contient les positions du premier caractère de la sous chaine autant de fois qu'elle est présente, surtout conçu pour une relecture via System.SysUtils.FileRead ou via un TStream !

    J'ai utilisé cette fonction dans un programme qui analysait le code de projet Delphi6 pour chercher tous les Translate de Multilizer D6 pour les transformer en Translate d'une lib interne maison (en D7) qui au passage ajoutait un numéro de message (Multilizer utilisait le message comme clé de translation) et un dédoublonnage des chaines en double

    Pour moi, savoir où-était la chaine recherchée me permettait d'effectuer mes remplacements, ensuite je cherchais le ); pour transformer par exemple Translate('toto'); en epcTranslate('toto', 1234);

  15. #15
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Merci pour votre aide, effectivement avec un tableau en base 0 ca fonctionne tout de suite mieux

    Par contre toujours quelque chose de bizarre. Dans un même fichier, je cherche la chaîne type string 'OFMD' et j'obtiens 11105 résultats avec SearchStringInFile et si je cherche cette même chaine en format hexa '4F464D44' avec SearchBinaryInFile cette fois j'obtiens cette fois 11063 résultats. Le résultat ne devrait pas être le même ?

    Deux questions suite à ca :
    - Est-il possible de chercher une chaine hexa (via la fonction c'est OK) et si elle est trouvée, rechercher dans les (par exemple) 40 valeurs suivantes si une autre chaine hexa est présente ?
    - Comment récupérer les (par exemple) 20 valeurs qui suivent lorsque la chaine est trouvée ?

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    Citation Envoyé par NicCo Voir le message
    Le résultat ne devrait pas être le même ?
    Normalement si !
    Sauf pour la sensibilité à la casse qui par défaut est respecté dans SearchStringInFile, paramètre CaseSensitive est à True
    Fait attention à l'ordre des paramètres car si tu confonds CaseSensitive et AcceptOverlap,
    c'est surement ça le soucis une activation de l'insensibiltié à la casse donc plus de réponse possible !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SearchBinaryInFile(Fichier, Recherche, Positions, True, 0, (*AcceptOverlap*)False);
    SearchBinaryInFile(Fichier, Recherche, Positions, True); // Même en utilisant les valeurs par défaut, je te conseille ça !
    SearchStringInFile(Fichier, Recherche, Positions, True, 0, (*CaseSensitive*)False, (*AcceptOverlap*)False);
    SearchStringInFile(Fichier, Recherche, Positions, True); // Valeur par défaut
    Compare avec UltraEdit ou Notepad++, moi, j'ai testé ainsi !



    Citation Envoyé par NicCo Voir le message
    - Est-il possible de chercher une chaine hexa (via la fonction c'est OK) et si elle est trouvée, rechercher dans les (par exemple) 40 valeurs suivantes si une autre chaine hexa est présente ?
    Citation Envoyé par NicCo Voir le message
    - Comment récupérer les (par exemple) 20 valeurs qui suivent lorsque la chaine est trouvée ?
    les deux questions ont à la même solutions

    tu as l'offset, tu peux alors faire pour la première occurrence

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SearchBinaryInFile(Fichier, Recherche, Positions, True); // tu n'es pas obligé de tout mettre, il y a des valeurs par défaut
    FileToSearch := FileOpen(Fichier, fmOpenRead);
    FileSeek(FileToSearch, Positions[0] + Length(Recherche) , FILE_BEGIN); // tu seras juste APRES le D si Recherche contient 'OFMD' !
    FileRead(FileToSearch, S[1], 40); // 40 ou 20, S c'est un string[40]
    Ensuite, soit tu fais un simple System.AnsiStrings.AnsiPos(#$FE#$FD, S) soit tu utilises SearchBinaryInBinary

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SetLength(AA, 2);
    AA[0] := $FF;
    AA[1] := $FE;
    SearchBinaryInBinary(@S[1], 40, AA, DummyOffsets);
    le tout pouvant être dans une boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SearchBinaryInFile(...
    FileToSearch := FileOpen(...
    for I := Low(Positions) to High(Positions) do
    begin
      FileSeek(...Positions[I]...); 
      FileRead ... 
      if SearchBinaryInBinary ... > 1 then
        ...
    end

  17. #17
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Vraiment très fort, effectivement il s'agissait bien de la gestion de la casse, après le passage à True j'ai bien le même nombre de valeurs entre Binary et String

    Merci pour le reste de l'explication, je vais regarder un peu tout ca

  18. #18
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    Alors tout semble fonctionner sauf le SearchBinaryInBinary, dès que le programme arrive à cette fonction j'ai une erreur de lecture et le programme plante.
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Fichier: string;
      FileToSearch: integer;
      RechSEI, RechOFMD: TByteDynArray;
      PosSEI: TInt64DynArray;
      PosOFMD: TCardinalDynArray;
      iOff, TotalSEI: integer;
      S: AnsiString;
    begin
      Fichier:='C:\Temp\Test.hex';
     
      SetLength(RechSEI, 6);
      RechSEI[0]:=$00;
      RechSEI[1]:=$00;
      RechSEI[2]:=$00;
      RechSEI[3]:=$01;
      RechSEI[4]:=$06;
      RechSEI[5]:=$25;
     
      SetLength(RechOFMD, 4);
      RechOFMD[0]:=$4F;
      RechOFMD[1]:=$46;
      RechOFMD[2]:=$4D;
      RechOFMD[3]:=$44;
     
      TotalSEI:=SearchBinaryInFile(Fichier, RechSEI, PosSEI, True, MaxInt, False);
     
      FileToSearch := FileOpen(Fichier, fmOpenRead);
      Memo1.Lines.BeginUpdate();
       try
          Memo1.Lines.Add('---');
          for iOff := Low(PosSEI) to High(PosSEI) do
          begin
            FileSeek(FileToSearch, PosSEI[iOff] + Length(RechSEI) , FILE_BEGIN);
            FileRead(FileToSearch, S[1], 40);
            if SearchBinaryInBinary(@S[1], 40, RechOFMD, PosOFMD, True, MaxInt, False) > 1 then Memo1.Lines.Add(IntToStr(PosOFMD[iOff]));
          end;
       finally
          Memo1.Lines.EndUpdate();
       end;
    end;
    Peut-être une erreur quelque part ? Il n'y a pas de modifications à faire sur BinaryToBinary pour une utilisation sous Delphi XE2 ?

    Merci !

  19. #19
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 254
    Points
    25 254
    Par défaut
    il manque SetLength(S, 40); pour allouer la mémoire de S
    etonnant que FileRead n'échoue pas aussi !

    tu peux utiliser aussi TByteDynArray au lieu de AnsiString, cela évite de mélanger les genres et montre que tu manipules QUE du binaire !
    Idem, faudra faire un SetLength
    Mais faut utiliser FileRead(..., S[0], ... et SearchBInB(@S[0], ... car en base zéro !


    SearchBinaryInBinary utilise directement CompareMem, c'est Byte comparé à Byte, donc pas de soucis lié à l'Unicode !
    CompareMem a changé entre D6 et la version FastMM de XE2 mais je pense que c'est compatible
    utilise le code de test fourni pour vérifier


    ) > 1 then Memo1.Lines.Add(IntToStr(PosOFMD[iOff])); ne devrait-t-il pas être ) > 0 then Memo1.Lines.Add(IntToStr(PosSEI[iOff]) +' : '+ IntToStr(PosOFMD[0])); ?

  20. #20
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2014
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mars 2014
    Messages : 143
    Points : 60
    Points
    60
    Par défaut
    C'est parfait tout fonctionne comme je le souhaite pour le moment

    Une dernière question je pense : actuellement, j'utilise la fonction SearchInBinaryFile et j'enregistre la position des offsets de tout ce que je trouve. Ensuite avec une boucle je vais relire mon fichier à chaque position d'offset (via FileSeek) et je lis les 200 octets qui suivent (via FileRead).
    Ma question : ne serait-il pas possible de modifier la fonction SearchBinaryInFile pour qu'au lieu de stocker les offsets et les relire plus tard via une boucle on puisse lire directement les 200 octets ? J'ai essayé quelques modifs mais ca plante la fonction...

Discussions similaires

  1. Assigner a une variable une valeur lue dans un fichier texte
    Par mapotam dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 22/12/2009, 14h46
  2. Réponses: 15
    Dernier message: 14/08/2009, 14h45
  3. Rechercher une valeur précise dans une table
    Par tonton54 dans le forum MySQL
    Réponses: 5
    Dernier message: 28/10/2008, 15h58
  4. Rechercher une valeur particulière dans une table
    Par stefsas dans le forum SAS Base
    Réponses: 2
    Dernier message: 22/09/2008, 17h40
  5. Réponses: 9
    Dernier message: 12/08/2008, 16h50

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