Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Trainer mit Delphi Coden (https://www.delphipraxis.net/142407-trainer-mit-delphi-coden.html)

Rusher.Nr1 27. Okt 2009 16:29


Trainer mit Delphi Coden
 
Hi Leute ich hab mich mal vor na ganzen weile mit Delphi beschäftigt und diese standard sachen Programmiert für Anfänger wie Taschenrechner oder InternetBrowser und son Zeugs.

Jetzt hab ich in letzterzeit für verschiedene Programme Trainer mit dem Programm Cheat-Engine Programmiert. Und da kam mir die Frage in denn Sinn ob ich das nicht auf einfach in Delphi machen könnte?

Ich meine man Brauch ja nur 2 Dinge eigentlich.

1. Wie attacke ich ein laufenden Prozess? (am besten Automatisch)
und
2. Wie kann ich da ein Script einfügen?

Beispiel zu 2: (Original aus CE)
Zitat:

[enable]
alloc(Funktion, 337)
label(dontReset)
Funktion:
push ecx
mov ecx,[99df5c]
cmp [ecx+15BC], 61
jle dontReset
dec [ecx+638]
dontReset:
pop ecx
cmp eax,edi
mov [ebp-20],eax
ret
007bd1e9:
call Funktion
[disable]
007bd1e9:
cmp eax,edi
mov [ebp-20],eax
dealloc(Funktion, 337)
Wehre Super wenn ihr mir da Helfen könntet.

bugfix 6. Feb 2010 16:46

Re: Trainer mit Delphi Coden
 
Das Thema ist zwar schon älter, aber vllt. findets ja jemand nützlich.

Alles was du tun musst, um dein Cheat Engine Script in einen Trainer zu packen, ist die Bytes deiner Befehle an die entsprechenden Memory Adressen zu schreiben.

Die entsprechenden Bytes für jeden Befehl kannst du im Memory View von Cheat Engine sehen.
Beispiel:

Delphi-Quellcode:
00 b8 c3 50 00 34
ist gleich
Delphi-Quellcode:
add [eax+340050c3],bh
In deinem Trainer wirst du konkret folgendes brauchen:

1.) Eine function, mit der du die Prozess-ID des Spieles herausfinden kannst:

Delphi-Quellcode:
function GetProcessID(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;
2.) Procedures, mit denen du deine Bytes in den Speicher schreibst.

Diese hier benutze ich für NOPs
Delphi-Quellcode:
procedure poke1(Address: Cardinal; Data: Byte);
var
  Written: Cardinal;
begin
  WriteProcessMemory(PidHandle, Pointer(Address), @Data, SizeOf(Data), Written);
end;
Nutzungsbeispiel:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
 if GetProcessID(ProgramName, PidId) then
  begin
   PidHandle := OpenProcess(PROCESS_ALL_ACCESS,False,PidId);
   poke1($41ba76, $90);
   poke1($41ba76 + 1, $90);
   poke1($41ba76 + 2, $90);
   poke1($41ba76 + 3, $90);
   poke1($41ba76 + 4, $90);
   poke1($41ba76 + 5, $90);
  closehandle(PidHandle);
 end;
end;
Hier schreibe ich an die Adresse 41ba76 und die 5 danach das Byte 90, also No Operation.
ProgramName ist dabei eine Konstante, die den Prozessnamen deines Spiels enthält
Delphi-Quellcode:
Const
  ProgramName = 'hl2.exe';
Die folgende Procedure nutze ich, wenn ich mehr als ein Byte in eine Adresse schreibe
Delphi-Quellcode:
procedure pokeX(Address: Cardinal; Data: Array of Byte);
var
Written: Cardinal;
begin
  WriteProcessMemory(PidHandle, Pointer(Address), @Data, SizeOf(Data), Written);
end;
Beispiel
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
 if GetProcessID(ProgramName, PidId) then
  begin
   PidHandle := OpenProcess(PROCESS_ALL_ACCESS,False,PidId);
     SetLength(byteArr, 4);
  byteArr[0] := $C7;
   byteArr[1] := $45;
   byteArr[2] := $48;
   byteArr[3] := $01;
  pokeX($81B0000, byteArr);
  SetLength(byteArr, 4);
  byteArr[0] := $80;
   byteArr[1] := $7d;
   byteArr[2] := $48;
   byteArr[3] := $00;
  pokeX($81B0007, byteArr);
  poke1($81B000B, $56);
  SetLength(byteArr, 5);
  byteArr[0] := $e9;
   byteArr[1] := $3e;
   byteArr[2] := $82;
   byteArr[3] := $2d;
  byteArr[4] := $F8;
  pokeX($81B000C, byteArr);
   SetLength(byteArr, 5);
   byteArr[0] := $E9;
   byteArr[1] := $B1;
   byteArr[2] := $7D;
   byteArr[3] := $d2;
   byteArr[4] := $07;
   pokeX($48824A, byteArr);

    closehandle(PidHandle);
 end;
end;
Das wars auch schon ;)

implementation 6. Feb 2010 18:49

Re: Trainer mit Delphi Coden
 
Müsste es nicht auch so gehen?
Delphi-Quellcode:
pokeX(Address, [Wert1, Wert2, Wert3]);
Stichwort: Offene Arrays.

Astat 6. Feb 2010 19:04

Re: Trainer mit Delphi Coden
 
Zitat:

Zitat von Rusher.Nr1
.. Programm Cheat-Engine..Und da kam mir die Frage in denn Sinn ob ich das nicht auf einfach in Delphi machen könnte?

Hallo Rusher.Nr1, das Progtamm "Cheat-Engine" ist überwiegend in Delphi geschrieben.
Sourcecode ist unter: http://www.cheatengine.org/downloads.php

lg. Astat

bugfix 6. Feb 2010 20:05

Re: Trainer mit Delphi Coden
 
Zitat:

Zitat von implementation
Müsste es nicht auch so gehen?
Delphi-Quellcode:
pokeX(Address, [Wert1, Wert2, Wert3]);
Stichwort: Offene Arrays.

In der Tat, es funktioniert. Danke dir!

brechi 6. Feb 2010 20:59

Re: Trainer mit Delphi Coden
 
Wundter mich dass SizeOf(Data) funktioniert (meiner Meinung nach sollte dies immer 4 ergeben). Bei dynamischen Array solltest besser:
SizeOf(Data[1]) * Length(Data) verwenden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:13 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