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 :

Erreur avec ReadProcessMemory


Sujet :

Windows

  1. #1
    Membre confirmé Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Par défaut Erreur avec ReadProcessMemory
    Bonjour,

    je cherche à récupérer les valeurs des variables utilisées par un autre processus (processus appelé ici "FT").

    Voici le code :
    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
    int main()
    {
        // Variables
        STARTUPINFO startupInfo; // Information about the FT startup
        PROCESS_INFORMATION processInformation; // Information about the FT process
        MEMORY_BASIC_INFORMATION memoryBasicInformation; // Basic information about the memory of the FT process
    
        // Initialize the STARTUPINFO structure for the FT process
        memset(&startupInfo, 0, sizeof(startupInfo));
        startupInfo.cb = sizeof(startupInfo);
    
        // Create the FT process
        if(
            CreateProcess(NULL,
                "FT_Client.exe 0",
                NULL,
                NULL,
                TRUE,
                CREATE_BREAKAWAY_FROM_JOB,
                NULL,
                NULL,
                &startupInfo,
                &processInformation
            )
        ==0){
            cout << "Unable to create the FT process : " << GetLastError() << endl;
            return(-1);
        }
    
        // Display the FT process Id
        cout << "FT process Id : " << processInformation.dwProcessId << endl;
    
        // Get basic information about the memory of the FT process
        if(
            VirtualQueryEx(processInformation.hProcess,
                NULL,
                &memoryBasicInformation,
                sizeof(memoryBasicInformation)
            )
        == 0){
            cout << "Unable to get basic information about the memory of the FT process :" << GetLastError();
            return(-1);
        }
    
        // Read the FT process memory
        if(
            ReadProcessMemory(processInformation.hProcess,
                &memoryBasicInformation.BaseAddress,
                &memoryBasicInformation,
                sizeof(memoryBasicInformation),
                NULL
            )
        ==0){
            cout << "Unable to read the FT process memory : " << GetLastError() << endl;
            return(-1);
        }
    
        // Close the FT process handle
        if(CloseHandle(processInformation.hProcess)==0){
            cout << "Unable to close the FT process handle : " << GetLastError() << endl;
            return(-1);
        }
    
        return 0;
    }
    Le résultat sur le flux de sortie standard est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FT process Id : 2008
    Unable to read the FT process memory : 299
    L'erreur 299 signifie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERROR_PARTIAL_COPY 
    299 (0x12B) Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
    Donc il semble y avoir un problème au moment de la lecture de la mémoire utilisée par le processus FT.

    Voyez-vous une (ou plusieurs) erreur dans mon code?

    Merci bien.

  2. #2
    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
    Par défaut
    Bonjour,

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        if(
            ReadProcessMemory(processInformation.hProcess,
                &memoryBasicInformation.BaseAddress,
                &memoryBasicInformation,
                sizeof(memoryBasicInformation),
                NULL
            )

    1) Tu essaye de lire dans le processus cible à l'adresse où se situe &memoryBasicInformation.baseAddress, ce qui n'a pas beaucoup de sens

    solution: enlève le '&'

    2) N'utilise pas memoryBasicInformation comme buffer de sortie non plus !

    solution: alloue un buffer (new ou une API windows type VirtualAlloc()) pour y mettre les données en sortie de ReadProcessMemory()

    3) Si tu passes NULL à VirtualQueryEx comme deuxième param. il va te donner les informations concernant la page à l'adresse 0, et celle-ci on ne peut pas y lire grand chose.

    solution: tout dépend de l'adresse que tu veux lire... Si tu veux lire dans le processus cible, commence par trouver l'adresse de base où est mappé le programme.

  3. #3
    Membre confirmé Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Par défaut
    Pour le 1), je suis tout à fait d'accord. memoryBasicInformation.BaseAddress pointe déjà vers l'adresse de base qui m'intéresse. Le '&' n'a donc rien à faire ici. Je viens de le retirer.

    Pour le 2), utiliser memoryBasicInformation comme buffer est une erreur je te l'accorde. En effet, memoryBasicInformation n'est qu'une structure qui est sensée contenir seulement des informations sur l'usage de la mémoire d'un processus. J'ai donc créé un tableau de char de taille 100 en espérant que ça fera l'affaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char buffer[100];
    ...
    ReadProcessMemory(processInformation.hProcess,
                memoryBasicInformation.BaseAddress,
                buffer,
                sizeof(buffer),
                NULL
    )
    Pour le 3), j'essaye de passer à VirtualQueryEx l'adresse de base de mon processus cible, mais il est difficile de la trouver. En effet, la structure memoryBasicInformation ne contient pas cette information. La fonction GetSystemInfo qui récupère une structure SYSTEM_INFO ne semble pas contenir cette information également. Enfin, processInformation qui est une structure PROCESS_INFORMATION ne contient pas non plus l'adresse de base de mon processus.

    Donc au final, je cherche à savoir :
    -comment créer un buffer pour ReadProcessMemory de façon plus propre? (un tableau de char de taille 100 ne doit pas être une bonne solution)
    -comment trouver l'adresse de base de mon processus cible?

  4. #4
    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
    Par défaut
    Hello,

    ne sachant pas trop ce que tu souhaites, j'ai codé un petit truc vite fait.

    Cela démarre un processus (calc.exe en l'occurrence) et affiche quelque infos sur les modules chargés dans l'espace d'adressage du processus.

    On récupère ensuite l'adresse de base du module principal et on lit la totalité de la page (soit 4096 octets) à cette même adresse.

    Code c++ : 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
     
    #include <windows.h>
    #include <iostream>
    #include <psapi.h>
    #include <string>
     
    using namespace std;
     
    #ifdef _UNICODE
    #define _tcout std::wcout
    #define _tstring std::wstring
    #else
    #define _tcout std::cout
    #define _tstring std::string
    #endif
     
    PVOID FindProcessBaseAddress(HANDLE hProcess);
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        // various structs init
    	STARTUPINFO startupInfo = {0}; 
    	PROCESS_INFORMATION processInformation = {0};
    	MEMORY_BASIC_INFORMATION meminfo = {0};
     
     
        // Initialize the STARTUPINFO structure
        memset(&startupInfo, 0, sizeof(startupInfo));
        startupInfo.cb = sizeof(startupInfo);
     
        // Create the desired process
        if(
    		CreateProcess(_T("C:\\windows\\system32\\calc.exe"),
                NULL,
                NULL,
                NULL,
                TRUE,
                0,
                NULL,
                NULL,
                &startupInfo,
                &processInformation) == 0 )
    	{
            cout << "Unable to create the FT process : " << GetLastError() << endl;
            return -1;
        }
     
        // Display the process Id
        cout << "Process Id : " << processInformation.dwProcessId << endl;
     
    	// if it's too quick, our process can't read remote process modules info, so wait a little bit.
    	Sleep(1000);
     
    	// get exe base address (and print some info)
    	PVOID exeBaseAddress = FindProcessBaseAddress(processInformation.hProcess);
     
    	// get page info at exe base address
    	VirtualQueryEx(processInformation.hProcess, exeBaseAddress, &meminfo, sizeof(MEMORY_BASIC_INFORMATION));
     
    	// alloc some room for bytes to read
    	PVOID pMembytes = VirtualAlloc(NULL, meminfo.RegionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
     
    	//read proc memory at base address
    	DWORD nobr = 0;
    	ReadProcessMemory(processInformation.hProcess, exeBaseAddress, pMembytes, meminfo.RegionSize, &nobr);
     
    	//release buffer
    	VirtualFree(pMembytes, 0, MEM_RELEASE);
     
        return 0;
     
    }
     
    PVOID FindProcessBaseAddress(HANDLE hProcess)
    {
    	DWORD cbNeeded = 0;
    	SIZE_T Number_of_HMODS = 1024 * sizeof(HMODULE);//array can hold 1024 HMODULES
    	MODULEINFO ModuleInfo = {0};
    	PVOID exeBase = NULL;
    	_tstring exeExtension = _T(".exe");
     
    	//allocate array for all HMODULEs in the process
    	HMODULE * pModules = (HMODULE *) VirtualAlloc(NULL, Number_of_HMODS, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
     
    	std::wstring module_name(MAX_PATH * sizeof(TCHAR), '\0');
     
    	// enum all process modules (.exe + .dll)
        if( EnumProcessModulesEx(hProcess, pModules, Number_of_HMODS, &cbNeeded, LIST_MODULES_ALL))
        {
            for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
            {
    			// get info about module
    			GetModuleInformation(hProcess, pModules[i], &ModuleInfo, sizeof(MODULEINFO));
    			// get its name
    			GetModuleFileNameEx(hProcess, pModules[i], &module_name.at(0), MAX_PATH * sizeof(TCHAR));
     
    			// print info and name
    			_tcout << _T("[+] Found module: ") << module_name.c_str() << endl;
    			_tcout << _T("\tModule base: 0x") << hex << ModuleInfo.lpBaseOfDll << endl;
     
    			//just check if it ends with ".exe" (there's only one '*.exe' by process!)
    			int pos = module_name.find(exeExtension);
    			if(pos != _tstring::npos)
    			{
    				// found executable base address!
    				exeBase = ModuleInfo.lpBaseOfDll;
    			}
            }
        }
     
    	//free buffer
    	VirtualFree(pModules, 0, MEM_RELEASE);
     
    	return exeBase;
    }

  5. #5
    Membre confirmé Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Par défaut
    Hum... Je comprends pourquoi j'avais du mal à trouver facilement mon adresse de base du processus.

    En lisant ton code, je vois que pour la trouver, tu as eu besoin de créer une fonction dédiée à cette tâche qui utilise plusieurs fonctions (VirtualAlloc, EnumProccessModule, GetModuleInformation). Aussi dans la structure MODULEINFO, il semble que ce soit le membre lpBaseOfDll qui corresponde à l'adresse de base que je cherche.

    Je ne sais pas ce que c'est qu'un module... Apparemment un processus possède plusieurs modules... Un module est caractérisé par une adresse de base.

    Il faut donc que pour chaque module de mon processus, j'en extrait l'adresse de base, ce qui me permettra ensuite de les lire un par un avec la fonction ReadProcessMemory.

    Ça doit être quelque chose dans le genre... Bref je vais analyser tout ça en détails et tester.

    Je rappel que mon objectif est simplement de lire des valeurs utilisées par le processus cible. J'aimerai bien les afficher dans la console. Par exemple, si dans le processus FT, il y a une valeur '115' qui correspond au nombre de pièces d'or du joueur, j'aimerai afficher : "Golds : 115" dans le flux de sortie standard.

    Qui peut m'expliquer ce que c'est qu'un "module" pour un processus donné qui lit et écrit dans sa zone mémoire?

  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
    Par défaut
    D'une manière générale (encore que sous ces acceptions, les termes sont plutôt orientes pour Windows):

    - Un processus est un conteneur qui dispose d'un espace d'adressage (ce qui fait qu'un processus croit disposer de toute la mémoire disponible) et contient des threads.

    - Un thread est une unité d'exécution de code.

    - Un module est une entité physique (un exécutable, des DLLs) qui contient notamment du code est des données (le point important est de comprendre que tant que le module n'est pas mappé, le code et les données sont dans un état statique). Ce module est placé (on dit "mappé") par le système d'exploitation dans l'espace d'adressage du processus.

    Lorsque le système crée un processus, il alloue de la mémoire pour celui-ci (création de l'espace d'adressage) et "mappe" les modules (l'exécutable [*.exe] et ses DLLs [*.dll]). Ensuite il crée un premier thread (dit "thread primaire") qui exécute du code. La première instruction exécutée par le thread primaire est située au point d'entrée de l'exécutable.

    C'est grossièrement résumé et certaines descriptions souffre d'exception mais cela te donne un point de vue général.

    Ceci dit:

    Je rappel que mon objectif est simplement de lire des valeurs utilisées par le processus cible. J'aimerai bien les afficher dans la console. Par exemple, si dans le processus FT, il y a une valeur '115' qui correspond au nombre de pièces d'or du joueur, j'aimerai afficher : "Golds : 115" dans le flux de sortie standard.
    Si tu cherche à lire une valeur dans un processus encore faut-il savoir à quelle adresse elle se situe. Dans le cas d'un trainer tu sera forcé de passer par un désassemblage...

  7. #7
    Membre confirmé Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Par défaut
    Ok donc la première étape consiste à énumérer les modules de mon processus.
    Je me suis aidé de l'exemple de Neitsa pour modifier mon code :
    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
    int main()
    {
        // Variables
        STARTUPINFO startupInfo; // Information about the FT startup
        PROCESS_INFORMATION processInformation; // Information about the FT process
        HMODULE *hModules; // Array that receives the list of module handles
        LPDWORD cbNeeded; // The number of bytes required to store all module handles
    
        // Initialize the STARTUPINFO and PROCESS_INFORMATION structures for the FT process
        ZeroMemory(&startupInfo, sizeof(startupInfo));
        startupInfo.cb = sizeof(startupInfo);
        ZeroMemory(&processInformation, sizeof(processInformation));
    
        // Allocate the memory of the array that receives the list of module handles
        hModules = (HMODULE *) VirtualAlloc(NULL, 1024 * sizeof(HMODULE), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if( hModules == NULL ){
            cout << "Unable to allocate the memory : " << GetLastError() << endl;
            return(-1);
        }
    
        // Create the FT process
        if(
            CreateProcess(NULL,
                "FT_Client.exe 0",
                NULL,
                NULL,
                TRUE,
                CREATE_BREAKAWAY_FROM_JOB,
                NULL,
                NULL,
                &startupInfo,
                &processInformation
            )
        ==0){
            cout << "Unable to create the FT process : " << GetLastError() << endl;
            return(-1);
        }
    
        // Display the FT process Id
        cout << "FT process Id : " << processInformation.dwProcessId << endl;
    
        // Wait in order to be able to read process modules
    	Sleep(10000);
    
        // Enum all process modules (.exe and .dll)
        if(
            EnumProcessModules(processInformation.hProcess,
                hModules,
                sizeof(hModules),
                cbNeeded
            )
        ==0){
            cout << "Unable to enum the FT process modules : " << GetLastError() << endl;
            return(-1);
        }
    
        // Wait until FT process exits.
        WaitForSingleObject(processInformation.hProcess, INFINITE );
        cout << "FT process exits." << endl;
    
        // Close the process and the FT process handle
        if( CloseHandle(processInformation.hProcess) == 0 ){
            cout << "Unable to close the FT process : " << GetLastError() << endl;
            return(-1);
        }
        if( CloseHandle(processInformation.hThread) == 0 ){
            cout << "Unable to close the FT process handle : " << GetLastError() << endl;
            return(-1);
        }
    
        // Free the memory allocated
    	if( VirtualFree(hModules, 0, MEM_RELEASE) == 0){
    	    cout << "Unable to free the memory allocated : " << GetLastError() << endl;
            return(-1);
    	}
    
        return 0;
    }
    Le résultat sur le flux de sortie standard :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FT process Id : 768
    Unable to enum the FT process modules : 5
    Ce qui signifie que l'accès m'est refusé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ERROR_ACCESS_DENIED
    5 (0x5)
    Access is denied.
    Pourtant je pensais qu'en lançant le nouveau processus j'aurai eu les droits suffisant pour lister les modules de celui-ci : "The new process runs in the security context of the calling process." (MSDN).

    Comment résoudre ce problème d'accès refusé?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Aucune idée. Surtout que normalement, le handle retourné par CreateProcess() a PROCESS_ALL_ACCESS sur le processus créé...
    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.

  9. #9
    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
    Par défaut
    Hello,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
       HMODULE *hModules; // Array that receives the list of module handles
        LPDWORD cbNeeded; // The number of bytes required to store all module handles
    
    // ... cut ...
    
            EnumProcessModules(processInformation.hProcess,
                hModules,
                sizeof(hModules),
                cbNeeded
            )
    - 1) Le sizeof sur hModules va retourner la taille d'un pointeur (4 ou 8), ce qui est trop petit. Il faut passer la même taille que celle passée à VirtualAlloc, à savoir :

    1024 * sizeof(HMODULE)

    c-a-d un tableau pouvant accueillir 1024 HMODULE.

    - 2) declare cbNeeded comme DWORD (et non pas LPDWORD) et rajoute un '&' à cbNeeded comme paramètre de EnumProcessModules.

  10. #10
    Membre confirmé Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Par défaut
    Bien vu Neitsa
    J'ai donc corrigé tout cela et j'ai ajouté les appels aux fonctions GetModuleInformation et GetModuleFileNameEx pour récupérer le nom de fichier correspondant à chaque module du processus :
    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
    int main()
    {
        // Variables
        STARTUPINFO startupInfo; // Information about the FT startup
        PROCESS_INFORMATION processInformation; // Information about the FT process
        HMODULE *hModules; // Array that receives the list of module handles
        DWORD cbNeeded; // The number of bytes required to store all module handles
        MODULEINFO moduleInfo; // Information about the FT module
        int counter; // A counter for for
        int numberOfModules; // The number of modules
        TCHAR filename[MAX_PATH]; // The module file name
    
        // Initialize the STARTUPINFO and PROCESS_INFORMATION structures for the FT process
        ZeroMemory(&startupInfo, sizeof(startupInfo));
        startupInfo.cb = sizeof(startupInfo);
        ZeroMemory(&processInformation, sizeof(processInformation));
    
        // Allocate the memory of the array that receives the list of module handles
        hModules = (HMODULE *) VirtualAlloc(NULL, 1024 * sizeof(HMODULE), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if( hModules == NULL ){
            cout << "Unable to allocate the memory : " << GetLastError() << endl;
            return(-1);
        }
    
        // Create the FT process
        if(
            CreateProcess(NULL,
                //"FT_Client.exe 0",
                "calc.exe",
                NULL,
                NULL,
                TRUE,
                CREATE_BREAKAWAY_FROM_JOB,
                NULL,
                NULL,
                &startupInfo,
                &processInformation
            )
        ==0){
            cout << "Unable to create the FT process : " << GetLastError() << endl;
            return(-1);
        }
    
        // Display the FT process Id
        cout << "FT process Id : " << processInformation.dwProcessId << endl;
    
        // Wait in order to be able to read process modules
    	Sleep(10000);
    
        // Enum all process modules (.exe and .dll)
        if(
            EnumProcessModules(processInformation.hProcess,
                hModules,
                sizeof(1024 * sizeof(HMODULE)),
                &cbNeeded
            )
        ==0){
            cout << "Unable to enum the FT process modules : " << GetLastError() << endl;
            return(-1);
        }
    
        // Display how many modules were enumerated
        numberOfModules=cbNeeded/sizeof(HMODULE);
        cout << "FT process modules : " << numberOfModules << endl;
    
        // For each module
        for(counter=0;counter<numberOfModules;counter++){
            cout << "FT process module numero " << counter << endl;
    
            // Get module information
            if(
                GetModuleInformation(processInformation.hProcess,
                    hModules[counter],
                    &moduleInfo,
                    sizeof(moduleInfo)
                )
            ==0){
                cout << "Unable to get information about the FT module : " << GetLastError() << endl;
                return(-1);
            }
    
            // Get its name
            if(
                GetModuleFileNameEx(processInformation.hProcess,
                    hModules[counter],
                    filename,
                    sizeof(filename) / sizeof(TCHAR)
                )
            ==0){
                cout << "Unable to get the FT module file name : " << GetLastError() << endl;
                return(-1);
            }
    
            // Display its name
            cout << "FT process module file name : " << filename << endl;
    
        }
    
        // Wait until FT process exits.
        WaitForSingleObject(processInformation.hProcess, INFINITE );
        cout << "FT process exits." << endl;
    
        // Close the process and the FT process handle
        if( CloseHandle(processInformation.hProcess) == 0 ){
            cout << "Unable to close the FT process : " << GetLastError() << endl;
            return(-1);
        }
        if( CloseHandle(processInformation.hThread) == 0 ){
            cout << "Unable to close the FT process handle : " << GetLastError() << endl;
            return(-1);
        }
    
        // Free the memory allocated
    	if( VirtualFree(hModules, 0, MEM_RELEASE) == 0){
    	    cout << "Unable to free the memory allocated : " << GetLastError() << endl;
            return(-1);
    	}
    
        return 0;
    }
    Résultat sur calc.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
    FT process Id : 3432
    FT process modules : 20
    FT process module numero 0
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 1
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 2
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 3
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 4
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 5
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 6
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 7
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 8
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 9
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 10
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 11
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 12
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 13
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 14
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 15
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 16
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 17
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 18
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process module numero 19
    FT process module file name : C:\WINDOWS\system32\calc.exe
    FT process exits.
    Résultat sur FT_Client.exe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FT process Id : 2940
    Unable to enum the FT process modules : 5
    Je pense donc que le processus FT est sécurisé (je ne sais pas comment), et du fait, je ne peux pas énumérer ses modules (contrairement à calc.exe).
    Par contre, je suis étonné de voir que les 20 modules du processus calc.exe correspondent au même fichier calc.exe. Je pensais voir un nom de fichier différent pour chaque module (1 .exe et 19 .dll).

    1) Pourquoi je ne peux toujours pas énumérer les modules du processus FT?

    2) Est-ce normal que les 20 modules du processus calc.exe font tous référence au nom de fichier calc.exe?

Discussions similaires

  1. Erreur Avec Interbase
    Par smokemon dans le forum Bases de données
    Réponses: 1
    Dernier message: 29/10/2004, 07h24
  2. Erreur avec procédure LockWorkStation ...
    Par simonseztech dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 16/08/2004, 15h33
  3. [Débutant][Conception] Erreur avec une classe interne
    Par Devil Redneck dans le forum Général Java
    Réponses: 5
    Dernier message: 11/06/2004, 15h45
  4. Erreur avec les ADO
    Par megane dans le forum Bases de données
    Réponses: 7
    Dernier message: 08/03/2004, 21h37
  5. Erreur avec WM_COMMAND (BN_CLICKED)
    Par cyberlewis dans le forum Windows
    Réponses: 2
    Dernier message: 09/02/2004, 00h25

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