2013-01-22 12 views
8

Chcę uzyskać dostęp do określonego adresu procesu. Ale do tego potrzebuję najpierw uzyskać adres bazowy procesu. Używam narzędzia, aby zobaczyć, czy naprawdę to robię dobrze. Narzędzie pokazuje, że potrzebuję: "app.exe"+0x011F9B08 = 0x119F8300Uzyskaj adres podstawowy procesu

Myślałem, że mogę uzyskać adres bazowy procesu przez OpenProcess(), ale to daje mi: 0x0000005c w wyniku. Nie sądzę, że to prawda? Co najmniej, nie tego potrzebuję.

myślę adres bazowy jest mi potrzebne: 0x119F8300 - 0x011F9B08 = 0x107FE7F8 <-- base?

To jest mój kod:

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

Jak mogę uzyskać adresu bazowego procesu, że już otwarty?

+3

Co dokładnie masz na myśli przez "podstawowy adres procesu"? – NPE

+2

Być może musisz się nauczyć o [pamięci wirtualnej] (http://en.wikipedia.org/wiki/Virtual_memory) –

+0

Czy próbujesz odczytać pamięć _annego_ działającego procesu i musisz znać adres podstawowy, pod którym obraz był zmapowane w wirtualnej przestrzeni adresowej tego procesu? –

Odpowiedz

5

Jeśli chcesz uzyskać adres wirtualny w adresowej przestrzeni innego procesu za, można to zrobić tak:

  1. otworzy proces używając OpenProcess - jeśli się powiedzie, wartość zwracana jest uchwytem do procesu, który jest po prostu nieprzejrzystym tokenem używanym przez jądro do identyfikacji obiektu jądra. Jego dokładna wartość całkowita (0x5c w twoim przypadku) nie ma znaczenia dla programów przestrzeni użytkownika, poza odróżnieniem go od innych uchwytów i nieprawidłowych uchwytów.
  2. Zadzwoń pod numer GetProcessImageFileName, aby uzyskać nazwę głównego modułu wykonywalnego procesu. Aby uzyskać listę wszystkich modułów w procesie docelowym, należy użyć .
  3. Dla każdego modułu wywołaj GetModuleFileNameEx, aby uzyskać nazwę pliku i porównaj ją z nazwą pliku wykonywalnego.
  4. Po znalezieniu modułu wykonywalnego zadzwoń pod numer GetModuleInformation, aby uzyskać nieprzetworzony punkt wejścia pliku wykonywalnego.

Daje to adres wirtualny, ale nie można wiele z nim zrobić, ponieważ nie jest on mapowany do przestrzeni adresowej obecnego procesu.

+1

Prawdopodobnie będzie to następstwo połączenia do ReadProcessMemory lub niektórych takich. Ponadto nie uważam, że wezwanie do GetModuleInformation jest konieczne. Adres bazowy modułu i jego HMODULE są jednym i tym samym. –

+1

@Peter: Tak, jest to konieczne - adres bazowy i 'HMODULE' są takie same, ale punkt wejścia modułu (funkcja startowa CRT, która wywołuje' WinMain() 'lub' DllMain() ') różni się od adres bazowy. –

+1

To prawda, i na pewno wygodnie jest wywołać GetModuleInformation(), jeśli tak jest (chociaż OP nie pytał o punkt wejścia). –

2

Chciałem opracować nieco odpowiedzi @Adama Rosenfielda. Użyję League of Legends jako przykładu tutaj.


Aby otworzyć proces (Uzyskanie dojścia) potrzebujemy jego PID (Identyfikator procesu). Możemy to zrobić za pomocą uchwytu okna (HWND), ponieważ zwykle tytuł okna jest znana

//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); 

Teraz, jesteśmy w stanie uzyskać uchwyt do procesu niech nadal

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

GetModule funkcja

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

jak dla mnie osobiście lubię pisać 2 oddzielne funkcje jedną dla uzyskania klamki i jedną dla uzyskania modułu.

Idziemy, udało nam się zdobyć adres bazowy procesu zagranicznego.