Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Speicherbereich einer Anwendung ermitteln (https://www.delphipraxis.net/68236-speicherbereich-einer-anwendung-ermitteln.html)

bundy 26. Apr 2006 20:22


Speicherbereich einer Anwendung ermitteln
 
Hi Leute.

Ich bin dabei einen Trainer zu proggen.

Jetzt ist er soweit fertig, und er läuft wunderbar, "auf meien PC" :(

Hab das Teil jetzt bei nen Kumpel testen wollen, aber is nicht. (Spiel liegt in einen anderen Speicherbereich) alls Dynamisch.

Jetzt will ich das Offset 0 des Spieles ermitteln, und dann die Adresse dazu zählen.

Wie komm ich über die ProcessID auf das Offset 0 der Anwendung ?


lg
Bundy

jmd anders 26. Apr 2006 20:33

Re: Speicherbereich einer Anwendung ermitteln
 
hmm eigentlich müsstest du ohne probleme mit readprocessmemory und writeprocessmemory auf den speicher zugreifen können.

dazu solltest du vorher den process öffen (openprocess) und eben auch die process id besorgen

SnuffMaster23 26. Apr 2006 20:35

Re: Speicherbereich einer Anwendung ermitteln
 
Hi,

ich glaub kaum, dass du da große Chancen hast, du müsstest ja mit der physikalischen Adresse arbeiten und das darf afaik nur der Kernel :). Jedes Programm kriegt doch seine 4 GB virtuellen Adressraum und denkt, es wäre allein im Speicher.
Ich versteh auch nicht, wie das bei dir funktionieren kann. Außerdem liegt das Spiel doch nicht zuverlässig immer an der selben Adresse, wer weiß, was du alles für Programme aufmachst und so.
Falls ich mich irren solle, lasse ich mich auch gern korrigieren, so isses ja nicht :D

Snuffi

bundy 26. Apr 2006 20:36

Re: Speicherbereich einer Anwendung ermitteln
 
So sieht code aus


Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cxControls, cxContainer, cxEdit, cxLabel, ExtCtrls, cxTextEdit,
  cxMaskEdit, cxSpinEdit, cxCheckBox, Menus, cxLookAndFeelPainters, StdCtrls,
  cxButtons;

type
  TfmMain = class(TForm)
    cxLabel1: TcxLabel;
    Image1: TImage;
    cxSpinEdit1: TcxSpinEdit;
    cxLabel2: TcxLabel;
    cxSpinEdit2: TcxSpinEdit;
    cxLabel3: TcxLabel;
    cxSpinEdit3: TcxSpinEdit;
    cxLabel4: TcxLabel;
    cxSpinEdit4: TcxSpinEdit;
    cxCheckBox1: TcxCheckBox;
    Timer1: TTimer;
    cxLabel5: TcxLabel;
    cxLabel6: TcxLabel;
    cxLabel7: TcxLabel;
    Shape1: TShape;
    cxButton1: TcxButton;
    cxButton2: TcxButton;
    procedure cxCheckBox1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure cxButton2Click(Sender: TObject);
    procedure cxButton1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private

    { Private-Deklarationen }
    function ReadValue(aAdresse:integer):integer;
    function WriteValue(aAdresse,aValue:integer):integer;
  public
    { Public-Deklarationen }
  end;

var
  fmMain: TfmMain;
  WindowName: Integer;
  ThreadId: Integer;
  ProcessId: Integer;
  HandleWindow: Integer;

const
// WindowTitle           = 'Harry Potter und der Feuerkelch' + #153;
 WindowTitle           = 'Project2';
 AddressLeben          = $241BC08;
 AddressSuperShoot     = $241D15A;
 AddressBohnenHarry    = $24194F0;
 AddressBohnenHermin   = $24194F8;
 AddressBohnenRonald   = $24194F4;


implementation

{$R *.dfm}

procedure TfmMain.cxButton1Click(Sender: TObject);
begin

cxSpinEdit1.Value:= ReadValue(AddressLeben);
cxSpinEdit2.Value:= ReadValue(AddressBohnenHarry);
cxSpinEdit3.Value:= ReadValue(AddressBohnenHermin) ;
cxSpinEdit4.Value:= ReadValue(AddressBohnenRonald) ;
end;

procedure TfmMain.cxButton2Click(Sender: TObject);
begin
WriteValue(AddressLeben,cxSpinEdit1.Value);
WriteValue(AddressBohnenHarry,cxSpinEdit2.Value);
WriteValue(AddressBohnenHermin,cxSpinEdit3.Value);
WriteValue(AddressBohnenRonald,cxSpinEdit4.Value);
end;

procedure TfmMain.cxCheckBox1Click(Sender: TObject);
begin
Timer1.Enabled:=cxCheckBox1.Checked;
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  WindowName := FindWindow(nil, WindowTitle);
  if WindowName = 0 then
  begin
    MessageDlg('Das Spiel läuft nicht !! Spiel Starten !!', mtwarning, [mbOK], 0);
    Close;
  end;
  ThreadId := GetWindowThreadProcessId(WindowName, @ProcessId);
  HandleWindow := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
end;



function TfmMain.ReadValue(aAdresse:integer): integer;
var
aValue:integer;
Bytesread : DWORD;
begin
ReadProcessMemory(HandleWindow, ptr(aAdresse), @aValue,sizeof(aValue),Bytesread);
Result:=aValue;
end;

procedure TfmMain.Timer1Timer(Sender: TObject);
begin
WriteValue(AddressSuperShoot,17130);
end;

function TfmMain.WriteValue(aAdresse,aValue: integer): integer;
var
Bytesread : DWORD;
begin
   WriteProcessMemory(HandleWindow, ptr(aAdresse), @aValue, sizeof(aValue), Bytesread);
end;

end.
das ganze funktioniert auf meinen PC, aber auf einen anderen nicht !

Es muss doch möglich sein wenn man sich den Hauptspeicher her nimmt.
Offset: 0000000000-------------------|Spiel|--------------------FFFFFFFFFF (4 GB)

Das erste Offset des Spieles zu finden oder ?

jmd anders 26. Apr 2006 20:43

Re: Speicherbereich einer Anwendung ermitteln
 
Eigentlich sollte es schon funktionieren, wenn du WriteProcessMemory so verwendest:

WriteProcessMemory(hProcess,
ptr(SpeicherAdresseImSpeicherbereich),
@DatenDiegeschriebenwerden,
Laenge,
BytesWritten);

also so funktioniert es bei mir


ich brauche also keine startadresse oder so.

bundy 26. Apr 2006 20:51

Re: Speicherbereich einer Anwendung ermitteln
 
Aber wie sieht es aus wenn das Spiel nicht immer am gleichen Platz im speicher liegt ?

Oder denke ich da falsch.
Sowas wie Dynamischer Speicher oder so dynamic memory addresses (dma)

Daniel G 26. Apr 2006 20:54

Re: Speicherbereich einer Anwendung ermitteln
 
@SnuffMaster23: Schau' mal in der MSDN nach... Er darf auf den Speicherbereich zugreifen... ;)

SnuffMaster23 26. Apr 2006 20:58

Re: Speicherbereich einer Anwendung ermitteln
 
@Daniel G
Wer ist "Er"? Der Kernel oder bundy?
Falls du bundy meinst, stellt das jetzt mein ganzes Weltbild auf den Kopf (zumindest teilweise :) )

c113plpbr 26. Apr 2006 20:59

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von bundy
Aber wie sieht es aus wenn das Spiel nicht immer am gleichen Platz im speicher liegt ?

Oder denke ich da falsch.
Sowas wie Dynamischer Speicher oder so dynamic memory addresses (dma)

Hast du schonmal daran gedacht, dass durch dynamische allozierungen diverser variablen des spiels, die variablen selbst irgendwo anders liegen könnten?

ciao, Philipp

Daniel G 26. Apr 2006 21:01

Re: Speicherbereich einer Anwendung ermitteln
 
@SnuffMaster23:

Wenn es möglich ist, das Handle mit "PROCESS_VM_WRITE and PROCESS_VM_OPERATION" zu erstellen:

Zitat:

WriteProcessMemory

The WriteProcessMemory function writes data to an area of memory in a specified process. The entire area to be written to must be accessible, or the operation fails.


BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T* lpNumberOfBytesWritten
);

Parameters
hProcess
[in] Handle to the process whose memory is to be modified. The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.
lpBaseAddress
[in] Pointer to the base address in the specified process to which data will be written. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for write access. If this is the case, the function proceeds; otherwise, the function fails.
lpBuffer
[in] Pointer to the buffer that contains data to be written into the address space of the specified process.
nSize
[in] Number of bytes to be written to the specified process.
lpNumberOfBytesWritten
[out] Pointer to a variable that receives the number of bytes transferred into the specified process. This parameter is optional. If lpNumberOfBytesWritten is NULL, the parameter is ignored.
Return Values
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The function will fail if the requested write operation crosses into an area of the process that is inaccessible.

Remarks
WriteProcessMemory copies the data from the specified buffer in the current process to the address range of the specified process. Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call the function. The process whose address space is being written to is typically, but not necessarily, being debugged.

The entire area to be written to must be accessible. If it is not, the function fails as noted previously.

Requirements
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, and Windows 95.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
Tut mir Leid um dein Weltbild ;)

bundy 26. Apr 2006 21:09

Re: Speicherbereich einer Anwendung ermitteln
 
Hat jetzt jemand vieleicht eine Idee.


Mein Gedankengang ist folgender:
Code:
1. Suche die Adresse des 1. Offsets des Spieles im Speicher
2. Addiere zum 1.Offset die Adresse des Modifikationspunktes (aus TSearch)
3. WriteProcess auf die Adresse
müsste doch so gehn oder.

Wenn ja Wie erhalte ich das 1.Offset des Spieles.

SnuffMaster23 26. Apr 2006 21:12

Re: Speicherbereich einer Anwendung ermitteln
 
Dann muss ich mir wohl ein neues zulegen :mrgreen:
Nee, mal ensthaft: Ich dachte, gerade das wäre der Trick an den virtuellen 32-Bit Adressen. Bei Win 3.1 gabs das nicht, da war das System auch nur multitaskingfähig, wenn sich die Programme "kooperativ" gezeigt haben (so hab ichs mal wo gelesen). Außerdem haben die sich manchmal gegenseitig gestört (glaub ich) wenn man nicht sehr umsichtig programmiert hatte, weil sie eben nebeneinander im selben Speicherbereich lagen.
Das werd ich nochmal etwas überdenken müssen...
Wie sollten sonst auch Sachen wie die Zwischenablage, OLE oder einfach das Nachrichtensystem von Windows funktionieren...

Na egal, genug OT jetzt!! :mrgreen:
bundy kann ich leider nicht helfen, ich hätte es ihm ausgeredet.

Snuffi

c113plpbr 26. Apr 2006 21:26

Re: Speicherbereich einer Anwendung ermitteln
 
@snuffmaster23:
ich glaube du bist irgendwo in der win9x-zeit hängen geblieben ... ^^

[edit]Aber im grunde hast du recht, jedes programm hat unter nt-systemen seinen eigenen adressraum, in dem es tun und lassen kann was es will ;)
Daher kann es mit sehr hoher wahrscheinlichkeit auch passieren, dass das Programm jedesmal an exakt die gleiche Stelle geladen wird, und somit auf vielen rechnern läuft, und durch zufall auf einem anderen nicht, weil in diesen ein modul mehr geladen ist, und das den speicher schon irgendwo besetzt -> diverse variablen werden an anderen stellen alloziert -> problem für trainer ...[/edit]

@bundy:
Ich vermute also, dass du das modulehandle des modules benötigst, dem der speicherbereich "gehört". Naja, theoretisch gesehen könntest du das via GetModuleHandle das betreffliche handle erfahren, allerdings nur, wenn du dich IM fremden Prozess befindest ... und sobald du sowas versuchst, wirds kompliziert.

Also musst du wohl EnumProcessModules verwenden, die daraus resultierenden module-handles sollten die Startadressen der geladenen Module (z.B. dlls) sein.
Die könntest du als Anhaltspunkte verwenden, allerdings würde ich es nicht darauf ankommen lassen (ich hab diese methode verwendet, um aus relativen funktions-adressen absolute adressen zu bekommen, soweit funktioniert das, aber ob du das auch mit den adressen irgendwelcher, möglicherweise dynamisch allozierter variablen machen kannst, ist eine andere frage).

ciao, Philipp

bundy 26. Apr 2006 21:39

Re: Speicherbereich einer Anwendung ermitteln
 
Ich hab das Programm jetzt auf meinen 2. Pc getestet, da funktioniert es auch wunderbar.

Warum sieht mein Kumpel nicht die gleichen Werte.
Stimmt der Speicherbereich des Spieles, nicht mit meinem überein?

Ich hab das Game schon zick mal mit Tsearch aufgemacht, und meinen PC dazwischen immer neu gestartet und die Adressen der Modifikations Offsets sind immer die gleichen.

Wie händelt das denn TSearch, wenn ich nach einem Wert suche. Tsearch such ja auch nur im Speicherbereich des Spieles oder?
Ich glaub ich denk da irgendwie verkehrt.

Oder wird jeder Applikation die 0000000000-FFFFFFFFFF (4 GB) zugesichert ?

lg
Bundy

SnuffMaster23 26. Apr 2006 21:46

Re: Speicherbereich einer Anwendung ermitteln
 
Genau, jeder Applikation werden 4 GB Speicher versprochen, so hab ich das jedenfalls bis vorhin verstanden. Und da niemand so viele GBs Speicher in seinen PC reinsteckt, gibts das Pagefile :)
Die Adressen für jedes Programm gehen von $00000000 bis $FFFFFFFF aber die sind virtuell, sagen also außerhalb des Programms nichts. Drum versteh ich auch nicht, wieso du danach fragst... egal.

bundy 26. Apr 2006 21:54

Re: Speicherbereich einer Anwendung ermitteln
 
Ich glaub ich weiss warum es beim meinem Kumpel nicht geht.

Er verwändet einen NoCD Patch, der dürfte ein anderer sein, den ich verwände. Das würde auch den unterschieldlichen Speicherbereich erklären .

Ich bedanke mich an alle die mir hier geholfen haben :thumb:

Frickeldrecktuxer_TM 26. Apr 2006 22:02

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von SnuffMaster23
Nee, mal ensthaft: Ich dachte, gerade das wäre der Trick an den virtuellen 32-Bit Adressen.

Isses auch, an die physikalische Adresse kommst du ohne weiteres nicht ran, die aktuelle Page kann sonstwo rumfliegen, wenn's grad' mies um den Arbeitsspeicher bestellt ist sogar im Swapfile auf der Festplatte ;-) Und von alldem kriegst du nichts mit.
Aber die physikalische Adresse interessiert auch nicht mehr sonderlich, denn mit WriteProcessMemory() schreibst du in den virtuellen Adressraum des Programmes. Die Adressen, mit denen man arbeitet, sind zwar immer noch virtuell, aber dafür sind es die des anderes Prozesses und nicht deines eigenen. No magic ;-)

Zitat:

Zitat von SnuffMaster23
Außerdem haben die sich manchmal gegenseitig gestört (glaub ich) wenn man nicht sehr umsichtig programmiert hatte, weil sie eben nebeneinander im selben Speicherbereich lagen.

Über WPM() kriegt man das heute immer noch hin, wenn dein Prozess entsprechende Rechte hat. Andere Prozesse abzuschießen ist nach wie vor kein Kunststück, aber es passiert nicht mehr aus Versehen oder aus Dummheit ;-)

Zitat:

Zitat von SnuffMaster23
Das werd ich nochmal etwas überdenken müssen...

Nope, dein Weltbild hat gestimmt, aber du bist davon ausgegangen, daß WPM() in den physikalischen Speicher schreibt, bzw man Werte nur im physikalischen Speicher ändern kann.

Zitat:

Zitat von SnuffMaster
Wie sollten sonst auch Sachen wie die Zwischenablage, OLE oder einfach das Nachrichtensystem von Windows funktionieren...

Komplizierter ;-)


@bundy: Wenn du großartig debuggen willst, solltest du dich auch mal über die Tool Help API schlau machen. Rumgefummele mit Modulhandles würde ich beispielsweise nicht wagen, denn niemand garantiert mir, daß der numerische Wert des Handles die Basisadresse des Moduls ist. Mir Module32First() und Module32Next() kannst du aber durch die Module eines Przesses iterieren, das gesuchte rausfischen und kommst laut API an die Basisadresse. Bei Microsoft gibt's dazu auch ein Beispiel (Funktion ListProcessModules() ist für dich interessant).

Eigentlich ist es aber so, daß das Prozessmodul (also die Exe) immer an der gleichen Stelle geladen wird, wenn ich mich richtig erinnere ist das mittlerweile 0x400000, sofern dort Platz ist, und das sollte beim Laden des Prozesses ja immer der Fall sein. Bist du denn sicher, daß dein Freund die gleiche Version (Patchlevel) wie du benutzt? Mitunter ändern die Hersteller die Position der Variablen gerne von Patchlevel zu Patchlevel, um gerade solche Hacks zu erschweren.

bundy 26. Apr 2006 22:15

Re: Speicherbereich einer Anwendung ermitteln
 
Ja das denke ich auch, das er ne andere EXE Version verwändet.

Kann ja nur so sein, wenn die Applikation auf Offset $400000 geladen wird, dann ist das ja ein fixer Startpunkt.
Wenn dann bei Offset z.B $4000E0 nicht der selbe Wert wie bei mir steht, dann kann ja nur die Struktur der Applikation ne andere sein.

Wer bestimmt das laden an Offset $400000, das Speichermangement oder die Applikation selbst ?


lg
Bundy

brechi 27. Apr 2006 00:17

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von Frickeldrecktuxer_TM
Rumgefummele mit Modulhandles würde ich beispielsweise nicht wagen, denn niemand garantiert mir, daß der numerische Wert des Handles die Basisadresse des Moduls ist.

Ja ne ist klar ^^. Wäre ja schlimm wenns nicht so wäre. ModuleHandle = BaseAdresse. Das ist bis XP 100% so.

@0x00400000
Die Applikation hat das im PE Header stehen. Dieser Wert wird vom compiler festgelegt. Bei Delphi kann man das unter Projekt -> Optionen -> Linker einstellen. Als Standard hat sich dise Adresse etabliert. Man kann auch jede andere wählen, sollte diese belegt sein (durch die kernel32.dll oder ntdll.dll oder unterhalb der 0x00100000 Grenze liegen) dann wird die EXE an einer anderen Stelle geladen und durch die Relocation Tabelle die Globalen Variablen usw. wieder richtig hergetsellt.

retnyg 27. Apr 2006 01:30

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von bundy
Ja das denke ich auch, das er ne andere EXE Version verwändet.

gut möglich, also solltest du per version der exe (oder anhand der dateigrösse oder prüfsumme)
die entsprechenden speicheradressen einpflegen.
andererseits ist es auch möglich dass die speicheradressen durch verschiedene windows-dll's bei der heap-verwaltung andere adressen zurückliefern, dann kannst du nur nach signifikanten byteketten in bestimmten speicherbereichen suchen.

als beispiel kann ich dir mal nen trainer posten, den ich für pokemon auf dem vba geschrieben habe



Delphi-Quellcode:
program pokerubyhack;
{$APPTYPE CONSOLE}
uses
  sysutils,
  windows,
  messages;

type pcardinal = ^cardinal;
function EnumCb(hnd: hwnd; lParam: cardinal):BOOLEAN; stdcall;
const bufsize = 256;
var strResult: string;
begin
   setlength(strResult,bufsize);
   zeromemory(@strResult[1],bufsize);
   //lastHnd := cardinal(hnd);
   GetWindowText(hnd,@strResult[1],bufSize);
   //if strResult[1] <> #0 then asm int 3 end;
   if copy(strResult,1,16) = 'VisualBoyAdvance' then begin
     pcardinal(lParam)^ := hnd;
     result := false
   end
   else result := true;
end;

function findwnd:hwnd;
var lparam: cardinal;
begin
  result := 0;
  lParam := cardinal(  @result );
  EnumWindows(@EnumCb,lparam);
end;

procedure haltp(c:integer;s:string);
begin
   writeln(s+#13#10'press any key to continue');readln;
   halt(c);
end;

type
  ppokestat = ^pokestat;
  pokestat = packed record
    CHP:word;
    AHP:word;
    ATT:word;
    DEF:word;
    INI:word;
    SPA:word;
    SPD:word;
  end;

const START_OFFSET = $1560000;
      DIST2REC = 6;
      pokedef : array[1..7]of string[3] =('CHP','AHP','ATT','DEF','INI','SPA','SPD');
var hnd: hwnd;
    pid : dword;
    dwread: dword;
    hp : thandle;
    s: string;
    p, buf, pend,pokedata: pointer;
    pokeptr: pointer;
    j: integer;
    c,d: char;
    newstat: pokestat;
    pm: pword;
    nv: word;

procedure hackStats(pokeNum:byte);
var dwWritten : dword;
begin
   writeln(#13#10'trying to patch pokemon #'+ inttostr(pokenum));
   writeprocessmemory(hp,pointer(cardinal(pokedata)+DIST2REC+((pokenum -1) * $64 )),@newstat,sizeof(pokestat),dwWritten);
   if dwWritten > 0 then
     writeln(format(#13#10'successful: %d bytes written',[dwWritten]))
   else
     writeln(#13#10'an error occured');
end;


begin

  writeln('retnygs pokemon trainer for visual boy advance v 1.0');
  writeln('====================================================');
  writeln('tested with 2006 pokemon ruby 1.2 and VBA Link 1.7.3L'#13#10'supported cmd line parameters: number of pokemon to patch [1-6]'#13#10'patch is temporary and will be removed on next level up.'#13#10#13#10);

  hnd := findwnd;
  if (Hnd <> 0) then begin
    GetWindowThreadProcessId(hnd,@pid); //Get ProcessID and ignore ThreadID
    hp:=openprocess(ProCEsS_aLL_ACCESS,false,pid);
    if (hp = 0) or (pid = 0) then haltp(1,'could not find hacker process');
    setlength(s,$640000);
    buf:=@s[1];
    cardinal(p):=START_OFFSET; // weise startadresse des zu suchenden speicherbereiches zu
    readprocessmemory(hP,p,buf,length(s),dwRead);
    pokedata := nil;
    if dwread > 0 then begin
       //writeln('could read something'#13#10);
       setlength(s,dwread);
       cardinal(pend) := cardinal(buf) +dwread;
       while cardinal(buf) < cardinal(pend)-$64-(DIST2REC-1) do begin
          inc(pbyte(buf));
          // durchsuche speicher nach gewisser bytefolge die typisch ist
          if (pcardinal(buf)^ = $0) and (pbyte(cardinal(buf)+(DIST2REC-1))^ = $FF) and (pcardinal(cardinal(buf)+$64)^ = $0) and (pbyte(cardinal(buf)+$64+(DIST2REC-1))^ = $FF) then
          begin
            cardinal(pokeptr):= cardinal(buf);
            cardinal(pokedata) := START_OFFSET + cardinal(buf) - cardinal(@s[1]);
            writeln('pokemon list found at adress: ' + inttohex(cardinal(pokedata),8));
            writeln;
            break;
          end;
       end;
       if pokedata <> nil then begin
          writeln('pokemon #: CHP AHP ATT DEF INI SPA SPD');
          writeln('______________________________________');
          for j := 1 to 6 do begin
            writeln('pokemon '+inttostr(j)+':'+
            format(' %.3d %.3d %.3d %.3d %.3d %.3d %.3d',
            [ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.CHP,
             ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.AHP,
             ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.ATT,
             ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.DEF,
             ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.INI,
             ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.SPA,
             ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.SPD
            ])  );
          end;

          with ppokestat(@newstat)^ do begin
            CHP:=999;
            AHP:=999;
            ATT:=999;
            DEF:=999;
            INI:=999;
            SPA:=999;
            SPD:=999;
          end;
          if paramcount > 0 then c := paramstr(1)[1] else begin
            writeln(#13#10'please enter a pokemon number [1-6] that you want to boost or [0] to abort, [A] for all');
            readln(c);
          end;
          case c of
            '1'..'6' :
            if paramcount > 0 then hackstats(byte(c)-48)
            else begin
              writeln ('Automatic hack will set all values to 999'#13#10'manual hack will allow you to enter the values yourself'#13#10'type A for automatic or M for manual');
              read(d);
              if d in ['a','A'] then hackstats(byte(c)-48)
              else if d in ['m','M'] then begin
                 newstat := ppokestat(cardinal(pokeptr)+DIST2REC+(((byte(c)-48)-1)*$64))^;
                 pm:=@newstat.chp;
                 for j := 1 to 7 do begin
                   write('enter new value for ' + pokedef[j] + ', current: ' + inttostr(pm^) + ' :');
                   readln(nv);
                   pm^ := nv;
                   inc(pm);
                 end;
                 hackstats(byte(c)-48)
              end else writeln('wrong input');
            end;
            '0' : writeln('aborted');
            'A','a' : for j := 1 to 6 do hackstats(j);
            else haltp(1,'error - undefined input');
          end;
       end;
    end else writeln('couldnt read from target process');
    closehandle(hp);
    haltp(0,#13#10);
  end else haltp(1,'could not find VBA window');

end.

bundy 27. Apr 2006 08:58

Re: Speicherbereich einer Anwendung ermitteln
 
Hy danke für den Code.

lg
Bundy

Frickeldrecktuxer_TM 27. Apr 2006 09:58

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von brechi
Ja ne ist klar ^^. Wäre ja schlimm wenns nicht so wäre. ModuleHandle = BaseAdresse. Das ist bis XP 100% so.

So, bitte nochmal lesen, was ich geschrieben habe. Niemand garantiert mir, daß das so ist. Ein Handle ist ein Handle ist ein Handle, und kein Pointer. Daß die Zahlenwerte zufällig übereinstimmen ist nichts als reiner Zufall. Das kann sich jederzeit und von Architektur zu Architektur ändern (sollte es mal mehr als eine Architektur geben, die von MS unterstützt wird ;-)). Wenn du dich darauf verlassen willst, daß Microsoft niemals die Implementierung ändern wird, deine Sache, aber ich nehme lieber den Weg, der mir garantiert, daß ich einen Pointer auf die Basisadresse bekomme, und diese Garantie gibt mir die ToolHelp API.

SnuffMaster23 27. Apr 2006 16:56

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von Frickeldrecktuxer_TM
Nope, dein Weltbild hat gestimmt, aber du bist davon ausgegangen, daß WPM() in den physikalischen Speicher schreibt, bzw man Werte nur im physikalischen Speicher ändern kann.

Erstmal danke dass du mein Weltbild gerettet hast :D
Ich bin nicht von physikalischem Speicher ausgegangen, sondern eher davon, dass jedes Programm sich für das One-And-Only hält, also mit den anderen nichts zu tun hat

Snuffi

brechi 27. Apr 2006 18:17

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Daß die Zahlenwerte zufällig übereinstimmen ist nichts als reiner Zufall.
Da du dich ja anscheinend noch nicht mit der Windows Architektur auseinander gesetzt hast, kannst du mir unter Windows auch kein Gegenteil beweisen. Debug erstmal GetModuleHandle / GetProcAddress die ja beide Handles zurückgeben und schau was die genau machen.

Das Handles von Files/Processen nichts mit einer Addresse zu tun haben ist klar. Ich empfehle dir mal Windows95 Secrets von Matt Petriek, da erfährt man viel über den Aufbau von Windows.

Frickeldrecktuxer_TM 27. Apr 2006 18:41

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von brechi
Da du dich ja anscheinend noch nicht mit der Windows Architektur auseinander gesetzt hast, kannst du mir unter Windows auch kein Gegenteil beweisen. Debug erstmal GetModuleHandle / GetProcAddress die ja beide Handles zurückgeben und schau was die genau machen.

Nochmal lesen scheint wohl bei dir nicht zu helfen.
Mir ist sche**egal, wie etwas implementiert ist und wie es in der Realität aussieht. Es ist nicht in der API festgelegt, und das ist, was zählt. Microsoft kann in seiner nächsten Version kommen und die gesamte Debug-API umschreiben und die Handles zu Einträgen in irgendwelchen internen Lookup-Tables machen, und schon guckst du in die Röhre, weil dein Handle dir plötzlich nur noch sagt "Eintrag 42" und nicht mehr "Adresse $7411". Laut API ist das erlaubt, weil ein Handle kein Pointer auf die Basisadresse ist. Was aber nicht geht, ist, daß Microsoft in seiner nächsten Version plötzlich ganz andere Zahlen über die TollHelp-API zurückliefert, ganz einfach weil die API so definiert ist. Klar können sie die API ändern, aber davon kriegt man auch etwas mit. Die Sache mit den Handles merkt man entweder, indem man's ausprobiert, oder gar nicht.
Es ist ganz einfach eine Frage, ob ich Code schreiben will, der in irgendeiner Art und Weise definiertes Verhalten zeigt, oder ob er nur zufällig funktioniert und morgen bereits aufhören könnte, zu funktionieren.

Shaman 27. Apr 2006 20:45

Re: Speicherbereich einer Anwendung ermitteln
 
Hey there

Delphi-Quellcode:

uses
  tlhelp32;

function GetFirstModuleInfo(const ProcessId: Cardinal; out uModule: MODULEENTRY32): Boolean;
var
  hSnapShot: Cardinal;
begin
  Result:= False;
  hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
  if hSnapShot <> 0 then
  begin
    uModule.dwSize:= SizeOf(uModule);
    Result:= Module32First(hSnapShot, uModule);
    CloseHandle(hSnapShot);
  end;
end;

// uModule.modBaseAddr enthält die Basisadresse
Gruss
Shaman

brechi 28. Apr 2006 11:46

Re: Speicherbereich einer Anwendung ermitteln
 
Funktioniert nicht unter WinNT.
Leifert unter 9x nicht die Executable des Hauptprogramms.

Code:
 Wenn NT nutze Alternativfunktion anonsten nutze tlhelp32
Code:
  nutze GetModuleHandle, nutze eventl. unter Windows32Bit Betriebsystem was irgendwann mal nach Vista erscheint eine Alternativfunktion (evntl. tlhelp32)
tlhelp32 ist
1) langsamer
2) funktioniert auf NT nicht
3) umständlich


Zumal GMH auch nahmhafte Firmen/Leute benutzen. Genauso wahscheinlich wie die änderung der Handles ist die Entferung von den tlhelp funktionen, da Microdoft verstärkt Callback funktionen nutzt (EnumProcesses, EnumProcessModules) (Wegen Abwärtskompatibilität wird höchstwahrscheinlich weeder Base = Handle noch tlhelp32 verändert)

Auch hier müsste man dann für 9x/Nt Unterscheidungen machen.

Nun kann ja jeder einzelne sich darüber ein Bild machen, welche Methode er nutzen will.

himitsu 28. Apr 2006 11:58

Re: Speicherbereich einer Anwendung ermitteln
 
Also mit VirtualQuery kann man ja auch die Startposition eines Speicherblocks erfahren, also wäre es doch damit ebenfalls möglich, da die Dateien (EXE/DLL...) als eigenständige Speicherblöcke in dem Arbeitzsspeicher gemappt werden?

Delphi-Quellcode:
Var MBI: TMemoryBasicInformation;

P := irgendwas innerhalb des Moduls (z.B. der Pointer zu 'ner Funktion/Prozedur);
VirtualQuery(P, MBI, SizeOf(MBI));
BaseAddress := MBI.BaseAddress

Nicodius 28. Apr 2006 12:00

Re: Speicherbereich einer Anwendung ermitteln
 
sind trainer überhaupt legal?

:|für welches spiel ist es denn?

brechi 28. Apr 2006 12:20

Re: Speicherbereich einer Anwendung ermitteln
 
@himitsu

Die Idee daran ist nicht schlecht (wenn auch ein bisschen alt ;) ).
Richtig müsste es aber lauten:
Delphi-Quellcode:
  MBI.AllocationBase
Da (so viel ich weiß) MBI.BaseAddress die Base von der Section zurückliefert.

lpBuffer.AllocationBase liefert einen Pointer zurück, mit dem man (meiner MEinugn nach) problemlos in ein DWOrd umwandeln kann um dann z.b. mit GetProcAddress / GetModuleFileName etc. weitere Daten zu ermitteln.

Um aber die Base für einen Trainer umzurechnen, reicht es aber allemal.

himitsu 28. Apr 2006 12:39

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von brechi
lpBuffer.AllocationBase liefert einen Pointer zurück, mit dem man (meiner MEinugn nach) problemlos in ein DWOrd umwandeln kann um dann z.b. mit GetProcAddress / GetModuleFileName etc. weitere Daten zu ermitteln.

Jupp, dat is möglich ... 's nutze ich z.B. in meinem MM um den Namen des Moduls (falls vorhanden) zu ermitteln ^^

Und warum muß altes denn immer gleich schlecht sein (vom Code her ist es jedenfalls viiiiieeeellll übersichtlicher :roll: )

bundy 28. Apr 2006 12:39

Re: Speicherbereich einer Anwendung ermitteln
 
Zitat:

Zitat von Nicodius
sind trainer überhaupt legal?

:|für welches spiel ist es denn?

Harry Potter und der Feuerkelch.

Ob es legal ist keine Ahnung. :gruebel:
Da es ja kein Online Game ist, denke ich nicht, daß es jemanden stöhren wird. :angel: (Die Hoffnung stirbt zuletzt) :angel:

Wenn wer Interesse hat, poste ich ihn auch. Ich hoffe die DP hat da nix dagegen. :roll:

lg
Bundy

brechi 28. Apr 2006 12:55

Re: Speicherbereich einer Anwendung ermitteln
 
Mit alt meinte ich nicht, schlecht sondern einfach schon oft benutzt und bewährt :)

c113plpbr 28. Apr 2006 13:54

Re: Speicherbereich einer Anwendung ermitteln
 
Trainer sind in Singelplayerspielen definitiv legal, soweit sie nur im speicher arbeiten, sobald du die ausführbare datei des programms/spiels veränderst geht die sache in den bereich der illegalität ...

... zumindest meines wissens nach.

(ansonsten wäre unter win9x systemen ja jedes programm, dass "ausversehen" durch einen fehler auf fremden speicher zugreift illegal ... :mrgreen: )

ciao, Philipp

himitsu 28. Apr 2006 15:03

Re: Speicherbereich einer Anwendung ermitteln
 
Wir fiel da gerade mal wieder was ein ... 's paßt ja so gut hierzu und vielleicht hilft's etwas

Tutorials und Kurse -> IMAGEBASE - wichtiges zu DLL und Co.


PS: @brechi ... hattest Recht ... MBI.AllocationBase :roll: (na ja, ich darf doch auch mal was vergessen, oder nicht?)

Christian Seehase 30. Apr 2006 02:49

Re: Speicherbereich einer Anwendung ermitteln
 
Moin Bundy,

kann es sein, dass Dein Freund einfach nur einen anderen Patchlevel des Spieles installiert hat, und sich, durch den geänderten Code, auch die Adressen bei ihm geändert haben?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz