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 :

Extraction image contenue dans un .exe


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 23
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Extraction image contenue dans un .exe
    Bonjour à tous,

    Je souhaite créer un exécutable en C qui, lorsque vous l'exécuter, irait "extraire" une image contenue dans l'exe et placer l'image dans le même répertoire que l'exécutable.

    Par exemple :
    Imaginons que mon programme, extraction.exe, se trouve à l'emplacement D:\test. Aucun autre fichier autre que extraction.exe ne se trouve à cet emplacement. L'image "fondEcran.jpg" est compilée dans mon programme extraction.exe. Lors de l'exécution, l'image fondEcran.jpg sera créée dans D:\test et sera lisible par mon ordinateur.

    J'ai pensé à deux solutions, mais je suis totalement perdu sur la façon de procéder :

    Première méthode : ouvrir un fichier avec l'option "wb" et utiliser fwrite pour coller les données binaires de mon image. (via notepad++ par exemple il est possible de faire un copier spécial dans les options pour une copie binaire de l'image).
    Mon problème : Je pense que je ne comprends pas le fonctionnement de fwrite. Je ne sais pas quoi mettre dans mon fwrite. Enfin, je sais que je dois mettre les données binaires, mais je ne comprends pas comment...

    Deuxième option : Inclure mon image lors de la compilation via un fichier .rc. Et faire appel à ce .rc pour extraire l'image lors de l'exécution du programme.

    La deuxième option me parait plus propre (si c'est possible) mais les seuls tutoriels que je trouve pour l'utilisation des .rc, sont les tutos pour ajouter une icône personnalisée à l'exécutable...

    J'ai commencé la programmation C, il y a un peu plus de 8 mois maintenant. Je suis donc débutante. Excusez-moi d'avance si une solution simple existe.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Il me semble que les fichiers ressources .rc ne sont que pour Windows.
    Tu peux mettre tout ce que tu veux dans les ressources (images, icônes, des menus, des "forms", ...) De plus les IDE font le travail à ta place : il créé le fichier .rc et place les fichiers dans l'exécutable.
    Donc il faut se renseigner sur ton IDE ... à moins que tu fasses à la main (de souvenirs, il te faut dans ce cas 1 compilateur ressource comme rc.exe)

    Ensuite, tu as 1 logiciel qui permet d'extraire toutes les ressources embarquées : Resource Hacker (ResHack).

    Et pour moi ta façon de faire est mauvaise et non portable ouvrir 1 exécutable avec fopen me semble très incertain

    Je pense que la meilleure façon de faire, c'est de créer 1 "module" dans ton exécutable qui extraie les ressources et les place où tu veux, au moyen de bascules : par exemple "mon_exe -res "img1" -where "C:\XXX""
    Après, ce "module" sera très spécifique à Windows et très facile à coder : charger 1 ressource, ouvrir le dossier demandé ou celui par défaut, et écrire en recopiant la ressource en binaire.

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 23
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Je ne souhaite pas utiliser de logiciel tierce. Je souhaite que mon application puisse extraire elle même l'image qui est compilée en elle.

    Finalement un peu (voir beaucoup) ce que fait un installer d'un programme sous windows. vous lancer l'installation et il va extraire et créer les fichiers binaires ou non à l'endroit de l'installation.

    J'ai trouvé ce lien qui explique exactement ce que je veux faire mais en C++ (et je ne suis pas encore sur l'apprentissage de ce language) et avec l'extraction d'un .exe et non d'une image mais j'imagine que c'est la même démarche.

    lien : https://geeks.ms/rfog/2008/09/11/c-i...go-ejecutarlo/

    C'est en espagnol en revanche

    Ils utilisent bien le .rc pour intégrer la ressource. mais c'est sur l'étape 2 que je n'y comprend plus rien vu que c'est du C++...

    Je précise que le programme ne fonctionnera que sur Windows. C'est pour mon apprentissage perso, le programme n'a pas vocation à avoir une utilité à la fin. Je me suis demandé comment les installer faisaient pour extraire les fichiers d'eux même lors d'une installation. Je cherche donc à faire mon "installer" maison avec une image.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Du C++ comme tu utilises la WinApi/ Win32 qui est obsolète depuis 15 - 20 ans, cette bibliothèque est écrite en C.
    Et d'ailleurs, le bout de code c'est du C, rien en C++ (même s'il compile en C++ puisque ce dernier est 1 surcouche du C)

    Et sinon, il n'y a rien de mystérieux c'est la fonction FindResourceA qui fait le travail (<- documentation Microsoft en anglais)
    Le bout de code te montre comment coder proprement, parce qu'il faut utiliser les fonctions LoadResource puis LockResource.

    Après que dire de + : c'est du code Microsoft C avec des handles, des LPCSTR, ... et toutes les joyeusetés de la bibliothèque WinApi.
    Pour 1 débutante cela doit rester très déstabilisant ... il faut connaître par cœur, les pointeurs, les casts, les tableaux de caractères et l'encodage MBCS - Unicode, ... et sûrement même des trucs crades comme mettre 1 pointeur dans 1 entier (qui n'est plus portable en x64)

    Et comme je l'ai dit , embarquer des ressources à la main, sans l'aide de l'IDE, cela prend du temps à maitriser (il y a la notion de chemin, de compilateur de ressources, la syntaxe des fichiers .rc, ...)

  5. #5
    Membre éprouvé
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 420
    Points : 1 102
    Points
    1 102
    Par défaut
    Bonjour,

    Tu peux aller voir par là Writing custom data to executable files in Windows and Linux.

    Cependant attention sous Windows, le répertoire de ton exécutable placé dans les program files est interdit en écriture à presque tout le monde... Tu risques d'voir du mal à y mettre ton image.

    Cordialement

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par acaumes Voir le message
    Tu peux aller voir par là Writing custom data to executable files in Windows and Linux.

    Cependant attention sous Windows, le répertoire de ton exécutable placé dans les program files est interdit en écriture à presque tout le monde... Tu risques d'voir du mal à y mettre ton image.
    Je ne pense pas que ce n'est pas la bonne façon de faire écrire ces données en fin d'exécutable, et mettre à jour la taille de l'exécutable (<- si j'ai bien tout compris)

    Le truc le + simple pour moi c'est de faire le truc à l'ancienne et à l'envers :
    • mettre les ressources dans le code source avec des #define, en base64 si c'est du binaire, ou en remplissant des tableaux. Après, ces techniques ne sont pas super loin de là. Peut-être coder des moulinettes pour générer ses fichiers.
    • faire que ce soit l'exécutable lui même qui fasse l'extraction. Tout se fait avec la librairie standard.


    J'ai vu d'1 œil que sous Linux c'est + ou - cette technique en utilisant la commande objcopy objcopy --input binary --output elf32-i386 --binary-architecture i386 data.txt data.o, par exemple, pour transformer 1 fichier texte data.txt en fichier .o et en y ajoutant des macros pour récupérer ce qu'il y a dans le fichier.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par mimigeny Voir le message
    Je souhaite créer un exécutable en C qui, lorsque vous l'exécuter, irait "extraire" une image contenue dans l'exe et placer l'image dans le même répertoire que l'exécutable.
    Premier problème: qu'est-ce qui prouve que le "exe" contient une image
    Second problème: si cette image est présente, où est-elle et quelle est sa taille? (et ça ça dépend de la façon dont l'image a été encodée par le créateur de l'exe)

    Citation Envoyé par mimigeny Voir le message
    Mon problème : Je pense que je ne comprends pas le fonctionnement de fwrite. Je ne sais pas quoi mettre dans mon fwrite. Enfin, je sais que je dois mettre les données binaires, mais je ne comprends pas comment...
    Pas très compliqué: il faut bien avoir conscience que fwrite est fait pour écrire des données binaires. Et que (en C) qui dit "données" (au pluriel) doit dire alors "pointeur" (adresse) pointant vers l'endroit où ces données commencent en mémoire + taille de la donnée (parce que si la donnée c'est du char (1 octet) ce ne sera pas la même chose que du float (4 octets) + nb de données (car c'est au pluriel donc il y en a plusieurs). D'où la signature de fwrite qui est pointeur + taille (sous-entendu "d'un élément") + nb (d'éléments) + fichier où écrire
    Exemple: je veux écrire char tab[]="Hello" dans le fichier => fwrite(tab, sizeof(char), 5, fichier).
    Autre exemple : je veux écrire float tab[]={1, 2, 3, 4, 5} dans le fichier => fwrite(tab, sizeof(float), 5, fichier) => comme quoi ça ne change pas vraiment
    Peut-être que ce qui te gêne, c'est que le fichier généré ne soit pas lisible par un éditeur texte (style notepad++) => hé oui, c'est le propre des fichiers binaires, on ne peut pas les lire comme des fichiers textes car ce n'en sont pas (on nomme ces fichiers lisibles par un bloc note des fichiers "human readable"). Mais faut faire confiance à ton programme. Si tu les écris correctement en binaire, tu pourras alors les lire en binaire sans souci. Après-tout, tu ne peux pas ouvrir un mp3 avec notepad++ mais ça n'empêche pas ton lecteur de musique de l'ouvrir, lui. Donc si je sais que mon fichier contient 5 char ("Hello") alors me suffit de lire 5 char pour récupérer le "Hello".

    Citation Envoyé par mimigeny Voir le message
    Deuxième option : Inclure mon image lors de la compilation via un fichier .rc. Et faire appel à ce .rc pour extraire l'image lors de l'exécution du programme.
    Oui mais là je ne comprends pas trop. C'est toi le créateur de l'exe? Dans ce cas, tu as déjà l'image. Pourquoi alors vouloir l'extraire? Ou alors tu veux cacher une image dans un exe déjà existant puis pouvoir la récupérer plus tard (stéganographie) dans ce cas autant récupérer des logiciels déjà tout faits qui font déjà ça et qui fonctionneront bien mieux que ce que tu peux faire avec seulement 8 mois de connaissances.
    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]

  8. #8
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 562
    Points : 1 253
    Points
    1 253
    Par défaut
    Salut,

    Citation Envoyé par foetus Voir le message
    Et sinon, il n'y a rien de mystérieux c'est la fonction FindResourceA qui fait le travail (<- documentation Microsoft en anglais)
    Le bout de code te montre comment coder proprement, parce qu'il faut utiliser les fonctions LoadResource puis LockResource.
    Je viens de le faire:

    ressource.h
    main.rc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include "ressource.h"
    MAIN_C RCDATA "./main.c"
    main.c
    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
    #include "ressource.h"
    #include <stdio.h>
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
     
    int main(void)
    {
        HRSRC handle= FindResourceA(0, MAKEINTRESOURCE(MAIN_C), RT_RCDATA);
        void* address= LockResource(LoadResource(0, handle));
        DWORD size= SizeofResource(0, handle);
     
        FILE* file= fopen("main2.c", "wb");
        fwrite(address, 1, size, file);
        fclose(file);
    }

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par kaitlyn Voir le message
    Je viens de le faire
    pour 1 débutante qui dit "C'est pour mon apprentissage perso, le programme n'a pas vocation à avoir une utilité à la fin", je ne pense pas que ce soit pertinent de passer autant de temps à apprendre 1 bibliothèque aussi vieille, qui date d'avant la normalisation C99 et ultra spécifique Windows.
    Après, tout n'est pas à jeter non plus , comme par exemple l'encodage des caractères et 1 aperçu la programmation générique avec les handles/void*.


    Édit : 1 autre truc simple toi, tu dois avoir Visual C++, tu as créé 1 projet Win32 et ton fichier ressource a été intégré automatiquement.
    Et même peut-être 1 version non gratuite , parce qu'il me semble que Microsoft ne livrait pas la WinApi avec ces versions gratuites.
    Apparemment également, cette bibliothèque et ses outils ont migré dans le module "Windows SDK" depuis 2015.

    C'est d'ailleurs la question de @mimigeny, parce qu'elle ne semble pas avoir Visual C++

    il y a également, Delphi/ C++ Builder qui permet de faire des applications Windows, mais avec 1 surcouche objet comme MFC, ATL (Active Template Library), WTL (Windows Template Library), qui s'appelle VCL (Visual Component Library)

  10. #10
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 562
    Points : 1 253
    Points
    1 253
    Par défaut
    Salut foetus,

    J'ai utilisé mingw64 avec codeblocks, et c'est vrai que tout a été automatique

    En ligne de commande, ça devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    windres main.rc -O coff -o main.res     
    g++ main.c main.res -o main.exe
    Cela dit Win32 ne peut pas disparaître, c'est le coeur de windows, l'api fait même peau neuve : https://github.com/microsoft/win32metadata/, tu confonds avec la MFC peut-être.

    Sinon d'autres possibilités : https://caiorss.github.io/C-Cpp-Note...xecutable.html

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par kaitlyn Voir le message
    Merci, tu synthétises tout ce fil avec ton lien ... mais le problème reste là : sous Windows, il faut passer par l'API Microsoft, sous Linux par des outils externes, et en général, par des "techniques" assez grossières qui ne sont pas idéales (par exemple les gros fichiers).
    Et donc rien pour 1 débutant en C

    Sometimes it is necessary to embed resource such as icons, images, texts or even arbitrary binary data into executables. There several approaches for acomplishing this:

    Windows:
    *) Create a resource script, for instance resource.rc, and compile the resource to object code with the MSVC resource compiler. rc.exe or GCC/Mingw resource compiler, windres.exe. Then build the executable by linking the application object code with the compiled resource.
    *) Functions: FindResource, LoadResource, SizeofResource, LockResource
    *) Icon: On Windows it is the only way to add an icon to an executable.

    Unix-like:
    *) objcopy tool.
    *) ld (GNU ld linker)
    *) Icon: Native executables for MacOSX, Linux and BSD don't support embedded icon as Windows.

    Portable:
    *) Base 64 encoding - Initialize some string global variable with the resource encoded as base64 string. When the resource is needed, the program decode the global variable from base64 to a byte stream, byte array, string or file.

    *) Byte array encoding - The resource is turned into a C++ source code containing the resource encoded as a byte-array. The source is then compiled to object code and added to the application at linking time. This technique is better implemented with an custom external code generator or off-the-shelf tool such as:
    **) image-magick -> Can convert images into a header files containing the image bytes.
    $ convert image.png image1.h

    **) xdd - utility
    $ xxd file.png -i
    $ xxd file.png -i > resourcedata.hpp
    Pour les compilateurs de ressources, Delphi/ C++ Builder a également le sien, BRCC32.EXE, mais de souvenirs, diffère du compilateur officiel Microsoft rc.exe sur quelques points

    Et rajouter que pour certains type de fichiers, il existe des versions ASCII . Par exemple, pour les images tu as les formats Netpbm PPM/ PGM/ PBM/ PNM/ PAM

  12. #12
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 562
    Points : 1 253
    Points
    1 253
    Par défaut
    J'ai regardé vite fait et la solution ultime passe par l'assembleur avec la directive incbin, de base c'est 3 lignes de code. D’ailleurs, C'est ce que semble faire les compilateurs de ressources Windows, en plus d'ajouter un index, d’où la nécessité des API Win32 sus-citées. J'ai fait un test avec GAS sur Windows et ça fonctionne bien. Ainsi, avec NASM et GAS tu couvres 100% des besoins et des systèmes.

Discussions similaires

  1. Extraire les images contenues dans un fichier word
    Par elreybubu dans le forum Delphi
    Réponses: 2
    Dernier message: 25/10/2006, 13h07
  2. Dimension d'un control Image contenu dans une Frame
    Par avigeilpro dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 08/07/2006, 15h55
  3. Compter le nombre d'image contenu dans un <div>
    Par denn dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 13/02/2006, 15h45
  4. Réponses: 6
    Dernier message: 29/07/2005, 11h12
  5. [JAR] instancier une Image contenue dans un jar
    Par celine31 dans le forum Général Java
    Réponses: 3
    Dernier message: 03/04/2005, 15h55

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