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

Windows Discussion :

injection de DLL et surcharge de fonctions


Sujet :

Windows

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut injection de DLL et surcharge de fonctions
    J'aimrerais ecrire un programme qui fait un peu comme valgrind sous linux : remplacer HeapAlloc() (par exemple) par ma propre implémentation, sans avoir à refaire l'édition de lien. Si le programme de test, contenant l'utilisation de HeapAlloc se nomme test.exe, et si mon programme de test de fuites de mémoire s'appelle valgrind.exe, son utilisation serait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    valgrind.exe test.exe
    Pour cela, je désire utiliser l'injection de DLL. J'ai écrit une DLL, nommée valgrind.dll, contenant ma propre implémentation de HeapAlloc. Le but étant alors d'injecter valgrind.dll dans le process de test.exe quand ce dernier est lancé.

    Pour faire court, valgrind.exe lance bien test.exe (un joli printf me le dit), valgrind.dll est bien chargée (DllMain() est appelé, vu qu'il y a aussi un joli printf dedans), mais mon implémentation de HeapAlloc n'est pas appelée.

    Voici les différents codes :

    test.exe:

    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
    #include <stdio.h>
    
    #include <windows.h>
    
    int main()
    {
      HANDLE hDefaultProcessHeap;
      void *data;
    
      printf ("process lance...\n");
    
      hDefaultProcessHeap = GetProcessHeap();
      data = HeapAlloc(hDefaultProcessHeap, 0, 10);
      printf ("HeapAlloc a ete execute...\n");
      if (!data)
        {
          printf ("pas d'alloc...\n");
          return -1;
        }
      HeapFree (hDefaultProcessHeap, 0, data);
    
      return 0;
    }
    Rien de particulier dans ce code.

    valgrind.dll :

    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
    #include <stdio.h>
    
    #define DLL_PROCESS_ATTACH 1
    
    int __stdcall DisableThreadLibraryCalls(void *hModule);
    
    int __stdcall DllMain(void *hModule, unsigned int ulReason, void *lpReserved)
    {
      printf("dll !!!\n");
      if (ulReason == DLL_PROCESS_ATTACH)
        {
          DisableThreadLibraryCalls(hModule);
        }
    
        return 1;
    }
    
    __declspec(dllexport) void * HeapAlloc(void *hHeap, unsigned int dwFlags, size_t dwBytes)
    {
      printf("alloc !!!\n");
      return NULL;
    }
    Il est à noter pour ce code que je ne désire pas include windows.h pour des redéfinitions évidentes (ici, une seule : HeapAlloc), d'où ma redéclaration de DisableThreadLibraryCalls, par exemple, pour enlever des avertissements lors de la compilation.

    valgrind.exe :

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    #include <stdio.h>
    
    #include <windows.h>
    
    #define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ) 
    
    typedef HMODULE (*_load_library)(const char *);
    
    int main(int argc, char *argv[])
    {
      char buf[MAX_PATH];
      STARTUPINFO si;
      PROCESS_INFORMATION pi;
      HMODULE kernel32;
      HANDLE process;
      HANDLE thread;
      _load_library load_library;
      LPVOID remote_string;
      DWORD length;
      DWORD exit_code; /* actually the base address of the mapped DLL */
    
      if (argc < 2)
        {
          printf ("Usage: %s file\n\n", argv[0]);
          return -1;
        }
    
      length = GetFullPathName("valgrind.dll", MAX_PATH, buf, NULL);
      if (!length)
        {
          printf ("can't get full path name\n");
          return -1;
        }
      printf (" * filename : %s\n", buf);
    
      ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
      ZeroMemory(&si, sizeof(STARTUPINFO));
      si.cb = sizeof(STARTUPINFO); 
      if (!CreateProcess(NULL, argv[1], NULL, NULL, TRUE,
                         CREATE_SUSPENDED, NULL, NULL, &si, &pi))
        {
          printf ("can't spawn child process\n");
          return -1;
        }
      printf (" * child process launched\n");
    
      /* Check if CreateRemoteThread() is available. */
      /* MSDN suggests to check the availability of a */
      /* function instead of checking the Windows version. */
    
      kernel32 = LoadLibrary("kernel32.dll");
      if (!kernel32)
        {
          printf("no kernel32.dll found\n");
          goto close_handles;
        }
      printf (" * kernel32.dll loaded\n");
    
      if (!GetProcAddress(kernel32, "CreateRemoteThread"))
        {
          printf("no CreateRemoteThread found\n");
          goto free_kernel32;
        }
      printf (" * CreateRemoteThread found\n");
    
      process = OpenProcess(CREATE_THREAD_ACCESS, FALSE, pi.dwProcessId);
      if (!process)
        {
          printf("no process for valgrind_test.exe\n");
          goto free_kernel32;
        }
      printf (" * process opened\n");
    
      load_library = (_load_library)GetProcAddress(kernel32, "LoadLibraryA");
      if (!load_library)
        {
          printf("no address for LoadLibrary\n");
          goto close_process;
        }
      printf (" * LoadLibrary found\n");
    
      remote_string = VirtualAllocEx(process, NULL, length + 1, MEM_COMMIT, PAGE_READWRITE);
      if (!remote_string)
        {
          printf("no remote string\n");
          goto close_process;
        }
      printf (" * remote string allocated\n");
    
      if (!WriteProcessMemory(process, remote_string, buf, length + 1, NULL))
        {
          printf("no virtual memory\n");
          goto virtual_free;
        }
      printf (" * remote string written\n");
    
      thread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)load_library, remote_string, 0, NULL);
      if (!thread)
        {
          printf("no remote thread\n");
          goto virtual_free;
        }
      printf (" * thread launched\n");
    
      WaitForSingleObject(thread, INFINITE);
    
      if (!GetExitCodeThread(thread, &exit_code))
        {
          printf("no exit code\n");
          goto close_thread;
        }
      printf (" * exit code got\n");
    
      CloseHandle(thread);
      VirtualFreeEx(process, remote_string, length + 1, MEM_RELEASE);
    
      printf(" * fin injection\n");
    
      ResumeThread(pi.hThread);
    
      Sleep(2000);
      printf(" * fin process\n");
    
      thread = CreateRemoteThread(process, NULL, 0,
                                  (LPTHREAD_START_ROUTINE)GetProcAddress(kernel32,
                                                                         "FreeLibrary" ),
                                  (void*)exit_code, 0, NULL );
      WaitForSingleObject(thread, INFINITE );
      CloseHandle(thread );
    
      CloseHandle(process);
      FreeLibrary(kernel32);
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
      printf(" * ressources freed\n");
    
      return 0;
    
     close_thread:
      CloseHandle(thread);
     virtual_free:
      VirtualFreeEx(process, remote_string, length + 1, MEM_RELEASE);
     close_process:
      CloseHandle(process);
     free_kernel32:
      FreeLibrary(kernel32);
     close_handles:
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
    
      return -1;
    }
    Ce code est basé principalement sur celui que l'on peut trouver sur CodeProject, c'est-à-dire .

    Ca fait 2 jours que je suis sur ce code et que je cherche avec Google, et je n'arrive pas à trouver le problème (peut-être évident ?). Redéfinir HeapAlloc dans valgrind.dll n'est peut-être pas suffisant ?

    Donc si une âme charitable pouvait m'aider...

    merci
    L'Opus attire les Prélats

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    apparemment, c'est ma dll qui est trop simple (en tout cas, ce n'est pas aussi simple que sous linux...). Il faudrait faire un "hook" qui remplace HeapAlloc par mon implementation dans la fonction DllMain(). Quant à savoir comment... Je n'ai pas encore trouvé d'exemples pour ça
    L'Opus attire les Prélats

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faut pourrir l'IAT de tous les modules (exe et dll) du processus en y injectant l'adresse de ta fonction au bon endroit.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    pourquoi de tous les modules ?
    L'Opus attire les Prélats

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Avant de réinventer la roue, pourquoi ne pas utiliser tous les outils offerts par Windows ?
    Comme Pageheap.exe :
    http://support.microsoft.com/kb/286470

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    En fait, je ne cherche pas à réinventer la roue, mais à améliorer un logiciel déjà existant, qui fait bien plus que pageheap (il s'agit de mpatrol). Ses 2 principaux problèmes sont qu'il ne gère pas HeapAlloc et al, et qu'on doit, sous Windows, lier statiquement mpatrol à un programme ou une bibliothèque.
    L'Opus attire les Prélats

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par d'Oursse Voir le message
    pourquoi de tous les modules ?
    Parce que chaque module possède une IAT, et la mémoire peut être allouée dans différents modules. De plus, seule la fonction malloc() de la CRT est vraiment soumise à la loi "le module qui alloue est le module qui détruit"...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Pouvez-vous nous donner une fonction de mpatrol non prise en compte par Pageheap.exe ?

    On pourra vraisemblablement vous fournir soit les options des Pageheap.exe qui vont bien, soit un autre outil plus spécifique, soit une méthode pour implémenter cette ou ces fonctions manquantes.

  9. #9
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    @medinoc: ok

    @bacelar: je vous laisse le soin de lire la doc de mpatrol pour voir les differences : http://mpatrol.sourceforge.net/doc/files/mpatrol.pdf
    L'Opus attire les Prélats

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    qui fait bien plus que pageheap
    Une doc de 258 pour vérifier votre assertion.
    Il est bien plus simple et efficace de vous demandez UN exemple.
    A moins, bien sûr, que votre assertion ne repose sur rien de vraiment concret.

  11. #11
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    un exemple ? ok, pageheap ne detecte pas les problemes de stack...
    et si la doc fait 258 pages, ca veut peut-etre dire que c'est un chouia plus que la miserable page web de pageheap
    L'Opus attire les Prélats

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    les problemes de stack
    C'est très vague comme problème.
    VisualStudio gère nativement un grand nombre de ces problèmes, comme l'utilisation de canarie pour la détection d'anomalie (/GS).

  13. #13
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    dans la mesure ou je considere un logiciel qui verifie les probleme de memoire et ou je parle de stack, je parle evidemment de l'allocation de memoire dans la stack. Par exemple via alloca(). Un des problemes est la stack overflow, vu que la memoire allouee a la stack est (tres) limitee.

    ai-je oublie aussi de dire que mpatrol est multi-plateforme ? erreur reparee
    L'Opus attire les Prélats

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Vous voulez donc détecter un problème de stackoverflow avec de l'injection de dll, et ceci de manière portable.

  15. #15
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    j'arrete de discuter avec vous, vous n'avez meme pas lu ce que j'ai ecrit precedemment.

    et vous n'essayez meme pas de m'aider. Pas un seul commentaire de votre part concernant ce que je veux faire.

    je considere ce thread resolu pour ne plus avoir a vous lire
    L'Opus attire les Prélats

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

Discussions similaires

  1. API HOOK, Dump dll, Surcharge de Fonction
    Par MicroAlexx dans le forum Windows
    Réponses: 2
    Dernier message: 30/12/2005, 10h39
  2. [MFC] Surcharger des fonctions de CView
    Par Philippe320 dans le forum MFC
    Réponses: 2
    Dernier message: 22/11/2005, 21h24
  3. singleton, polymorphisme, et surcharge de fonction
    Par legend666 dans le forum C++
    Réponses: 11
    Dernier message: 14/11/2005, 09h27
  4. Réponses: 10
    Dernier message: 02/11/2005, 11h12
  5. Surcharge de fonction d'un edit dynamique
    Par Tartar Ukid dans le forum C++Builder
    Réponses: 4
    Dernier message: 13/10/2003, 11h56

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