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

Langage Delphi Discussion :

Lecture zipfile crypté


Sujet :

Langage Delphi

  1. #1
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut Lecture zipfile crypté
    Bonjour à tous,
    Je cherche à lire un fichier zippé et crypté (7Zip, mode ZipCrypto).
    De nombreux sites et forums donnent des exemples pour crypter un fichier mais peu pour le décryptage.
    Mes recherches m'ont amené à https://www.uweraabe.de/Blog/2017/03...rd-encryption/

    En utilisant l'unité fournie et mon 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      myZipFile:           TEncryptedZipFile;
      DecompressionStream: TStream;
      zh:                  TZipHeader;
      nIdx:                integer;
      sComponent:          string;
    begin
      Memo1.Clear;
      myZipFile := nil;
     
      if TZipFile.IsValid(sFileName) then
      begin
        try
          myZipFile := TEncryptedZipFile.Create(sPassword);
          DecompressionStream := TStream.Create;
          myZipFile.Open(sFileName, zmRead);
     
          // Recherche des fichiers
          for nIdx := 0 to myZipFile.FileCount - 1 do
          begin
            sComponent := myZipFile.FileNames[nIdx];
            Memo1.Lines.Add(sComponent);
     
            myZipFile.Read(sComponent, DecompressionStream, zh);
            Memo1.Lines.Add(intToStr(DecompressionStream.size));
            Memo1.Lines.Add(intToStr(zh.UncompressedSize));
            Memo1.Lines.Add(intToStr(zh.CompressedSize));
     
            if DecompressionStream.size > 0 then
            begin
              DecompressionStream.Seek(soFromBeginning, 0);
              Memo1.Lines.LoadFromStream(DecompressionStream);
            end;
     
          end;
          myZipFile.Close;
        finally
     
          myZipFile.Free;
          DecompressionStream.Free;
        end;
      end;
    end;
    Le nom du fichier est bien trouvé, le tZipHeader me retourne bien un nombre d'octets décompressés et compressés cohérents, mais Memo1.Lines.LoadFromStream(DecompressionStream); me retourne systématiquement le défaut "DataError".
    Suis-je en erreur sur la lecture du fichier, le décryptage (j'ai moi même crypté le fichier, donc pas de doute sur le Password) ou sur le transfert du tStream vers le tMemo ?
    Merci pour votre aide.
    Belle journée à tous.
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 429
    Points : 24 794
    Points
    24 794
    Par défaut
    TEncryptedZipFile c'est une lib externe ?
    Ou c'est juste la modification que tu mentionnes via un héritage de TZipFile ?

    On avait discuté qu'une version de Delphi avait ajouté une optimisation mal gaulée dans le CopyFrom, vérifie déjà si tu es concerné par cet ajout mal codé, normalement sans impact mais particulièrement pénible en débogage sur un grand nombre de fichier.

    Si oui,
    Tu es bon pour patcher manuellement les fonctions tel que LoadFromStream si tu as juste une Notification d'Exception, cela évitera l'inconfort en débogage et au passage cela évite quelques lignes de code inutile pour gérer l'optimisation que ne peut pas se faire, c'est patcher en 11.1 pour gérer ce cas de l'optimisation sur les stream compressés, à vérifier

    Si non,
    Autre piste à creuser



    Si le code de TEncryptedZipFile est celui-ci alors normalement, un password incorrect devrait bien planter sur la lecture du Header, si tu as le nom du fichier, c'est signe à mon avis que tu as bien mis le mot de passe.

    As-tu bien récupéré tout le code de TEncryptedZipFile qui gère la différence entre D10 et D11 (non patché) ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    attention, il y a un second article avec un source modifié ici, par ailleurs si tu utilises la dernière version de Delphi, TZipFile a été modifié, je ne sais pas s'il est encore compatible.

    il y a même une version 3

    voici un code qui fonctionne avec la version 3

    Attention, un Memo1.Lines.LoadFromStream(S) provoque une erreur, il vaut mieux passer par S.Read() directement car le LoadFromStream calcule la taille du flux et cela provoque des erreur sur un flux compressé et crypté: Seek(End) puis Seek(0)

    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
     
    uses
      System.Zip,
      uEncryptedZipFile;
     
    {$IFOPT Q+} Veuillez désactiver la vérification des débordements {$ENDIF}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Z: TEncryptedZipFile;
      S: TStream;
      H: TZipHeader;
      B: TBytes;
    begin
      Z := TEncryptedZipFile.Create('1234');
      Z.Open('..\..\uEncryptedZipFile.zip', TZipMode.zmRead);
      Z.Read(0, S, H);
      SetLength(B, H.UncompressedSize);
      S.Read(B, H.UncompressedSize);
      S.Free;
      Memo1.Lines.Text := TEncoding.ANSI.GetString(B);
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Merci à tous les 2

    J'avais bien testé avec la dernière version proposée (Part3). Pas d'exception déclenchée seulement une fenêtre 'DataError'.

    Le code proposé par Paul fonctionne parfaitement. Il me reste à comprendre le pourquoi du comment avec le LoadFromStream.
    dans tous les cas, merci à vous 2.
    Belle journée,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    note aussi que dans la dernière version tu as le support ZIP64 avec UncompressedSize64 pour les très gros fichiers
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Merci Paul pour cette précision.
    Je tombe effectivement sur un autre défaut qui doit bien être lié à un problème de capacité.

    Mon fichier Zippé contient au final, plusieurs fichiers. En changeant le premier paramètre du Read, je lis bien le contenu du bon fichier...à condition qu'il soit dans les premiers :

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      myZipFile:                   TEncryptedZipFile;
      DecompStream:                TStream;
      HeadZip:                     TZipHeader;
      myBytes:                     TBytes;
      tListFile:                   tStringList;
      sPrgTmp:                     String;
      nIdx, nCptComp, nCptUncComp: Integer;
    begin
      Memo1.Clear;
      nCptComp := 0;
      nCptUncComp := 0;
      tListFile := tStringList.Create;
      ZipListPrg(sFileName, tListFile); { Lecture Liste de fichier dans le Zip }
     
      if tListFile.Count > 0 then
      begin
        myZipFile := TEncryptedZipFile.Create(sPassword);
        myZipFile.Open(sFileName, TZipMode.zmRead);
     
        for nIdx := 0 to tListFile.Count - 1 do
        begin
          // Read Zip component
          myZipFile.Read(nIdx, DecompStream, HeadZip);
     
          Memo1.Lines.Add('-------------------------');
          Memo1.Lines.Add(tListFile[nIdx] + '(' + intToStr(nIdx) + ')');
     
          Memo1.Lines.Add('CompressedSize : ' + intToStr(HeadZip.CompressedSize));
          nCptComp := nCptComp + HeadZip.CompressedSize;
          Memo1.Lines.Add('Total : ' + intToStr(nCptComp));
     
          Memo1.Lines.Add('UncompressedSize : ' + intToStr(HeadZip.UncompressedSize));
          nCptUncComp := nCptUncComp + HeadZip.UncompressedSize;
          Memo1.Lines.Add('Total : ' + intToStr(nCptUncComp));
          Memo1.Lines.Add('-------------------------');
     
          // Load Stream
          SetLength(myBytes, HeadZip.UncompressedSize);
     
          DecompStream.Read(myBytes, HeadZip.UncompressedSize);
     
          Memo1.Lines.Add(TEncoding.ANSI.GetString(myBytes));
        end;
      end;
     
      DecompStream.Free;
      tListFile.Free;
    end;
    Au 22eme fichier interne
    -------------------------
    xxxx(22)
    CompressedSize : 587
    Total : 13382
    UncompressedSize : 1434
    Total : 37756
    -------------------------

    Puis le défaut : Erreur de lecture de Flux !

    Je pensais que la taille maxi du tStream était de 2^32 octets (J'en suis loin).
    Cordialement,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    attention, ton DecompStream.Free; est en dehors de la boucle, hors la méthode Read() crée une instance de TStream à chaque fois, il faut donc la détruire à chaque fois (après usage)
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    attention, ton DecompStream.Free; est en dehors de la boucle, hors la méthode Read() crée une instance de TStream à chaque fois, il faut donc la détruire à chaque fois (après usage)
    Oui, comme je pense que c'est le Stream qui me pose problème, j'avais essayé de le retirer de la boucle pour faire le test.
    En le remettant à sa place, j'ai toujours le même problème.

    En remplaçant DecompStream.Read par DecompStream.Read64, même problème.
    La valeur de DecompStream.Position est toujours identique à HeadZip.CompressedSize.
    Si je tente d'afficher DecompStream.Size, je provoque un défaut 'DataError'

    Si vous avez une idée...
    Merci par avance
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  9. #9
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Galet Voir le message
    Oui, comme je pense que c'est le Stream qui me pose problème, j'avais essayé de le retirer de la boucle pour faire le test.
    En le remettant à sa place, j'ai toujours le même problème.

    En remplaçant DecompStream.Read par DecompStream.Read64, même problème.
    La valeur de DecompStream.Position est toujours identique à HeadZip.CompressedSize.
    Si je tente d'afficher DecompStream.Size, je provoque un défaut 'DataError'

    Si vous avez une idée...
    Merci par avance
    attention, sur les ZIP, le Stream peut être un peu n'importe quoi, un sous stream du ZIP (stored) un stream compressé, et même un stream crypté...sur ce genre de Stream il ne faut pas se fier aux propriétés Size et Position, car elles peuvent donner des choses incohérentes en apparence, voir provoquer des erreurs. Le TZipHeader est là pour donner les caractéristiques du fichier, pas le stream.

    pour le Read64 ce n'est utilise que pour un stream dont la taille dépasse 32bits

    Est-ce que ton ZIP est validé par 7Zip par exemple ?

    Est-ce que ton ZIP est confidentiel, car je suppose qu'il a une particularité sur son 22 ième élément qui fait que ça plante...en mode debug que pointe Delphi ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Merci Paul pour ton aide.

    En mode debug, lorsque je visualise la variable myZipFile/tZipFile/FFiles/FItems, je peux voir tous les headers (1 par fichier).
    Je n'ai aucune info sur le Stream (DecompStream) qui reste visuellement vide.

    J'ai tenté de faire un zip uniquement avec ce fichier et le programme fonctionne bien.
    7Zip compresse ou décompresse très bien le fichier.
    Tous les fichiers sont des fichiers Texte (xml) qui n'ont rien de particulier. Pas de confidentialité particulière pour que je te transmette le fichier en question.
    Si je supprime ce fichier du Zip, le défaut apparait sur le fichier d'après ce qui me laisse à penser qu'un s'agit bien d'un dépassement de capacité.

    Dans le programme, si je supprime l'affichage du fichier en ne faisant apparaitre que les infos de nom et de taille zippé et non zippé des fichiers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //      setLength(myBytes, HeadZip.UncompressedSize);
    //      DecompStream.Read64(myBytes, 0, HeadZip.UncompressedSize);
    je retrouve bien la liste de tous les fichiers avec les infos cohérentes.


    En debug, l'application plante (Erreur de lecture du flux) sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Result := Result + Read(Buffer[Offset], Count);
    avec Offset=0 et Count 1434 (qui est bien la taille du fichier)

    de (System.classes/tStream.read64, ligne 14) :
    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
     
    function TStream.Read64(Buffer: TBytes; Offset, Count: Int64): Int64;
    const
      BUKETSIZE = $20000000; // 512M
    begin
      Result := 0;
      while Count >= BUKETSIZE do
      begin
        Result := Result + Read(Buffer[Offset], BUKETSIZE);
        Inc(Offset, BUKETSIZE);
        Dec(Count, BUKETSIZE);
      end;
      if Count > 0 then
        Result := Result + Read(Buffer[Offset], Count);
    end;
    Je continue à chercher...
    Cordialement,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  11. #11
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Bonjour à Tous,

    @Paul : Je suis hors de mon bureau avec une connexion limitée (et filtrée par mon client) sans accès aux MP. Je traite dès mon retour. Merci dans tous les cas.

    Après nombreux Tests, un code qui fonctionne en supprimant l'exception :
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      myZipFile:                   TEncryptedZipFile;
      DecompStream:                TStream;
      HeadZip:                     TZipHeader;
      myBytes:                     TBytes;
      tListFile:                   tStringList;
      nIdx, nCptComp, nCptUncComp: Integer;
    begin
      Memo1.Clear;
      nCptComp := 0;
      nCptUncComp := 0;
      tListFile := tStringList.Create;
      ZipListPrg(sFileName, tListFile); { List of Include Files in Zip }
     
      if tListFile.Count > 0 then
      begin
        myZipFile := TEncryptedZipFile.Create(sPassword);
        myZipFile.Open(sFileName, TZipMode.zmRead);
     
        for nIdx := 0 to tListFile.Count - 1 do
        begin
          // Read Zip include Files
          myZipFile.Read(nIdx, DecompStream, HeadZip);
     
          Memo1.Lines.Add('-------------------------');
          Memo1.Lines.Add(tListFile[nIdx] + '(' + intToStr(nIdx) + ')');
     
          nCptComp := nCptComp + HeadZip.CompressedSize;
          Memo1.Lines.Add('CompressedSize : ' + intToStr(HeadZip.CompressedSize) + '/ Total : ' + intToStr(nCptComp));
     
          nCptUncComp := nCptUncComp + HeadZip.UncompressedSize;
          Memo1.Lines.Add('UncompressedSize : ' + intToStr(HeadZip.UncompressedSize) + '/ Total : ' +
            intToStr(nCptUncComp));
          Memo1.Lines.Add('-------------------------');
     
          // Load Stream
          setLength(myBytes, HeadZip.UncompressedSize);
          try
            DecompStream.Read(myBytes, 0, HeadZip.UncompressedSize);
          except
            on EReadError do
              //ShowMessage('Read Error !!');
          end;
          DecompStream.Free;
     
          Memo1.Lines.Add(TEncoding.UTF8.GetString(myBytes));
        end;
      end;
      tListFile.Free;
    end;
    Le défaut est provoqué par la conversion du dernier caractère. Ainsi, en ne traitant que 'HeadZip.UncompressedSize-1' alors plus de problème...mais il manque le dernier caractère évidemment ...

    Suite et fin, après de nouveaux tests...
    Belle journée à tous,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  12. #12
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    tient je viens de voir qu'il y a plus simple avec un appel direct à myZipFile.Read(nIdx, myBytes);...mais en toute logique ça ne devrait pas corriger ton problème, ça simplifie juste le code avec en plus une vérification du CRC32
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    ok, j'ai pu regarder ton ZIP

    il y a un bug en effet et c'est dans uEncryptedZipFile

    dans System.ZLib, la méthode TZDecompressionStream.Read() peut lire le fichier source au delà de la fin des données compressées, car la source est lue par bloc de $ffff octets, du coup en fin de décompression, si on a lu trop de données, le flux est repositionné à la fin réelle des données. ça n'a aucun intérêt pour l'extraction ZIP mais dans un autre contexte cela pourrait être nécessaire.

    Alors, c'est supposé être géré par TDecryptStream.Seek mais pour une raison qui m'échappe ça ne fonctionne pas...mais pas de panique, il y a moyen de corriger le problème de façon plus judicieuse

    1) dans TDecryptStream j'ajoute un member FMaxRead
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      TDecryptStream = class(TCryptStream)
      protected
        FMaxRead: Int64;
    2) sa valeur est fixée dans InitHeader
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    procedure TDecryptStream.InitHeader;
    //...
    begin
      FMaxRead := Stream.Position + ZipHeader.CompressedSize;
    ...
    3) on s'assure de ne jamais lire au delà de la fin du flux compressé (qui se trouve à l'intérieur du ZIP)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function TDecryptStream.Read(var Buffer; Count: Integer): Integer;
    var
      P: PByte;
      I: Integer;
    begin
      I := FStream.Position + Count;
      if I > FMaxRead then
        Dec(Count, I - FMaxRead);
    ...
    bon, ça m'agace un peu de ne pas avoir compris pourquoi ça ne fonctionne pas (je pense qu'il y a confusion entre la position relative au début du flux compressé et la position absolue dans le fichier ZIP), mais ce correctif corrige le problème tout en étant plus logique, donc je m'en remettrais
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  14. #14
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    bon, ça m'agace un peu de ne pas avoir compris pourquoi ça ne fonctionne pas (je pense qu'il y a confusion entre la position relative au début du flux compressé et la position absolue dans le fichier ZIP), mais ce correctif corrige le problème tout en étant plus logique, donc je m'en remettrais
    Bon, quelque part, ça me rassure...de ne pas avoir trouvé le défaut...

    Je vais mettre tout ça dans mon code, histoire de mettre à disposition la solution finale et clore le sujet.
    Il faut que je teste aussi la décompression d'un sous-répertoire...
    Belle journée...
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  15. #15
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Bonjour à tous,

    Pour clore le sujet, voici le résultat des tests de décryptage de fichier Zip (VCL / 7Zip, chiffrement ZipCrypto) pour ceux qui en auraient l'utilité.
    Les modifications proposées par Paul sont intégrées.

    TestZip.zip

    Sources :
    https://www.uweraabe.de/Blog/2017/05...yption-part-3/
    Avec l'aide de Paul Toth

    Je vais, à présent, pouvoir l'inclure dans mon projet
    Belle journée à tous,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 021
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 021
    Points : 40 935
    Points
    40 935
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    je viens mais un peu tard pour signaler que des coorections ont été faites pour D11 à cause d'un problème sur TZCompressionStream.GetSize
    à retrouver ici https://github.com/UweRaabe/EncryptedZipFile
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  17. #17
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 429
    Points : 24 794
    Points
    24 794
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    je viens mais un peu tard pour signaler que des coorections ont été faites pour D11 à cause d'un problème sur TZCompressionStream.GetSize
    à retrouver ici https://github.com/UweRaabe/EncryptedZipFile
    Citation Envoyé par ShaiLeTroll Voir le message
    As-tu bien récupéré tout le code de TEncryptedZipFile qui gère la différence entre D10 et D11 (non patché) ?
    Normalement, depuis le début du sujet, la version est celle du "Feb 24, 2022", j'espère que c'était bien celle que l'on évoque tous les deux.

    UInt64 au lieu de Int64;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        FKey: array [0 .. 2] of UInt64;
    et dans CalcDecryptByte, idem

    avec TExtZCompressionStream au lieu de TZCompressionStream


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      TExtZCompressionStream = class(TZCompressionStream)
      protected
        function GetSize: Int64; override;
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        compressionStream := TExtZCompressionStream.Create(encryptStream, zcDefault, -15);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function TExtZCompressionStream.GetSize: Int64;
    begin
      Result := -1;
    end;

    Toujours ce Size !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  18. #18
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 483
    Points
    483
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Bonjour,

    je viens mais un peu tard pour signaler que des coorections ont été faites pour D11 à cause d'un problème sur TZCompressionStream.GetSize
    à retrouver ici https://github.com/UweRaabe/EncryptedZipFile
    Merci à tous les 2...pour que le sujet soit le plus complet.
    Le petit projet de test est en 10.2.3 (Tokyo), les modifications effectuées par Uwe Raabe ne sont donc pas implémentées.

    Belle soirée...
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

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

Discussions similaires

  1. Zipfile : lecture ok, écriture plantée
    Par AgriPacTe dans le forum Général Python
    Réponses: 3
    Dernier message: 26/11/2019, 09h57
  2. Lecture d'une vidéo "cryptée"
    Par exyacc dans le forum Débuter
    Réponses: 9
    Dernier message: 07/12/2016, 11h56
  3. Pb Lecture de bitmap monochrome
    Par Loïc38 dans le forum C++Builder
    Réponses: 4
    Dernier message: 02/07/2002, 19h24
  4. Lecture d'une image bitmap
    Par Geronimo dans le forum x86 32-bits / 64-bits
    Réponses: 18
    Dernier message: 28/06/2002, 13h01
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 11h24

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