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

MFC Discussion :

Executer du code binaire au sein d'un programme


Sujet :

MFC

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut Executer du code binaire au sein d'un programme
    Bonjour,
    j'essaie de faire un petit programme qui charge le binaire d'une dll en mémoire et l'exécute, c'est à dire charge les octets correspondants à une DLL en mémoire, et exécute une fonction de la DLL sans passer par une écriture sur disque.
    Après avoir cherché sur les newsgroups, j'ai trouvé quelques infos intéressantes.

    Seems to me you could use LoadResource() to get the binary resource
    into memory, copy it over to some committed pages allocated with
    VirtualAlloc(), then execute it after changing the protection of the
    pages with the PAGE_EXECUTE_READWRITE flag to VirtualProtect().

    Haven't tried it, but it should work.

    Good luck,
    G. Levand
    Pour ma part, je ne stocke pas cette DLL en ressource mais sous forme d'un tableau d'octets

    unsigned char res[]={0x9B,0xA9,0x80 ........ };
    Ensuite, j'essaie de faire ce que dit le post des News :

    LPVOID addr = VirtualAlloc(NULL, 57484, MEM_COMMIT, NULL);
    PDWORD OldProtect;
    VirtualProtect(addr, 57484, PAGE_EXECUTE_READWRITE, OldProtect);
    memcpy(addr, res, 57484);
    Mais déjà à ce niveau, je plante sur le memcpy.
    Si quelqu'un a une idée...
    Sinon, je n'ai pas trop idée de comment m'y prendre une fois la DLL copiée en mémoire. Je ne pense pas qu'un simple GetProcAddress() fonctionne.

    Merci

    PS : pour info, j'ai lu les autres posts traitant du sujet, et disant que ce n'est pas possible. Mais d'après plusieurs posts sur les newsgroups, c'est bel et bien possible (pas forcément facile, mais possible). En gros je veux juste executer un code binaire en mémoire, en y associant un pointeur de fonction.

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    plutot que d'utiliser memcpy, j'utiliserai plutot WriteProcessMemory

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Ok, ça s'execute sans plantage
    Par contre, comment je peux faire l'equivalent d'un
    mafonc = (typefonc)GetProcAddress(HMODULE ..., "fonc");
    Parce que au point où j'en suis, la DLL est donc présente en mémoire, dans une page, mais elle est pas loadée.
    Merci

    EDIT : Arg, ca s'annonce un peu plus difficile que prévu. Mon pointeur addr renvoyé par VirtualAlloc est NULL....

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    si j'ai bien compris, tu voudrais avoir une dll mais sans avoir de fichier sur le disque ?
    Je ne comprends pas trop le but ni l'interet ?

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Bon, j'ai résolu le pb du addr NULL. Maintenant la DLL est bien copiée.

    En fait, ce que je désire faire, c'est pouvoir executer du code binaire dynamiquement. C'est juste un petit challenge.
    J'ai lu un article sur un système de protection qui executait du code dynamiquement, en l'écrivant puis éxecutant directement en mémoire.
    J'ai donc envie d'essayer de faire pareil pour voir comment ça se passe.

    Donc je présume que l'intéret est avant tout au niveau sécurité.

    PS : si je calcule l'adresse relative de ma fonction (dans la dll) et que j'y ajoute la valeur de addr (la page ou j'ai copié le binaire), je pourrai executer mon code ?

    Merci

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    tu devrais jetter un oeil a cet article sur codeguru ,
    le sujet : injection de code dans un autre process...
    http://www.codeguru.com/Cpp/W-P/system/processesmodules/article.php/c5767/

  7. #7
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    C'est beaucoup plus complexe que ça. Une dll, c'est pas un simple tableau d'opcodes directement exécutables.
    Tu as la liaison dynamique à faire (IAT), et le rebasing, car la dll a été compilée pour être exécutée à une adresse donnée. Si c'est pas possible, faut mettre à jour tout son contenu avec l'adresse utilisée. C'est faisable (puisque Windows le fait), mais laborieux...
    Si tu veux exécuter du code à la volée, oriente toi plutot vers un interpréteur / compilateur embarqué.
    http://www.elasticworld.org/
    Si tu ne veux pas aller jusque là, crée ton propre système sans passer par des dll. Tu alloues de la mémoire exécutable, tu écris les opcodes dedans (tu codes un assembleur donc), et voilà. Sinon t'as pas fini

  8. #8
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Et dans le cas d'un EXE (c'est un simple exemple) ou il s'agit effectivement d'une serie d'opcodes. Comment je peux lancer l'execution en mémoire (apres avoir fait le WriteProcessMemory) ?

    PS : merci farscape pour ton lien, je vais regarder ça

  9. #9
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Voilà l'état actuel des choses :
    Apparement, une fois la DLL chargée en mémoire, il faut que je la lie dynamiquement. Il me faut des connaissances sur les PE file format.
    J'ai trouvé des docs interessantes (rubrique PE tutorials) :
    http://win32assembly.online.fr/tutorials.html
    Dans les tutos, on apprend à récupérer toutes les données, adresses de fonctions, etc...
    Donc dans mon code, je dois également récupérer ces infos, et lier la DLL.
    Voici ce que j'ai trouvé sur les Newsgroups :

    James Brown Jun 3 2003, 7:04 pm show options
    Newsgroups: microsoft.public.win32.programmer.kernel
    From: "James Brown" <PLEASEDONTSPAMjames.bro...@virgin.net> - Find messages by this author
    Date: Tue, 3 Jun 2003 18:04:46 +0100
    Local: Tues, Jun 3 2003 7:04 pm
    Subject: Re: How to load DLL from memory
    Reply to Author | Forward | Print | Individual Message | Show original | Report Abuse

    It is not enough to do LockResource and "load" the DLL from the resource
    section,
    because of the nature of PE files. You need to do several more steps:

    1. Store DLL (a PE file) as resource
    2. Lock the resource (i.e. get pointer to PE header)
    3. Allocate (using VirtualAlloc) enough memory as indicated in
    NtHeader.OptionalHeader.SizeOfImage
    4. Try to allocate this at location ntheader.OptionalHeader.ImageBase - if
    this fails, then just allocate
    anywhere in your address space.
    5. Copy (from resource into newly allocated space) the DLL's PE header (+
    section tables), and
    each section 1-by-1 into the correct places (as described in the PE
    header)
    6. Fix the new PE header to indicate where the module has been loaded
    7. Perform full Base-Relocations - you need to find the base-relocations
    section by looking
    in the data-directory of the PE header.
    8. Fixup the DLL's import table, by looping through it calling
    LoadLibrary/GetProcAddress as
    appropriate
    9. Call the DLL's entry-point with DLL_PROCESS_ATTACH - the signature
    of the DLL entrypoint is BOOL __stdcall DllEntry(PVOID base, DWORD
    dwReason, PVOID reserved)

    10. (Optionally) add the loaded module into the linked-list of inside the
    PEB. Not required.

    That's all you need to do to load a DLL - you can load pretty much any
    system DLL as well using this
    technique. It's not too much work, but you must be familiar with the PE
    format (portable executable)
    in order to get it to work.

    Cheers,
    http://groups.google.com/group/micro...4fe2152876f605

    Raj wrote:
    > What i mean to say is same. While re-writing LoadLibrary,we need to
    > replace NtOpenFilem,NtReadFile... & need to manage with section
    > object.

    NtOpenFile -> CreateFile
    NtReadFile -> ReadFile
    NtClose -> CloseHandle
    section object -> file mapping object

    CreateFileMapping supports the SEC_IMAGE flag, so you could implement
    LoadLibrary like:

    HANDLE file = CreateFile(name_of_dll);
    HANDLE mapping = CreateFileMapping(file, NULL, SEC_IMAGE, 0, 0);
    HMODULE module = (HMODULE) MapViewOfFile(mapping, 0, 0, 0, 0);

    I guess that this is what LoadLibrary is doing internally, except using the
    equivalent NTDLL calls. You're still limited to creating a file mapping
    backed by an on-disk file.

    Guaranteed solution: Read up on the PE format and implement your own loader.
    Or be willing to accept that you'll have to put the DLL on disk.

    --
    Tim Robinson (MVP, Windows SDK)
    http://mobius.sourceforge.net/
    http://groups.google.com/group/micro...f8fcd7aa452915

    Apparement, si j'arrive à construire l'objet Mapping, je pourrai obtenir un HMODULE et travailler sur ma DLL...


    Merci, pour vos remarques commentaires.

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Hidekii
    Et dans le cas d'un EXE (c'est un simple exemple) ou il s'agit effectivement d'une serie d'opcodes. Comment je peux lancer l'execution en mémoire (apres avoir fait le WriteProcessMemory) ?
    Pour un exe c'est pire, car contrairement à une dll, il sera toujours chargé à la même adresse, et est donc compilé pour fonctionné à cette adresse. Un exe n'est pas relogeable. Donc oui c'est une série d'opcodes, mais ils sont conçus pour être exécutés à une adresse de base bien précise.

    Pour ta citation du newsgroup, bon courage pour les étapes 7 et 8.
    Au fait, un HMODULE, c'est rien d'autre que le début en mémoire du fichier PE. Donc si tu alloues un buffer et copies toute ta dll, le HMODULE, c'est l'adresse de ton buffer.
    Dans son exemple il utilise un file mapping pour pas s'embêter à charger la dll en mémoire. Mais elle est chargée depuis le disque (CreateFile...), en tant que fichier autonome. Donc ça t'aide pas beaucoup. Ca correspond à l'étape 3, et honnêtement, c'est insignifiant comparé à ce qui suit.

  11. #11
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    J'ai résolu mon problème et ça fonctionne !!
    Quelqu'un a déjà fait ça :
    http://www.joachim-bauch.de/tutorial...memory.html/en

    Et ca fonctionne. Je reconnais que le mapping est un peu fastidieux (étapes 7 & 8 ), mais c'est faisable
    J'ai relu le code avec l'article de MSDN sur le PE file format, et tout concorde ! C'est exactement ce que je recherchais

    Je vous laisse regarder ça.

    Merci

    PS : apparement pour un EXE, c'est le même schéma : faire un mapping avec relocation des opcodes...

  12. #12
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    La relocation n'est possible que si le fichier PE a été prévu pour. Le problème, d'après mes souvenir, c'est qu'un exe n'ayant aucune raison d'être relogé, les linkers ne prévoient rien pour. A voir...
    Celà dit autant pour une dll c'est intéressant, autant pour un exe, ça a pas trop de sens. Tu fais quoi une fois relogé, tu l'exécutes ? Il va très probablement se terminer via un ExitProcess (donc ne pas rendre la main, et tuer ton exe...). Tu lui files quoi comme paramètres de WinMain ? etc...

  13. #13
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Oui tout a fait, je suis d'accord avec toi.
    Je m'interessais surtout au cas de la DLL.
    Après, c'est juste pour l'art...

  14. #14
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Oui, c'est cool d'avoir un lien où c'est fait.
    Tu peux cliquer sur Résolu

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

Discussions similaires

  1. Executer du code avant tous le rest du programme
    Par valleyman dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 25/09/2006, 07h47
  2. [FLASH MX2004] Rien ne se passe qd j'execute mon code
    Par adilou1981 dans le forum Flash
    Réponses: 2
    Dernier message: 27/07/2005, 23h31
  3. [C#]Comment executer du code qui se trouve dans une string ?
    Par freddyboy dans le forum Windows Forms
    Réponses: 4
    Dernier message: 28/02/2005, 16h31
  4. Réponses: 5
    Dernier message: 15/07/2004, 23h28
  5. Réponses: 7
    Dernier message: 12/05/2004, 22h27

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