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 :

Ecriture et lecture des ressources sur une .exe


Sujet :

Delphi

  1. #1
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 4
    Points
    4
    Par défaut Ecriture et lecture des ressources sur une .exe
    Salut,

    J'ai creé un programme qui doit etre modifié ulterieurement pour inclure des nouveau fichiers.
    En cherchant dans le forum, je décide que la meilleure solution est d'employer les ressources, quelques fonctions ont ete fournis ...

    donc, pour l'editeur j'emploie :
    *BeginUpdateResource
    *UpdateResource
    *EndUpdateResource

    tout semble bien fonctionner puisque le fichier exe cible change de taille ...

    Coté programme cible, j'ai essayé 2 methodes qui aboutissent au meme resultat : ressource introuvable
    *Méthode 1 avec le constructeur de la classe TResourceStream
    *Méthode 2 en employant les API :FindResource, LoadResource et LockResource.

    J'ai déja employé les ressources, mais en utilisant les fichiers .RES et l'ajout de directive {$R fichier.res}, et tout etait dans l'ordre, donc je pense que le probleme vient de l'éditeur.

    Voici le code de l'éditeur :

    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
    function AddFile(SrcFile, DestFile, ResName: String): Boolean;
    Var
      DestHandle: Integer;
      ResStream: TMemoryStream;
    begin
      Result := False;
     
      DestHandle := BeginUpdateResource(PChar(DestFile), False);
      If DestHandle = 0 then
        Raise Exception.Create('Erreur de lecture de :'+DestFile);
     
      ResStream := TMemoryStream.Create;
      Try
        ResStream.LoadFromFile(SrcFile);
        if not UpdateResource(DestHandle, RT_RCDATA, PChar(ResName), 0,
                 ResStream.Memory, ResStream.Size)  then
          Begin
            EndUpdateResource(DestHandle, True);
            Raise Exception.Create('Error while adding the resource');
          End;
        EndUpdateResource(DestHandle, False);
        Result := True;
      Finally
        ResStream.Free;
      End;
    end;

  2. #2
    Candidat au Club
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Comme je n'ai pas encore eu des réponses, j'ai décidé de chercher une solution alternative, surtout que je me suis rendu compte que les API que j'ai employé au debut ne sont pas disponibles pour W98.

    Donc, au lieu de d'employer les ressources, j'ai passé à l'écriture directe sur le fichier exe, cela ne semble pas poser aucune problème puisque l'écriture se fait a la fin de fichier. D'ailleurs c'est cette méthode qui est utilisée par Inno Setup ....

    Pour ceux qui sont interressés, voici un code qui permet, d'écrire et de lire un message text sur un fichier exe. Biensur, vous n'etes pas limités aux chaines de characteres, vous pouvez aussi inclure des fichiers entiers....

    Le principe est le suivant: le message est ecrit a la fin du fichier, il est suivit par un mot qui doit etre reconnue pendant la lecture (j'ai choisi 'DATA') , enfin, le longeur de message initial (Cardinal) ecrit sur 4 octets.

    Le fichier exe (modifié ou non) va essayer de lire 4 octets(longeur de 'DATA') parmis les 8 derniers octets presents sur le fichier pour verifier si un message a ete ajouté ou non, si oui, il utilise le longeur (lu sur les derniers 4 octets) pour lire le message complet.

    Voici le code de l'éditeur:
    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
     
    function AddMsg(AFile, Msg: String): Boolean;
    Var
      FileH: THandle;
      FPos: Cardinal;
      MsgLength: Integer;
      Buffer : Array [1..255] of Char;
    begin
      Result := False;
     
      FileH:=CreateFile(PChar(AFile),Generic_READ or GENERIC_WRITE,
                        0,0,OPEN_EXISTING,0,0);
      If FileH = INVALID_HANDLE_VALUE then
        Exit;
     
      Try
        FPos:=SetFilePointer(FileH,0,0,FILE_END);
        MsgLength := Length(Msg);
        StrPCopy(@Buffer, Msg+'DATA');
        WriteFile(FileH, Buffer, MsgLength+4, FPos, 0);
        WriteFile(FileH, MsgLength, 4, FPos,0);
        Result := True;
      Finally
        FileClose(FileH);
      End;
    end;
    et le code inclu dans le fichier exe a modifier :
    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
     
    function ExtractMsg: String;
    var
      FileH: THandle;
      FPos:Cardinal;
      Buffer:array[1..255] of char;
      Msg:string;
      MsgLength, I: Integer;
    begin
      Result :='';
      FileH:= CreateFile(PChar(Application.ExeName),Generic_READ,FILE_SHARE_READ,0,
                          OPEN_EXISTING,0,0);
     
      If FileH = INVALID_HANDLE_VALUE then
        Exit;
     
      Try
        FPos := SetFilePointer(FileH,-8,0,FILE_END);
        ReadFile(FileH, Buffer, 4, FPos, 0);
        If StrlComp(@(Buffer[1]), PChar('DATA'), 4) = 0 then
        Begin
          ReadFile(FileH, MsgLength, 4, FPos, 0);
          FPos := SetFilePointer(FileH,-(8+MsgLength),0,FILE_END);
          ReadFile(FileH, Buffer, MsgLength, FPos, 0);
          SetLength(Msg, MsgLength);
          For I:=1 To MsgLength do
            Msg[I] := Buffer[I];
          Result := Msg;
        End;
      Finally
        FileClose(FileH);
      End;
    end;
    Pour la méthode des ressources, je cherche encore une solution ...
    Merci ...

  3. #3
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Salut! Cela me rappelle une démo que j'avais codé il ya quelques temps déjà où le programme sauvegardait son propre message dans l'EXE en faisant une copie de lui-même avant de se supprimer...
    Citation Envoyé par LeRoi
    Pour la méthode des ressources, je cherche encore une solution ...
    Merci ...
    A mon avis, c'est peine perdue. Même des programmes complets comme "ResHacker" ne sont pas capables de modifier les ressources d'un EXE... En fait, ça revient à faire du hacking, je crois que ce n'est pas possible sans déssasembler le programme, séparer les données du code, et réadresser le tout correctement une fois les données modifiées... tout ça en assembleur; Un vrai casse tête.

    Par contre, il est possible de charger un programme avec un fichier de ressources si le programme est prévu pour pouvoir le faire. C'est ce que j'ai programmé hier justement. La fonction utilisée est WriteComponent pour enregistrer un composant dans un fichier et ReadComponent pour le restituer. Ainsi, le programme peut être modulable. Voici une démo, à+

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 396
    Points : 640
    Points
    640
    Par défaut
    il y a un très bon article avec des sources à lire la dessus sur http://www.delphidabbler.com/articles?article=7 (les autres articles sont aussi intéressants)

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Citation Envoyé par LeRoi
    Pour la méthode des ressources, je cherche encore une solution ...
    J'ai essayé ton code avec la méthode des ressources,
    et il fonctionne très bien...seulement,
    et j'ai eu les mêmes problèmes que toi lorsque j'ai utilisé un nom
    de ressource contenant des lettres minuscules...

    À ce moment, la nouvelle donnée est ajouté dans les ressources
    et elle porte bien le nom spécifié mais est inaccessible via
    l'API FindResource()...

    Avec un nom de ressource en lettre MAJUSCULE... tout va bien.
    UpperCase est donc ton ami!

  6. #6
    Membre expert
    Avatar de Bestiol
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 515
    Points : 3 894
    Points
    3 894
    Par défaut
    Citation Envoyé par Sub0
    Même des programmes complets comme "ResHacker" ne sont pas capables de modifier les ressources d'un EXE... En fait, ça revient à faire du hacking, je crois que ce n'est pas possible sans déssasembler le programme, séparer les données du code, et réadresser le tout correctement une fois les données modifiées... tout ça en assembleur; Un vrai casse tête.
    Désolé Sub0 mais je dois te contredire
    ResHacker permet tout à fait de modifier les ressources d'un EXE et, si on prend le temps de faire les choses correctement, le casse-tête n'est pas si difficile à résoudre !
    Et pas besoin d'assembleur pour faire ça... Il faut "juste" savoir quoi modifier

    Je vais essayer de regarder cela de plus près, histoire de ne pas parler "dans le vent" ^^

    @+
    Bestiol.

    ps: pour un autre exemple de l'ajout de fichiers en fin d'EXE, j'avais fait une source qui utilise cette méthode :
    Compression SFX avec zLib

  7. #7
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Tu peux donc prendre n'importe quel programme compilé et modifier le texte, les images, l'icône, bref, te l'approprier très facilement alors, non ? Cela doit être possible si l'on conserve le format et les dimensions des ressources en effet...

  8. #8
    Membre expert
    Avatar de Bestiol
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 515
    Points : 3 894
    Points
    3 894
    Par défaut
    C'est effectivement le cas
    Je m'étais amusé, une fois, à modifier quelques ressources de Explorer.exe

    Si le programme est bien fait (et c'est le cas de ResHacker je pense ^^) il n'y a pas besoin de conserver la taille des ressources originales : la mise à jour de quelques champs dans les entêtes du fichier PE permettent de mettre à jour la nouvelle taille des ressources modifiées.

  9. #9
    Membre expert
    Avatar de Bestiol
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 515
    Points : 3 894
    Points
    3 894
    Par défaut
    Bon en me baladant sur les docs de UpdateResource etc. j'ai "un peu" dérivé et fait une source montrant comment modifier l'icône principale d'un exe. En gros donc, comment modifier l'icône affichée par Windows pour un exécutable

    Voir la pièce jointe

    @+ !
    Olivier

    ps: ResHacker est codé en Delphi
    Fichiers attachés Fichiers attachés

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/09/2007, 08h59
  2. [Resource] Lecture des ressources dans une classe
    Par Mister Nono dans le forum Struts 1
    Réponses: 3
    Dernier message: 09/03/2007, 10h59
  3. Recupération des selections sur une DBGrille multi Selection
    Par Andry dans le forum Bases de données
    Réponses: 1
    Dernier message: 26/11/2004, 11h43
  4. Réponses: 2
    Dernier message: 09/02/2004, 08h17

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