Odczytanie base address z procesu 64-bitowego

Odpowiedz Nowy wątek
2015-10-25 18:17

Rejestracja: 14 lat temu

Ostatnio: 1 miesiąc temu

0

Mam problem z odczytaniem base address z 64bitowego procesu.
Normalnie stosuję tą funkcję:

function GetModuleBaseAddress2(PID: Cardinal; MName: String): dword_ptr;
var
 Snap: THandle;
  M32: TModuleEntry32;
begin

  Snap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,PID);
  if (Snap = 0) then
    Exit;
  if Module32First(Snap, M32) then begin
    repeat
      if MName = M32.szModule then begin
        Result := Cardinal(M32.modBaseAddr);
        Break;
      end;
    until not Module32Next(Snap, M32);
  end;
end;

Niestety przy procesie 64 bitowym nie jest spełniony warunek " if Module32First(Snap, M32)" i funkcja nic nie zwraca.

Próbowałem także z

 function GetModuleBaseAddress(ProcessID: Cardinal; MName: String): Pointer;
var
  Modules         : Array of HMODULE;
  cbNeeded, i     : Cardinal;
  ModuleInfo      : TModuleInfo;
  ModuleName      : Array[0..MAX_PATH] of Char;
  PHandle         : THandle;
begin
  Result := nil;
  SetLength(Modules, 1024);
  PHandle := OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, ProcessID);
  if (PHandle <> 0) then
  begin
    EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded); //Getting the enumeration of modules
   //EnumProcessModulesEx(
    SetLength(Modules, cbNeeded div SizeOf(HMODULE)); //Setting the number of modules
    for i := 0 to Length(Modules) - 1 do //Start the bucle
    begin
      GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName)); //Getting the name of module
      if AnsiCompareText(MName, ModuleName) = 0 then //If the module name match with the name of module we are looking for...
      begin
        GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo)); //Get the information of module
        Result := ModuleInfo.lpBaseOfDll; //Return the information we want (The image base address)
        CloseHandle(PHandle);
        Exit;
     end;
    end;
  end;
end;

Także nie działa.
Dokładnie chodzi o grę Shadow of Mordor. Przy innych grach, których używałem do odczytania base address wszystko działa, niestety przy tej poległem i nie mogę rozgryźć problemu

Pozostało 580 znaków

2015-10-25 18:34
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 godziny temu

Lokalizacja: Tuchów

0

Niestety przy procesie 64 bitowym nie jest spełniony warunek " if Module32First(Snap, M32)" i funkcja nic nie zwraca.

Funkcja nie może nic nie zwrócić; W Twoim kodzie zwraca wartość niezdefiniowaną lub domyślną, jeśli warunek nie zostanie spełniony - sprawdź w dokumentacji; Przydałoby się tak tę funkcję napisać, aby zawsze "coś" zwracała, bo na 100% dostajesz ostrzeżenie przy kompilacji, które nie wiem dlaczego ignorujesz;

Z samymi hackami nie pomogę, ale @olesio bawi(ł) się w te klocki, więc może coś doradzi.


edytowany 2x, ostatnio: furious programming, 2015-10-25 18:35

Pozostało 580 znaków

2015-10-25 19:20

Rejestracja: 9 lat temu

Ostatnio: 3 godziny temu

0

Podpowiedź pierwsza:
https://www.assembla.com/spac[...]ad_dll/proc_man.c?_format=raw

kod wskazuje na to że wołanie funkcji dla 64 bitowego procesu z procesu 32 bitowego może się nie udać.

Podpowiedź druga:
http://stackoverflow.com/ques[...]oces-always-returns-error-299


edytowany 1x, ostatnio: vpiotr, 2015-10-25 19:22

Pozostało 580 znaków

2015-10-25 19:34
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 tydzień temu

Lokalizacja: Szczecin

0

Nic na teraz nie pomogę, bo jestem poza domem. Jutro dopiero po południu obadam. Drugi kod na systemach starszych od 98 powinien działać. Pewnie nie można pobrać nazwy 64 bitowego procesu, bo pełną ścieżkę / nazwę pobiera się wtedy z tego co kojarzę inaczej. Musiał byś przeanalizować źródło Cheat Engine i zobaczyć jak t tam jest dokładnie zrobione. Zobacz też czy PE Tools pokazuje jakieś konkretne dsne dla procesu tej gry.

@furious programming i to nie są żadne Hooki. To w uproszczeniu adres bazowy procesu. Przydać się to może przy operacjach na pamięci procesu. Kiedy nam Cheat Engin pokaże że dana wartość jest na przykład pod adresem NazwaExeka.exe+1234bcdf to wiemy że offset 1234bcdf jest względem adresu bazowego, który może być różny w zapeżności od systemu i warunków uruchomienia. Ostatnio musiałem się tym posiłkować robiąc trainer do trybu RPG do gry Polanie 2 dla żony znajomego. Początkowo myślałem, że ustalony adrs Pointera jest stały. Dopiero Analiza w Cheat Engine pod Windowsem XP na VM pokazało, że adres należy podać względem tego bazowego. Ale to gra dość stara i 32 bitwa. Wtedy skorzystałem z podobnego kodu jak ten drugi.

Ewntualnie może pod kątem ustalania tego z pod WinAPI doraźnie pomóc może @Bartosz Wójcik.


Nie chodziło mi o hooki - napisałem hacki, od hakowania :P - furious programming 2015-10-25 19:51
Źle przeczytałem. Ale to też z hackowaniem też nie ma nic wspólnego. Hackować można na przykład servery online. Tutaj nie wiem czy modyfikacja miała dotyczyć czegoś online, czy chodzi o sam trainer. - olesio 2015-10-25 22:26
potocznie @olesio, potocznie; - furious programming 2015-10-25 22:29

Pozostało 580 znaków

2015-10-26 16:40

Rejestracja: 14 lat temu

Ostatnio: 1 miesiąc temu

0

Tak, chodzi o trainer. Niestety ciągle nie rozwiązałem problemu

Pozostało 580 znaków

2015-10-26 23:06

Rejestracja: 16 lat temu

Ostatnio: 6 godzin temu

0

Grzebanie w 64-bitowym procesie spod 32-bitowego programu to w ogóle kiepski pomysł. Windows dość ściśle izoluje te dwie platformy i może się po prostu nie dać.

A nawet jeśli by się dało, to byłoby to bardzo utrudnione. Przecież 64-bitowy proces ma 64-bitowe wskaźniki, z base address włącznie.

edytowany 2x, ostatnio: Azarien, 2015-10-26 23:09

Pozostało 580 znaków

2015-10-26 23:07
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 tydzień temu

Lokalizacja: Szczecin

0

Nie umiem pomóc poki co, bo nie umiem poslużyć się EnumProcessModulesEx tak aby dla ostatniego parametru LIST_MODULES_ALL zwracało mi rozsądną ilość modułów. Ustawiam rozmiar tablicy na 1024, a wymagany rozmiar jest w okolicach kilkuset tysięcy. Jak wspomniał poprzednik, trzeba chyba inaczej robić we własnym kodzie jako procesie 32 bitowym do ogarnięcia 64 bitowego. Może @kAzek coś więcej podpowie, jak ustalić BaseAddress 64 bitowego procesu. Ja umiem tylko pełną ścieżkę. A z informacjami o modułach nie kombinowałem. A rozkłada mnie przeziębienie i niestety nie mam siły dalej kombinować z tym, bo ledwie siedzę, a nawet leżę przy komputerze.


Nie mam czasu na zabawę ale nie umiesz bo If the function is called by a 32-bit application running under WOW64, the dwFilterFlag option is ignored and the function provides the same results as the EnumProcessModules function. - kAzek 2015-10-26 23:21
to oczywiście MSDN https://msdn.microsoft.com/en[...]op/ms682633%28v=vs.85%29.aspx (2 akapit w Remarks) a więc tak się a to nie zabierzesz a czy jest inny sposób to nie wiem... jak się ostatnio bawiłem "w procesy" to jeszcze nie 64 bit - kAzek 2015-10-26 23:25

Pozostało 580 znaków

2015-10-27 17:57

Rejestracja: 14 lat temu

Ostatnio: 1 miesiąc temu

0

Cheat engine jakoś sobie radzi z tym. Próbuje przeanalizować źródło, ale widzę że nie będzie łatwo

Pozostało 580 znaków

2015-10-27 22:01

Rejestracja: 16 lat temu

Ostatnio: 6 godzin temu

1

Kiedy nam Cheat Engin pokaże że dana wartość jest na przykład pod adresem NazwaExeka.exe+1234bcdf to wiemy że offset 1234bcdf jest względem adresu bazowego, który może być różny w zapeżności od systemu i warunków uruchomienia.

Okej, dobra, ale jeżeli NazwaExeka.exe jest procesem 64-bitowym, to się okazuje że wartość jest pod adresem 0x1234567890abcdef, a sam exek ma adres bazowy 0x0011223344556677. Jak się do tej komórki teraz niby odwołać spod 32-bitowego procesu?

Możemy mieć szczęście, jeżeli adres jest typu 0x0000000011223344, wtedy obcięcie go do 32-bitów 0x11223344 nie będzie katastrofą, ale nie ma takiej gwarancji.

Nie idźcie tą drogą.

Pozostało 580 znaków

Rev
2015-10-28 14:34
Rev
Moderator

Rejestracja: 13 lat temu

Ostatnio: 1 tydzień temu

1

Nie jest to możliwe. Nie ma innej odpowiedzi. Wszystkie 32-bitowe programy, które udostępniają taką możliwość robią to de facto za pomocą 64-bitowego kodu. Nawet jeżeli ładnie to ukrywają to pod spodem uruchamiają proces 64-bitowy i komunikują się z nim. A to można już wykonać na kilka sposobów - np. za pomocą COM i out-of-process server w surrogate (dllhost), który zajmie się i uruchomieniem procesu i serializacją (nie wiem na ile w Delphi/Pascalu będzie helperów do tego, bo ręczne bawienie się z proxy/stubs czy tlb może być męczące) albo zwykłe stworzenie procesu i komunikowanie się przez stdin/stdout, pipes albo cokolwiek innego sobie wymyślicie. 32-bitowy Process Monitor z Sysinternals zawiera w resource'ach swoją 64-bitową kopię ;).


Pozostało 580 znaków

2015-10-29 18:27

Rejestracja: 14 lat temu

Ostatnio: 1 miesiąc temu

0

Ok, to wiele wyjaśnia. Próbuję odczytać base address procesu 64bitowego z aplikacji 64 bit znów bez sukcesu.
Czy funkcje z pierwszego postu powinny działać w aplikacji 64bit?

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0