Entwickler-Ecke

Windows API - Inkorrekte Werte bei ReadProcessMemory


Barney - So 31.08.08 15:48
Titel: Inkorrekte Werte bei ReadProcessMemory
Hallo Community :D,
Ich beschäftige mich seit einiger Zeit mit Delphi und bin gerade dabei mir ein kleines Automatisierungsprogramm für MineSweeper zu schreiben.
Zu aller erst habe ich vor die Größe des Feldes auszulesen. Also habe ich die Minesweeper.exe mit Cheatengine geöffnet und den Static Pointer für die Höhe des Feldes herausbekommen($10056A8 und $01005338). Jedoch bekomme ich beim auslesen immer den selben , falschen , Wert heraus. (Auch wenn Minesweeper nicht gestartet ist , es is und bleibt der falsche Wert)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
window,processid,minehandle,temp: Cardinal;

buffer : Pinteger;


const
title = 'MineSweeper';
address = $01005338;
begin

window := FindWindow(nil , title);
GetWindowThreadProcessID(window,@processid);
minehandle := OpenProcess(PROCESS_VM_READ,false,processid);

//getmem(buffer,4);

ReadProcessMemory(minehandle,pointer(address),buffer,2,temp);
edit1.Text:= inttostr(integer(buffer));

end;

end.


Ich bin für jeden Lösungsansatz dankbar :)

Mfg
Barney

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt


Delete - So 31.08.08 16:02

Der Link hilft dir bestimmt:http://www.delphi-library.de/topic_Spiele+Trainer+erstellen_34077.html :wink:


Barney - So 31.08.08 16:13

Danke für die Antwort.
Jedoch kenne ich diesen Thread schon und habe auch mit ihm gearbeitet jedoch hat er mir nicht weiter geholfen.

Was noch ganz interessant ist:

Wenn ich 'getmem' in meinem Code auskommentiere erhalte ich einen Wert der bei 444000 liegt.
Wenn ich es nicht auskommentiere erhalte ich einen Wert der bei 900000 liegt und für jeden Klick auf den button erhöht sich der Wert um 12.


Mfg
Blackfog


uall@ogc - So 31.08.08 16:18


Delphi-Quelltext
1:
2:
var buffer: integer;
ReadProcessMemory(minehandle,pointer(address),@buffer,2,temp);



Desweiteren hilft dir der Rückgabewert der Funktion (erfolgreich ausgeführt) temp (wie viel wurde wirklich gelesen) und GetLastError (wo war der Fehler)

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt


Barney - So 31.08.08 16:29

Danke uall das war ein ziemlich hilfreicher Denkanstoß. :)

Der Returnwert von temp ist 2. Somit sollten 2 Bytes gelesen worden sein.
Der Returnwert von GetLastError ist 0.
Der Returnwert der ReadProcessMemory Funktion ist -1.

Jedoch kommen bei der Änderung die du vorgeschlagen hast auch nur seltsame Werte heraus.

Mfg
Barney


elundril - So 31.08.08 16:35

auch wenns ne blöde frage ist aber woher weißt du die adresse von minesweeper?? ist die immer gleich?


Barney - So 31.08.08 16:40

Ja die Addressen sind statisch. Das habe ich 1.) Selbst durch Cheatengine gesehen und 2.) Auf einer anderen Seite bestätigen können :D.

Mfg
Barney


Delete - So 31.08.08 16:51

Ich würde statt Cheat-Engine lieber tsearch nehmen.Man könnte allerdings auch HxD aus der EE nehmen.
Bevorzuge ich sogar.


Barney - So 31.08.08 17:06

Also die richtige Adresse ist 010056A8. Wenn ich diese in CE änder , ändert sie sich auch im Spiel.

Mfg
Barney


uall@ogc - So 31.08.08 21:28

also gehts jetzt mit der adresse? oben hast ja ne andere verwendet

übrigens statt 2 solltest du SizeOf nehmen. und fürn integer dann SizeOf(Integer) was 4 wäre.
wenn nur ein byte lesenn willst nimmst halt nen byte


Barney - Mo 01.09.08 17:45

Moin,
Also auch mit der anderen Adresse funktioniert das ganze nicht. Ich versteh einfach nicht warum -.-". Die Adresse sollte richtig sein. Das habe ich selbst herausgefunden und auf einer anderen Seite bestätigen können.

Zitat:

Quelltext
1:
2:
3:
4:
5:
6:
As you can see from the code I've discovered 4 important things:

   1. Reading the memory in address [0x1005334] gives me the Width of the map.
   2. Reading the memory in address [0x1005338] gives me the Height of the map.
   3. Reading the memory in address [0x1005330] gives me the number of mines in the map.
   4. Given x,y that represents a cell in the map, in column x, row y, the address [0x1005340 + 32 * y + x] gives me the cell value.


Quelle: http://www.codeproject.com/KB/trace/minememoryreader.aspx

Mfg
Barney


Delete - Mo 01.09.08 18:04

MineHandle muss Integer sein.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Und es fehlt CloseHandle()


Barney - Mo 01.09.08 18:23

Ändert nichts ;(.
Weder das ändern des Handle Typs , noch das das schließen des Handles am Ende.

Mfg
Barney


Chryzler - Mo 01.09.08 18:29

Also ich hab deinen Code mal schnell nach C++ übersetzt und ausprobiert (hab grad Delphi nicht installiert) und hab die korrekte Größe bekommen. :?


Barney - Mo 01.09.08 18:31

Ähmm ja :D.
Villeicht sollte ich doch wieder zu c++ wechseln oO bzw. mich dem mal richtig zuwenden.
Komisch Komisch.
Hast du als Adresse $010056A8 genommen ?

Mfg
Barney


Chryzler - Mo 01.09.08 18:36

Sowohl $01005338 als auch $010056A8 scheinen die Höhe zurückzuliefern. Hast du die zu lesende Größe bei ReadProcessMemory auch auf 4 geändert, so wie es user profile iconuall@ogc geschrieben hat? Ein Integer hat 32 Bits, also 4 Bytes, keine 2.


Barney - Mo 01.09.08 18:38

Jop hab das ganze auch geändert... Ich setzt mich mal dran und bastel das ganze mal in c++...


uall@ogc - Mo 01.09.08 18:41

die Adresse ist auch abhänging von der Version des Spiels (Unter 2k / XP / Vista verschieden und auch SP<x> verschieden)


Chryzler - Mo 01.09.08 18:47

user profile iconuall@ogc hat folgendes geschrieben:
die Adresse ist auch abhänging von der Version des Spiels (Unter 2k / XP / Vista verschieden und auch SP<x> verschieden)

Naja, er hat ja die Adresse selber überprüft dass sie stimmt.

Probiers mal so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);  
var  
  window, processid, minehandle, temp: Cardinal; 
  buffer: Integer; 
const  
  title = 'MineSweeper';  
  address = $01005338;  
begin   
  window := FindWindow(nil, title);  
  GetWindowThreadProcessID(window, @processid);  
  minehandle := OpenProcess(PROCESS_VM_READ, false, processid);   
  ReadProcessMemory(minehandle, Pointer(address), @buffer, SizeOf(buffer), temp);
  CloseHandle(minehandle);
  Edit1.Text := IntToStr(buffer);   
end;


Barney - Mo 01.09.08 19:15

So hab mich grade mal dran gesetzt und habe das ganze in C++ gezimmert und siehe das : Es klappt perfekt :D

@ Chryzler
Dein Code funktioniert wunderbar , Danke :D.
Wo jetzt mein Fehler lag muss ich nochmal analysieren oO .

Vielen Dank an dich auf jeden Fall.

Mfg
Barney