2009-05-14 13 views

risposta

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; 
} 

Inoltre, se si desidera utilizzare PROCESS_ALL_ACCESS in OpenProcess, si potrebbe provare questo:

#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

Il codice salterà il primo processo nel sistema (tuttavia, il primo processo è molto probabilmente "SYSTEM" quindi nessun bug visibile all'utente.) – Michael

+0

Il primo processo è SYSTEM, quindi va bene (ho preso letteralmente quel codice direttamente da uno di i miei progetti);) – xian

+0

Quando tento di agire sul hProcess ottengo il codice di errore 6, che è ERROR_INVALID_HANDLE – Malfist

2

Partenza: MSDN Article

È possibile utilizzare GetModuleName (credo?) Per ottenere il nome e verificare che contro.

+0

La maggior parte del GetModuleName, del nome QueryFullProcessImage, ecc., Richiede un handle e pertanto non sarà molto utile. Toolhelp restituisce il nome del processo. – Michael

1

OpenProcess Funzione

Da MSDN:

per aprire un handle a un altro processo locale e ottenere i diritti di accesso completo, è necessario abilitare il privilegio SeDebugPrivilege.

+0

Non ho il pID, solo il nome. – Malfist

+1

SeDebugPrivilege non è assolutamente necessario per i processi in esecuzione come te. Se hai accesso al processo tramite il suo ACL (che generalmente fai per processi che crei allo stesso livello di integrità del tuo codice), non hai bisogno di SeDebugPrivilege. Dalla stessa pagina MSDN: Se il chiamante ha abilitato il privilegio SeDebugPrivilege, l'accesso richiesto è garantito indipendentemente dal contenuto del descrittore di sicurezza. – Michael

+0

Sì, è necessario ottenere l'ID processo innanzitutto eseguendo processi iterativi. –

10

Esistono due tecniche di base. Il primo utilizza PSAPI; MSDN ha an example che utilizza EnumProcesses, OpenProcess, EnumProcessModules e GetModuleBaseName.

L'altro utilizza Toolhelp, che preferisco. Utilizzare CreateToolhelp32Snapshot per ottenere un'istantanea dell'elenco dei processi, passarci sopra con Process32First e Process32Next, che fornisce il nome del modulo e l'ID del processo, fino a trovare quello desiderato, quindi chiamare OpenProcess per ottenere un handle.

14

Il codice seguente mostra come è possibile utilizzare TOOLHELP e OpenProcess per ottenere un handle al processo . Gestione degli errori rimossa per brevità.

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

Hai dimenticato una parentesi nella condizione "if (MatchProcessName (process.szExeFile, name)" –

+0

Come la risposta di xian, questa ha una condizione di competizione ed è intrinsecamente pericolosa – benrg

+0

@Occulta' if (string (process.szExeFile) == stringa (nome)) 'può essere usato al posto di questa funzione. Ho modificato la risposta di Michael. – bytecode77

Problemi correlati