2013-01-22 10 views
8

Desidero accedere a un determinato indirizzo di un processo. Ma per quello ho bisogno di ottenere l'indirizzo di base del processo prima. Sto usando uno strumento per vedere se effettivamente lo sto facendo bene. Lo strumento mostra che ho bisogno di quanto segue: "app.exe"+0x011F9B08 = 0x119F8300Ottieni l'indirizzo di base del processo

Ho pensato che avrei potuto ottenere l'indirizzo di base di un processo tramite OpenProcess(), ma che mi dà: 0x0000005c di conseguenza. Non penso sia giusto? Almeno, non quello di cui ho bisogno.

penso che l'indirizzo di base ho bisogno è: 0x119F8300 - 0x011F9B08 = 0x107FE7F8 <-- base?

Questo è il mio codice:

hWindow = FindWindow(NULL, lpWindowName); 
if(hWindow) 
{ 
    GetWindowThreadProcessId(hWindow, &dwProcId); 
    if(dwProcId != 0) 
    { 
      // hProcHandle -> 0x0000005c 
      hProcHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId); 
    } 
    else 
    { 
     return 0; 
    } 
} 

Come posso ottenere l'indirizzo di base del processo che ho aperto?

+3

Cosa intendete esattamente con "l'indirizzo di base di un processo"? – NPE

+2

Forse è necessario conoscere la [memoria virtuale] (http://en.wikipedia.org/wiki/Virtual_memory) –

+0

Stai cercando di leggere la memoria di un altro processo in esecuzione e devi conoscere l'indirizzo di base in cui è stata scattata l'immagine mappato nello spazio degli indirizzi virtuali di quel processo? –

risposta

5

Se si desidera ottenere l'indirizzo virtuale all'interno dello spazio indirizzi del l'altro processo, si può fare che in questo modo:

  1. Aprire il processo utilizzando OpenProcess - in caso di successo, il valore restituito è una maniglia al processo, che è solo un token opaco utilizzato dal kernel per identificare un oggetto kernel. Il suo valore intero esatto (0x5c nel tuo caso) non ha significato per i programmi dello spazio utente, se non per distinguerlo da altri handle e handle non validi.
  2. Chiamare GetProcessImageFileName per ottenere il nome del modulo eseguibile principale del processo.
  3. Utilizzare EnumProcessModules per enumerare l'elenco di tutti i moduli nel processo di destinazione.
  4. Per ogni modulo, chiamare GetModuleFileNameEx per ottenere il nome file e confrontarlo con il nome file dell'eseguibile.
  5. Quando hai trovato il modulo dell'eseguibile, chiamare GetModuleInformation per ottenere il punto di ingresso grezzo del file eseguibile.

Questo ti darà l'indirizzo virtuale, ma non c'è molto che tu possa fare con esso poiché non è mappato nello spazio degli indirizzi del processo corrente.

+1

Presumibilmente questo sarebbe seguito da una chiamata a ReadProcessMemory o alcuni di questi. Inoltre, non credo che la chiamata a GetModuleInformation sia necessaria. L'indirizzo di base del modulo e il suo HMODULE sono la stessa cosa. –

+1

@Peter: Sì, è necessario - l'indirizzo di base e 'HMODULE' sono gli stessi, ma il punto di ingresso del modulo (la funzione di avvio CRT che chiama' WinMain() 'o' DllMain() ') è diverso da l'indirizzo di base. –

+1

Questo è vero, ed è certamente conveniente chiamare GetModuleInformation() se questo è il caso (anche se l'OP non ha chiesto il punto di ingresso). –

2

ho voluto approfondire un po 'la risposta di @ Adamo Rosenfield. Userò League of Legends come esempio qui.


Per aprire il processo (Ottenere un handle) abbiamo bisogno del suo PID (Process ID). Possiamo farlo tramite un handle di finestra (HWND) perché di solito il titolo della finestra è noto

//You will need to change this the name of the window of the foreign process 
HWND WindowHandle = FindWindow(nullptr, L"League of Legends (TM) Client"); 
DWORD PID; 
GetWindowThreadProcessId(WindowHandle, &PID); 
PVOID hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, PID); 

Ora che siamo in grado di ottenere un handle per il processo di continuiamo

HMODULE Module = GetModule(); 
DWORD BaseAddress = (DWORD)Module; 

Il GetModule funzione

HMODULE GetModule() 
{ 
    HMODULE hMods[1024]; 
    HANDLE pHandle = GetHandle(); 
    DWORD cbNeeded; 
    unsigned int i; 

    if (EnumProcessModules(pHandle, hMods, sizeof(hMods), &cbNeeded)) 
     { 
     for (i = 0; i < (cbNeeded/sizeof(HMODULE)); i++) 
     { 
      TCHAR szModName[MAX_PATH]; 
      if (GetModuleFileNameEx(pHandle, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR))) 
      { 
       wstring wstrModName = szModName; 
       //you will need to change this to the name of the exe of the foreign process 
       wstring wstrModContain = L"League of Legends.exe"; 
       if (wstrModName.find(wstrModContain) != string::npos) 
       { 
        CloseHandle(pHandle); 
        return hMods[i]; 
       } 
      } 
     } 
    } 
    return nullptr; 
} 

per quanto riguarda me personalmente mi piace scrivere 2 funzioni separate una per ottenere una maniglia e una per ottenere il modulo.

Ci andiamo, abbiamo ottenuto con successo l'indirizzo di base di un processo di stranieri.

Problemi correlati