GetModuleBaseAddress - ReadProcessMemory

0

Witam,

Mam taką funkcję:

function GetModuleBaseAddress(ProcessID: Cardinal): Pointer;
 var
   Modules         : Array of HMODULE;
   cbNeeded, i     : Cardinal;
   ModuleInfo      : TModuleInfo;
   ModuleName      : Array[0..MAX_PATH] of Char;
 begin
   Result := nil;
   SetLength(Modules, 1024);

   if (IDProcess <> 0) then
   begin
     EnumProcessModules(IDProcess, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded); //Getting the enumeration of modules
     SetLength(Modules, cbNeeded div SizeOf(HMODULE)); //Setting the number of modules
     for i := 0 to Length(Modules) - 1 do //Start the loop
     begin
       GetModuleBaseName(IDProcess, 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(IDProcess, 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;

Funkcja teoretycznie zwraca BaseAddress procesu np: gg.exe z tym, że jest to zawsze wartość $00800000
Nie jestem pewny czy jest to rzeczywiście poprawny BaseAddress procesu.

W necie znajduję masę przykładów C# odnośnie odczytywania poszczególnych danych z procesu np gier itp na podstawie BaseAddress + offset.

Przykład odczytania:
Health: "Diablo III.exe"+00FE31CC + 0x18 + 0xC8 + 0xC + 0x2A0 + 0x14

problem w tym, że nie rozumiem tego w jaki sposób jest to liczone. Co oznacza to "Diablo III.exe" czy w tym miejscu ma być podstawiony baseaddres ? następnie czym jest kolejny adres i offsety.

Prosiłbym o wytłumaczenie zasady działania takiego schematu, ewentualnie jakies strony z omówieniem podstaw wyciągania wartości z pamięci (baseaddres, offsety, pointery).

Przykład kodu odczytania ilości życia w grze:

   BlackMagic diablo = new BlackMagic();
                diablo.OpenProcessAndThread(SProcess.GetProcessFromWindowTitle("Diablo III"));
                IntPtr baseDiablo = diablo.MainModule.BaseAddress; // czym jest base address oraz jak powinien wygladac, 
                                                                                      // jak go pobrać?
                Console.WriteLine("baseDiablo: " + baseDiablo);   

                // Try to get current health
                uint value = diablo.ReadUInt((uint)baseDiablo + 0xFE31CC); // co jest dodawane do base addresu, offset ?
                value += 0x18;
                value = diablo.ReadUInt(value);
                value += 0xC8;
                value = diablo.ReadUInt(value);
                value += 0xC;
                value = diablo.ReadUInt(value);
                value += 0x2A0;
                value = diablo.ReadUInt(value);
                value += 0x14;
                float hp = diablo.ReadFloat(value);

Kombinuję w CE, przejrzałem tutorial ale niestety za wiele z niego dowiedzieć się nie można. Czy macie może jakieś praktyczne przykłady kodu wykorzystania BaseAddress + offset, szukanie pointerów itp?

Chciałbym poznać zasadę działania takiego schematu, a w necie znajduję jedynie fragmenty które są tłumaczone w taki sposób, że gość z podstawową wiedzą na ten temat nie jest w stanie tego ogarnąć.

0

Kod funkcji do ustalenia ImageBase masz prawidłowy. Też go wygooglowałem i testowałem. Dla emulatora Amigi WinUAE podało mi prawidłowy ImageBase. Najlepiej wygoogluj sobie LordPE albo inny PE Edytor i zobacz jakie wartości on pokazuje dla uruchomionych procesów. Co do używania CE to tutoriali na sieci można znaleźć mnóstwo, w tym również video na YouTube. Jest też polskojęzyczne forum http://coding-gods.org z tutorialami ze screenshotami, gdzie pewien user pokazuje co i jak na przykładzie dołaczonego do CE exeka tutorialowego. A to Diablo III.exe pokazywane przez CE to właśnie ImageBase. Ja Diablo 3 nie posiadam i nie zamierzam kupować, bo nie lubię gier RPG, ale mogę podpowiedzieć, że należało by ustalić - jeżli się da - Pointery tak jak jest to pokazane na tutorialach. Zwykle można znaleźć właściwe Pointery "jedno poziomowe" (nie MultiLevel). Na przykład dla WinUAE prawidłowy Pointer to taki którego adres ustalony przez polecenie Find out what writes to this address jest odpowiednio wcześniej / później po znalezionym adresie na przykład energii. Poza tym na przykład w grach amigowych w kodzie procesu będzie to na pewno linia rejest+rejestr, a nie na przykład zawierająca rejestr+01. Tyle mogę podpowiedzieć. Swoje dotychczasowe trainery pisane w Delphi 7 pod WinAPI opierałem właśnie na tym. Znająć prawidłowy Poiner mamy odniesienie do adresu pamięci, który po reboocie systemu albo ponownym uruchomieniu gry również wskaże na to miejsce. Konkretnych gotowców już nie podaje, bo znowu mi ktoś bezpodstawnie zarzuci, że malware rozpowszechniam. Mogę jedynie odesłać do swojego bloga (link w sygnaturce) we wspisie powitalnym masz przykład kodu w Delphi jak zapisywać i odczytywać podstawoewe Pointery. Natomiast w artykule na temat robienia trainera do Maxa Payna w archiwum zip jest kod gotowego trainera w WinAPI oraz opis jak ustaliłem te wartośći. Nie wiem również czy cheatowanie w Diablo 3 jest w ogóle możłiwe i dozwolone. Czy nie kończy się banem na konto. A poza tym, o ile wiem, to gra głównie sieciowa, więc na logikę wszelkie wartości powinny być "server side". Czyli gra i tak sprawdzi sobie i pobierze daną wartość z serwera, a to co jest po stronie klienta służy jedynie jej wyświetleniu. A co do kodu który wkleiłeś, to przecież jest on na tyle banalny, że wszystko widać jak na dłoni do ImageBase dodawane jest $FE31CC. Także przetłumacz to sobie do Delphi. Powodzenia. Jak coś to może ktoś jeszcze coś Ci tutaj pomoże, o ile nie skończy się znowu na zarzutach podsyłania malware tymrazem dla innej osoby i ta się jak ja nie zrazi ;/ Anyway, ja odpowiedzieć będę mogł dopiero w ten poniedziałek pod wieczór, bo wyjeżdzam, także pora iść pospać.

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