Home of Gamehacking
Kleine Hilfe zu WriteProcessMemory gesucht... - Druckversion

+- Home of Gamehacking (http://homeofgamehacking.de)
+-- Forum: Coding (http://homeofgamehacking.de/forumdisplay.php?fid=15)
+--- Forum: Delphi (http://homeofgamehacking.de/forumdisplay.php?fid=20)
+--- Thema: Kleine Hilfe zu WriteProcessMemory gesucht... (/showthread.php?tid=1175)

Seiten: 1 2 3 4 5 6 7


Kleine Hilfe zu WriteProcessMemory gesucht... - darius83 - 04.09.2012

Huhu Leute, bin neu hier und hab mir gedacht, ich frag einfach mal Wink

Also, ich habe mir mal zum Rumspielen von Command & Conquer - Generals
die Adresse für mein momentanes Vermögen rausgesucht. Dazu hab ich mit CE einen Pointer+Offsets rausgesucht. Jetzt möchte ich mit Delphi ein Fenster erstellen, in dem mein momentanes Gold angezeigt und bei Buttonklick dieses um Summe X erhöht wird. Getestet hab ichs mit CE schon, da klapps, also Pointer und Offsets sind richtig. Den momentanen Wert mit Delphi auslesen klappt auch, aber wenn ich diesen Wert einfach überschreibe, schmeisst das Spiel mich mit einer Fehlermeldung raus. Vielleicht kann mir da ja jemand helfen...

Hier mal, wie ich das ganze getestet habe:
Ich hab die auskommentierten Stellen mal drin gelassen, weil ich an der Stelle getestet habe, was passiert, aber es kam bisher immer der selbe Spielabbruch dabei heraus.

Code:
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Gold: TLabel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
const
  process = 'game.dat';

function GetID(Const ExeFileName: string; var ProcessId: integer): boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  result := false;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  while integer(ContinueLoop) <> 0 do begin
	if (StrIComp(PChar(ExtractFileName(FProcessEntry32.szExeFile)), PChar(ExeFileName)) = 0)
	   or (StrIComp(FProcessEntry32.szExeFile, PChar(ExeFileName)) = 0)  then begin
	   ProcessId:= FProcessEntry32.th32ProcessID;
	   result := true;
	   break;
	end;
	ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Pid: Integer;
  Pidhandle: Integer;
  Address: Cardinal;
  NewValue: Integer;
  lBuf: Integer;
  Data: Integer;
  Written: Cardinal;
begin
  Pid := 0;
  Written := 4;
  Address := $0096c9b0;
  NewValue := $0186A0;
  Data := 4;
  if GetID(process, Pid) then begin
    Pidhandle := OpenProcess(PROCESS_ALL_ACCESS,False,Pid);
    try
      ReadProcessMemory(Pidhandle, Pointer(Address), @lBuf, Data, Written);
      lBuf:= lBuf+$0C;
      ReadProcessMemory(Pidhandle, Pointer(lBuf), @lBuf, Data, Written);
      lBuf:= lBuf+$34;
      ReadProcessMemory(Pidhandle, Pointer(lBuf), @lBuf, Data, Written);
      //if lBuf < 50000 then
        //WriteProcessMemory(Pidhandle, Pointer(Address), @NewValue, Data, Written);
      Gold.Caption := 'Gold : '+IntToStr(lBuf);
      sleep(5000);
      //Showmessage(IntToStr(lBuf));
      //WriteProcessMemory(Pidhandle, Pointer(Address), @NewValue, Data, Written);
    finally
      closehandle(Pidhandle);
    end;
  end;
end;

end.




RE: Kleine Hilfe zu WriteProcessMemory gesucht... - Mydayyy - 05.09.2012

Seh ich das richtig, dass deine Adresse in lBuf liegt du aber mit WPM nach Address schreibst?


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - darius83 - 05.09.2012

OMG ja du hast recht... Was ich doch für ein Blindfrosch bin... Hab vergessen, Adress zu ändern... hab den Befehl so benutzt, als ich noch auf eine Adresse direkt zugegriffen habe, ohne Offsets :/ Sowas blödes... Werds gleich mal testen und schaun, ob es dann klappt...

Schonmal danke für die Hilfe Wink

Edit1: Ja danke, hat jetzt geklappt... Werd demnächst mal den richtigen Code posten, wenns alles so ist, wie es soll Wink Vielleicht kanns ja jemand gebrauchen.


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - darius83 - 05.09.2012

Hier mal wie versprochen, mein aktualisierter Code...
Nach dem Klick auf den Button wird ein Timer gestartet, der jede Sekunde prüft, ob das Spiel geöffnet ist und wenn ja, wie der Kontostand ist.
Sobald der Kontostand > 0 ist, wird gepüft, ob der Kontostand > 10000 ist.
Sinkt der Kontostand darunter, wird er automatisch auf 15000 erhöht.
Ein erneuter Klick auf den Button stoppt den Timer wieder.

Viel Spaß damit Wink

[code=delphi]
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Gold: TLabel;
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
const
process = 'game.dat';

function GetID(Const ExeFileName: string; var ProcessId: integer): boolean;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
result := false;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while integer(ContinueLoop) <> 0 do begin
if (StrIComp(PChar(ExtractFileName(FProcessEntry32.szExeFile)), PChar(ExeFileName)) = 0)
or (StrIComp(FProcessEntry32.szExeFile, PChar(ExeFileName)) = 0) then begin
ProcessId:= FProcessEntry32.th32ProcessID;
result := true;
break;
end;
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

function GetAdress(Pidhandle: Integer; BasePointer: Cardinal; Offsets: Array of Cardinal) : Cardinal;
var
i, Anzahl, Data: Integer;
Written: Cardinal;
begin
Written := 4;
Data := 4;
Result := BasePointer;
Anzahl := High(Offsets);
if Anzahl = 1 then
Result := Result + Offsets[1]
else begin
for i := 1 to Anzahl do begin
ReadProcessMemory(Pidhandle, Pointer(Result), @Result, Data, Written);
Result := Result + Offsets[i];
end;
end;
end; // function GetAdress

procedure TForm1.Button1Click(Sender: TObject);

begin
if Timer1.Enabled then
Timer1.Enabled := False
else
Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
Pid: Integer;
Pidhandle, lBuf, lBuf2, NewValue, Data: Integer;
Address, Written: Cardinal;
Offsets: Array of Cardinal;
begin
Pid := 0;
Data := 4;
Address := $0096c9b0;
SetLength (Offsets, 3);
Offsets[1] := $0C;
Offsets[2] := $34;
NewValue := $3A98;
if GetID(process, Pid) then begin
Pidhandle := OpenProcess(PROCESS_ALL_ACCESS,False,Pid);
try
lBuf := GetAdress(Pidhandle, Address, Offsets);
ReadProcessMemory(Pidhandle, Pointer(lBuf), @lBuf2, Data, Written);
if lBuf2 > 0 then
if lBuf2 < 10000 then
WriteProcessMemory(Pidhandle, Pointer(lBuf), @NewValue, Data, Written);
Gold.Caption := 'Gold : '+IntToStr(lBuf2);
finally
closehandle(Pidhandle);
end;
end;
SetLength (Offsets, 0);
end;

end.
[/code]


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - iNvIcTUs oRCuS - 05.09.2012

Also ich würde das definitiv anders lösen.
Z.B. mit Hotkeys...
Und zweitens würde ich dennoch eine Codecave vorziehen. Weil zum einen der permanente Zugriff durch den Trainer vermieden wird und weil so keine "komischen" Effekte beim neuschreiben des Wertes auftreten.

Naja und die Sache mit dem Label macht für mich nicht wirklich Sinn.
Seh ich doch im Spiel sowieso obs geklappt hat oder nicht.


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - darius83 - 05.09.2012

(05.09.2012, 16:21)sILeNt heLLsCrEAm schrieb: Also ich würde das definitiv anders lösen.
Z.B. mit Hotkeys...
Ja ist ne Möglichkeit, die man realisieren könnte, aber ich persönlich wollte es ohne Tastendruck haben Wink
(05.09.2012, 16:21)sILeNt heLLsCrEAm schrieb: Und zweitens würde ich dennoch eine Codecave vorziehen. Weil zum einen der permanente Zugriff durch den Trainer vermieden wird und weil so keine "komischen" Effekte beim neuschreiben des Wertes auftreten.
Von Codecaves habe ich noch so gut wie keine Ahnung... Vielleicht erklärst du mir ja mal, was du damit meinst, bzw. wie so etwas funktioniert.
Und was meinst du mit "komischen" Effekte?
(05.09.2012, 16:21)sILeNt heLLsCrEAm schrieb: Naja und die Sache mit dem Label macht für mich nicht wirklich Sinn.
Seh ich doch im Spiel sowieso obs geklappt hat oder nicht.
Das stimmt, aber ich habs für mich einfach anzeigen lassen, um zu kontrollieren, ob der Wert auch stimmt. Im Prinzip überflüssig.

LG Darius83




RE: Kleine Hilfe zu WriteProcessMemory gesucht... - iNvIcTUs oRCuS - 05.09.2012

(05.09.2012, 18:17)darius83 schrieb: Ja ist ne Möglichkeit, die man realisieren könnte, aber ich persönlich wollte es ohne Tastendruck haben Wink
Dazu musst Du aber immer aus dem Spiel tabben wenn Du's nicht im Fenster Modus laufen lässt Wink
Wäre für mich keine gute Wahl.

(05.09.2012, 18:17)darius83 schrieb: Von Codecaves habe ich noch so gut wie keine Ahnung... Vielleicht erklärst du mir ja mal, was du damit meinst, bzw. wie so etwas funktioniert.
Und was meinst du mit "komischen" Effekte?
Komische Effekte...
In diesem speziellen Fall wirds kaum solche Effekte geben da Du ja den Wert erst schreibst wenn ein gewisser Wert unterschritten wurde. Mit anderen Worten, Du tust ja den Wert nicht permanent freezen.
Würdest Du den Timer Wert etwas hochschrauben und den Wert permanent freezen dann würdest Du den Effekt im Spiel haben das die Geldsumme sagen wir mal unruhig dargestellt wird.

Codecaves...
Zum einen sei Dir mal Acubras Codecave Tutorial ans Herz gelegt.

Zum anderen könnte dich auch diese Tutorials interessieren...
Pointer Tutorial
Codecave Tutorial - Ghost Recon: Advanced Warfighter

grEEtZ sILeNt heLLsCrEAm


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - darius83 - 05.09.2012

Ok das mit dem Tabben ist ein Argument...
Aber wozu? XD Trainer starten, Timer starten, Spiel starten, sich in jedem Spiel über einen Kontostand von mindestens 10k Gold freuen, Spiel beenden, Timer stoppen, Trainer beenden.
Brauch ich kein TAB für Happy
Wie gesagt, der Trainer ist auf mich persönlich zugeschnitten, Source ist free, also wems nicht gefällt, darf gern dran rumbasteln.
Aber eventuell mach ich nochmal ne Version fertig mit Shortcut. Mal schaun, was sich so ergibt Wink

Was diese komischen Effekte angeht, solange sie nicht auftreten, ist doch alles ok... Meine Meinung, aber ich werds mir trotzdem nochmal anschaun.

Die Tuts werd ich mir auf jeden Fall mal anschaun, man will ja was dazulernen Wink

LG Darius83

Edit: Hab mir die Tuts mal angeschaut... Also wirklich helfen tut mir das jetzt nicht gerade...
Kann man diese Caves auch mit Delphi machen, oder ist das nur mit CE möglich?
Wenn man mit CE einen Cave erstellt, wird der dann nur angewendet, wenn CE läuft?

Ausserdem seh ich da wirklich nicht so den Vorteil drin, einen Cave zu benutzen...
In diesem speziellen Fall von mir vielleicht ok, aber wenn ich die ausgelesenen Daten
nicht nur ändern, sondern auch irgendwo ausgeben will, komm ich mit einen einfachen
Cave nicht mehr hin, es sei denn ich schreibe im Cave ein komplett neues Fenster zur Ausgabe,
was mir dann doch ein wenig zu kompliziert ist... Dazu verstehe ich viel, viel zu wenig vpon ASM XD


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - iNvIcTUs oRCuS - 05.09.2012

(05.09.2012, 20:16)darius83 schrieb: Ok das mit dem Tabben ist ein Argument...
Aber wozu? XD Trainer starten, Timer starten, Spiel starten, sich in jedem Spiel über einen Kontostand von mindestens 10k Gold freuen, Spiel beenden, Timer stoppen, Trainer beenden.
Brauch ich kein TAB für Happy
Brauch ich kein "Timer starten/stoppen" Button für Wink


RE: Kleine Hilfe zu WriteProcessMemory gesucht... - iNvIcTUs oRCuS - 06.09.2012

(05.09.2012, 20:16)darius83 schrieb: Edit: Hab mir die Tuts mal angeschaut... Also wirklich helfen tut mir das jetzt nicht gerade...
Kann man diese Caves auch mit Delphi machen, oder ist das nur mit CE möglich?
Wenn man mit CE einen Cave erstellt, wird der dann nur angewendet, wenn CE läuft?

Also im Bezug auf diese Aussage frage ich mich ernsthaft wie Du es geschafft hast einen Trainer zu schreiben?!
In deinem Trainer nutzt Du doch auch die WriteProcess API. Damit lassen sich nicht nur einfache Adressen beschreiben...

(05.09.2012, 20:16)darius83 schrieb: Ausserdem seh ich da wirklich nicht so den Vorteil drin, einen Cave zu benutzen...
In diesem speziellen Fall von mir vielleicht ok, aber wenn ich die ausgelesenen Daten
nicht nur ändern, sondern auch irgendwo ausgeben will, komm ich mit einen einfachen
Cave nicht mehr hin, es sei denn ich schreibe im Cave ein komplett neues Fenster zur Ausgabe,
was mir dann doch ein wenig zu kompliziert ist... Dazu verstehe ich viel, viel zu wenig vpon ASM XD

Und wie willst Du das bei einem Spiel lösen wo Pointer nicht so ohne weiteres möglich sind???
Eine Adresse auslesen kann man auch durch eine Codecave. Man filtert die Adresse die man sucht und schreibt diese in eine "bestimmten" Speicherzelle. Und diese Speicherzelle wiederrum kann man mit dem Trainer auslesen. Also nichts mit extra Fenster in ASM Bauweise...