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 :

[C/API]Patcher un module en RAM


Sujet :

Windows

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 6
    Points : 4
    Points
    4
    Par défaut [C/API]Patcher un module en RAM
    Bonjour à tous,
    Je débute en C et j'ai besoin d'aide.
    Je m'explique j'aimerais modifier des bytes en mémoire dans un module qui est lui meme chargé dynamiquement par un executable.
    Exemple : main.exe se lance puis a un moment donné fait appel a 1.dll qui se charge.
    Mon but est de modifier 1.dll en mémoire, je veut lui écrire 1 (un) byte.
    Mon problème est que je ne sais pas comment m'y prendre, je sais comment faire cela sur un executable, mais pas sur
    un module chargé par un executable.
    Je vous joint le code que j'ai pu faire en pechant a droite et a gauche.

    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
    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
    #include <psapi.h>
    #include <commctrl.h>
    #include <Winuser.h> 
    
    
    
    void main( )
    {
        HWND hWnd; // Strucure pour l'handle de la fenetre
        DWORD processID; // Dword du PID
        HMODULE hMods[1024];
        HANDLE hProcess; 
        DWORD cbNeeded;
        unsigned int i;
        char *dll = "iecustom.dll"; // Module a patcher
    
         
        char *hTitle = "Internet Explorer 7 Beta 2 Setup"; // Titre de la fenetre....
        hWnd = FindWindow(NULL, hTitle); // Recupere l'handle de la fenetre...
        
        GetWindowThreadProcessId(hWnd,&processID); // Recupere le PID en fonction de l'handle...   
        
        printf( "\nWindow ID: %u\n", hWnd );
        // Print the process identifier.
    
        printf( "\nProcess ID: %u\n", processID );
    
        // Get a list of all the modules in this process.
    
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                PROCESS_VM_READ,
                                FALSE, processID );
        if (NULL == hProcess)
            return;
    
        if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
        {
            for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) // Pour chaque modules...
            {
                TCHAR szModName[MAX_PATH];
    
                if ( GetModuleBaseName( hProcess, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR)))
                {
                    // Print the module name and handle value.
                    if (strcmp(szModName,dll) == 0) // Si le module est bien le bon...
                    {
                    _tprintf( TEXT("Found : \t%s (0x%08X)\n"), szModName, hMods[i] ); // On l'affiche & on patche.
    
                    DWORD address = 0xC825AB; // Offset a patcher
    
                    unsigned char patch[1] = {0xEB}; // Byte a remplacer (jmp)
    
                    if(    WriteProcessMemory (hMods[i],(void*)address, &patch, sizeof(patch), NULL)) { 
                        
                        printf( "\nWell done"); }
    
                    break; // On arrete la boucle...
                    }
    
                }
            }
        }
        CloseHandle( hProcess );
    }
    Je suis perdu !
    Un peu d'aide s'il vous plais

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par mr.tux
    Je débute en C et j'ai besoin d'aide.
    Je m'explique j'aimerais modifier des bytes en mémoire dans un module qui est lui meme chargé dynamiquement par un executable.
    Heureusement, a ma connaissance, ce genre de manip est interdite (du moins en mode 'utilisateur'. En mode kernel, faut voir), mais ça risque d'être dangereux. Certainement pas une manip de novice.
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Heureusement, a ma connaissance, ce genre de manip est interdite (du moins en mode 'utilisateur'. En mode kernel, faut voir), mais ça risque d'être dangereux. Certainement pas une manip de novice.
    Merci pour ta réponse.
    Je ne met pas en doute tes connaissance mais cette manip est tout a fait possible, c'est ce que l'on fait quand on crée un trainer (logiciel qui modifie une ou des valeurs en mémoire pour obtenir plus d'argent ou de vie dans un jeu).

    Certe je suis novice en dans ce language mais d'apres ce que j'ai lu l'API et accesible en userland et agit en kernel land il faut juste avoir les debugs privileges pour effectuer cette action (etre admin).

    EDIT : J'ai mis a jour mon code (sur le 1er post), mon problème est que je l'API WritProcessMemory() me renvoie FALSE... je ne sais pas si l'handle du module est erronée ou autres chose.
    Merci pour votre aide.

  4. #4
    Membre actif

    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2003
    Messages
    286
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 286
    Points : 255
    Points
    255
    .: La cosse : il n'y a que ça de vrai :.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Je te remercie pour ta réponse, mais ce que tu ma donné semble asser compliqué (je suis ultra débutant en C/Win32) et j'ai juste besoin que l'on me dise pourquoi mon code ne fonctionne pas.
    Quelle est la raison pour lasquelle je peut faire un WriteProcessMemory sur le module principal (executable) mais pas sur une de ses librairies.
    J'ai débugger avec OllyDebug mon code et je ne trouve pas la réponse.

  6. #6
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    A première vue, le code semble bon. La ligne qui me dérange est celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DWORD address = 0xC825AB; // Offset a patcher
    WriteProcessMemory travaille avec des VA (Virtual Address) ou Adresse linéaire si tu préfères.

    Or, ici, tu lui passes un offset (endroit sur le fichier disque) et non l'adresse linéaire à laquelle tu souhaites faire ta modification (endroit une fois la DLL chargée en mémoire).

    Je déduis cela du commentaire et de l'adresse qui est assez faible pour un module (typiquement les DLLs sont chargées dans les adresses hautes de l'espace userland).

    Tu peux soit faire la conversion à la main (relativement difficile si tu ne connais pas bien le format PE) soit en débuggant et regardant l'adresse de ton octet à modifier dans ton module sous ton débuggeur (en priant pour que Windows ne fasse pas de "relocation" du module).

    Enfin, dernière solution qui est la plus difficile mais ne ratera jamais, faire un "parsing" du PE header du module pour appliquer la conversion offset->RVA et ceci à l'exécution.

    Dans le cas ou ton adresse est bonne, pesne à changer le flag de ta section en Writeable avec VirtualProtect().Typiquement tu n'as pas de droit d'écriture sur la section .text.

  7. #7
    Membre confirmé Avatar de Mayti4
    Inscrit en
    Février 2004
    Messages
    442
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 442
    Points : 488
    Points
    488
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                PROCESS_VM_READ,
                                FALSE, processID );
    Il manque PROCESS_VM_WRITE, puisque tu veux écrire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WriteProcessMemory (hMods[i],(void*)address, &patch, sizeof(patch), NULL))
    hMods[i] n'est pas un handle de process, utilise hProcess.

    N'oublies pas qu'il y'a une API GetLastError qui renvoie la dernière erreur.

    Avant d'écrire vérifies l'accès en écriture sur la page qui contient 'address', avec VirtualQueryEx.

    Si ce n'est pas le cas, utilise VirtualProtectEx pour l'ajouter.
    L'itération est humaine; la récursion, divine.

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Merci Neitsa pour ta réponse je t'ai écrit tu sais ou.
    Et un grand merci a Mayti4 pour ta reponse, en effet nul besoin d'aller chercher l'handle du module car il semble partager l'espace memoire du process, aprés avoir fait un VirtualProtectEx() sur la zone memoire ca roule...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     DWORD address = 0x00C825AB; // Offset a patcher
     unsigned char patch[1] = {0xEB}; // Byte a remplacer (jmp)
    
    hProcess = OpenProcess( PROCESS_ALL_ACCESS ,FALSE, processID );
        if (NULL == hProcess)
            return;
                VirtualProtectEx(hProcess,(void*)address,1,PAGE_READWRITE,&dwIdOld);
    
     if( WriteProcessMemory (hProcess,(void*)address, &patch, sizeof(patch), NULL)) {   
                        printf( "\nWell done"); }
    Merci a tous pour votre aide !

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

Discussions similaires

  1. [Windows] API Windows et les modules Shell
    Par Jevrod dans le forum Plateformes
    Réponses: 0
    Dernier message: 21/01/2011, 23h31
  2. Réponses: 0
    Dernier message: 21/01/2011, 11h16
  3. Module de recherche Google map api.
    Par DeTeR dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 27/08/2008, 19h32
  4. [VB6] usercontrol + module + API
    Par sBoOb14 dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 20/07/2007, 10h55
  5. Réponses: 5
    Dernier message: 22/01/2007, 14h57

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