2009-05-14 8 views

Répondre

62
#include <cstdio> 
#include <windows.h> 
#include <tlhelp32.h> 

int main(int, char *[]) 
{ 
    PROCESSENTRY32 entry; 
    entry.dwSize = sizeof(PROCESSENTRY32); 

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 

    if (Process32First(snapshot, &entry) == TRUE) 
    { 
     while (Process32Next(snapshot, &entry) == TRUE) 
     { 
      if (stricmp(entry.szExeFile, "target.exe") == 0) 
      { 
       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); 

       // Do stuff.. 

       CloseHandle(hProcess); 
      } 
     } 
    } 

    CloseHandle(snapshot); 

    return 0; 
} 

Aussi, si vous souhaitez utiliser PROCESS_ALL_ACCESS dans OpenProcess, vous pouvez essayer ceci:

#include <cstdio> 
#include <windows.h> 
#include <tlhelp32.h> 

void EnableDebugPriv() 
{ 
    HANDLE hToken; 
    LUID luid; 
    TOKEN_PRIVILEGES tkp; 

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); 

    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); 

    tkp.PrivilegeCount = 1; 
    tkp.Privileges[0].Luid = luid; 
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL); 

    CloseHandle(hToken); 
} 

int main(int, char *[]) 
{ 
    EnableDebugPriv(); 

    PROCESSENTRY32 entry; 
    entry.dwSize = sizeof(PROCESSENTRY32); 

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 

    if (Process32First(snapshot, &entry) == TRUE) 
    { 
     while (Process32Next(snapshot, &entry) == TRUE) 
     { 
      if (stricmp(entry.szExeFile, "target.exe") == 0) 
      { 
       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); 

       // Do stuff.. 

       CloseHandle(hProcess); 
      } 
     } 
    } 

    CloseHandle(snapshot); 

    return 0; 
} 
+4

Votre code ignorera le premier processus dans le système (cependant, le premier processus est probablement "SYSTEM" donc pas de bogue visible par l'utilisateur.) – Michael

+0

Le premier processus est SYSTEM, donc c'est bien (j'ai littéralement pris ce code directement mes projets);) – xian

+0

Quand j'essaye d'agir sur le hProcess j'obtiens le code d'erreur 6 qui est ERROR_INVALID_HANDLE – Malfist

2

Départ: MSDN Article

Vous pouvez utiliser GetModuleName (je pense?) Pour obtenir le nom et vérifier contre cela.

+0

La plupart des noms GetModuleName, QueryFullProcessImage, etc., requièrent un handle et ne seront donc pas très utiles. Toolhelp renvoie le nom du processus. – Michael

1

OpenProcess Fonction

De MSDN:

Pour ouvrir une poignée à un autre processus local et d'obtenir les droits d'accès, vous devez activer le privilège SeDebugPrivilege.

+0

Je n'ai pas le pID, seul le nom. – Malfist

+1

SeDebugPrivilege n'est absolument pas nécessaire pour les processus qui s'exécutent comme vous. Si vous avez accès au processus via sa liste de contrôle d'accès (ce que vous faites généralement pour les processus que vous créez au même niveau d'intégrité que votre code), vous n'avez pas besoin de SeDebugPrivilege. À partir de la même page MSDN: Si l'appelant a activé le privilège SeDebugPrivilege, l'accès demandé est accordé quel que soit le contenu du descripteur de sécurité. – Michael

+0

Oui, vous devez d'abord obtenir l'ID de processus en répétant les processus. –

10

Il existe deux techniques de base. Le premier utilise PSAPI; MSDN a an example qui utilise EnumProcesses, OpenProcess, EnumProcessModules et GetModuleBaseName.

L'autre utilise Toolhelp, que je préfère. Utilisez CreateToolhelp32Snapshot pour obtenir un instantané de la liste de processus, passez dessus avec Process32First et Process32Next, qui fournit le nom du module et l'ID du processus, jusqu'à ce que vous trouviez celui que vous voulez, puis appelez OpenProcess pour obtenir un handle.

14

Le code suivant montre comment vous pouvez utiliser TOOLHELP et OpenProcess pour obtenir une poignée au processus . La gestion des erreurs a été supprimée par souci de concision.

HANDLE GetProcessByName(PCSTR name) 
{ 
    DWORD pid = 0; 

    // Create toolhelp snapshot. 
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    PROCESSENTRY32 process; 
    ZeroMemory(&process, sizeof(process)); 
    process.dwSize = sizeof(process); 

    // Walkthrough all processes. 
    if (Process32First(snapshot, &process)) 
    { 
     do 
     { 
      // Compare process.szExeFile based on format of name, i.e., trim file path 
      // trim .exe if necessary, etc. 
      if (string(process.szExeFile) == string(name)) 
      { 
       pid = process.th32ProcessID; 
       break; 
      } 
     } while (Process32Next(snapshot, &process)); 
    } 

    CloseHandle(snapshot); 

    if (pid != 0) 
    { 
     return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 
    } 

    // Not found 


     return NULL; 
} 
+0

Vous avez oublié une parenthèse dans la condition "if (MatchProcessName (process.szExeFile, name)" –

+0

Comme la réponse de xian, il s'agit d'une condition de concurrence et elle est intrinsèquement dangereuse – benrg

+0

@Occulta 'if (string (process.szExeFile) == string (name)) 'peut être utilisé à la place de cette fonction, j'ai édité la réponse de Michael. – bytecode77

Questions connexes