• Trainer
  • Forums
  • Suche
  • Members
  • Kalender
  • Hilfe
  • Extras
Forum stats
Show team
Neue Beiträge ansehen
Heutige Beiträge ansehen
Home of Gamehacking - Archiv
Login to account Create an account
Login
Benutzername:
Passwort: Passwort vergessen?
 



  Home of Gamehacking - Archiv Coding Delphi Kleine Hilfe zu WriteProcessMemory gesucht...

Seiten (7): « Zurück 1 2 3 4 5 ... 7 Weiter »
Ansichts-Optionen
Kleine Hilfe zu WriteProcessMemory gesucht...
iNvIcTUs oRCuS Offline
Super Moderator
****
Beiträge: 2.688
Themen: 529
Registriert seit: Aug 2010
Bewertung: 19
#21
09.09.2012, 01:29
Diese Diskussion sollten wir lieber im Gamehacking Forum weiterführen da wir an dieser Stelle zu sehr ins Offtopic geraten.
Ich denke mal das Du, so wie Du schreibst, auch schon einen Spiele Titel hast bei dem Du mit dem Suchen einer Adresse nicht weiterkommst.
Dann poste doch einfach mal einen Thread wie gesagt im Gamehacking Forum und da können wir weiter drüber philosophieren Wink
Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer !!!

Traineranfragen per PM werden prinzipiell gelöscht...

[Bild: signatur6akm7.gif]
Suchen
Antworten
darius83 Offline
Junior Member
**
Beiträge: 34
Themen: 2
Registriert seit: Sep 2012
Bewertung: 0
#22
09.09.2012, 18:35
Soo, ich habe mal geschaut, wie ich das ganze mit einer Codecave lösen könnte, habe dann 2 Adressen gefunden:

game.dat+166D77 - 89 46 04 - mov [esi+04],eax // Geld wird durch sammeln erhöht.

game.dat+166CD5 - 89 47 04 - mov [edi+04],eax // Geld wird durch ausgeben gesenkt.

Rein theoretisch kann ich ja jetzt an beiden einen Jump schreiben und eax dann auf einen festen Wert setzen (mov eax,3A98 z.B.). Mit CE klappt das ganze auch wunderbar Wink

aber wie realisiere ich das ganze jetzt in Delphi, damit ich nicht jedes mal wieder in CE die beiden Adressen raussuchen muss und anschliessend die Codecave in CE eingeben muss? Also, wie sage ich Delphi, an welcher Stelle die Bytes für die CodeCave geschrieben werden müssen, irgendwie muss ich ja da auch den entsprechenden Adresswert finden, oder schreibe ich das ganze immer an die selbe Stelle?

LG Darius83

Es gibt 10 verschiedene Typen von Personen, die, die ich mag und die, die ich nicht verstehen kann...
Suchen
Antworten
Acubra Offline
Trainermaker
****
Beiträge: 904
Themen: 127
Registriert seit: Oct 2010
Bewertung: 6
#23
09.09.2012, 20:37
Hey,
starte das Spiel doch einfach neu und gucke ob sich die Offsets (166D77, 166CD5) verändert haben. Wenn nicht, dann werden die Adressen (abhängig von der Baseadresse der game.dat) immer die gleichen sein. Somit kannst du dann auch per WriteProcessMemory einfach deine Bytes schreiben.
Du musst natürlich zuerst die BaseAdresse herausfinden und darauf dann das jeweilige Offset addieren, um zur eigentlichen Adresse zu kommen (vorausgesetzt die BaseAdresse der game.dat ändert sich bei jedem Neustart).
"Auf dieser Welt gibt es mehr Scheisse als auf Festivalklos"
[Bild: hoglogo_smalpxga.jpg]
Homepage Suchen
Antworten
darius83 Offline
Junior Member
**
Beiträge: 34
Themen: 2
Registriert seit: Sep 2012
Bewertung: 0
#24
09.09.2012, 22:49 (Dieser Beitrag wurde zuletzt bearbeitet: 09.09.2012, 23:13 von darius83.)
Hmmm und wieso funktioniert das hier nicht?

[code=delphi]
WriteProcessMemory(Pidhandle, Pointer($00566d77),Pointer($E98492D201) , 5, Written);
[/code]

Written gibt imer 0 aus...
Es gibt 10 verschiedene Typen von Personen, die, die ich mag und die, die ich nicht verstehen kann...
Suchen
Antworten
iNvIcTUs oRCuS Offline
Super Moderator
****
Beiträge: 2.688
Themen: 529
Registriert seit: Aug 2010
Bewertung: 19
#25
10.09.2012, 00:32 (Dieser Beitrag wurde zuletzt bearbeitet: 10.09.2012, 00:33 von iNvIcTUs oRCuS.)
Das kann auch nicht funktionieren...
Anstelle von "Pointer($E98492D201)" erwartet die Funktion die Daten die geschrieben werden sollen. In deinem Fall weiß die Funktion nichts damit anzufangen.
Ich würde das der Funktion als Array übergeben. Ist eigentlich am einfachsten.
Ich lass mich natürlich gerne auch eines Besseren belehren.

Das würde dann z.B. so aussehen.
[code=Delphi]var
JMPCC: array [0..4] of byte = ($E9, $84, $92, $D2, $01);
Written: SIZE_T;
begin
WriteProcessMemory(Pidhandle, Pointer($00566d77), @JMPCC, 5, Written);
end;[/code]


(09.09.2012, 18:35)darius83 schrieb: Rein theoretisch kann ich ja jetzt an beiden einen Jump schreiben und eax dann auf einen festen Wert setzen (mov eax,3A98 z.B.). Mit CE klappt das ganze auch wunderbar.
Aber bedenke... Das funktioniert nur wenn auch nur die Geldadresse durch diese Befehle laufen. Wenn durch diese Befehle auch Adressen laufen die für das Spiel von anderen Nöten sind kann es sein das es crasht. Sowas muss nicht immer sofort passieren, kann aber z.B. beim Level laden oder im Home Screen vorkommen. Je nachdem halt...
Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer !!!

Traineranfragen per PM werden prinzipiell gelöscht...

[Bild: signatur6akm7.gif]
Suchen
Antworten
darius83 Offline
Junior Member
**
Beiträge: 34
Themen: 2
Registriert seit: Sep 2012
Bewertung: 0
#26
10.09.2012, 01:37
(10.09.2012, 00:32)sILeNt heLLsCrEAm schrieb: Aber bedenke... Das funktioniert nur wenn auch nur die Geldadresse durch diese Befehle laufen. Wenn durch diese Befehle auch Adressen laufen die für das Spiel von anderen Nöten sind kann es sein das es crasht. Sowas muss nicht immer sofort passieren, kann aber z.B. beim Level laden oder im Home Screen vorkommen. Je nachdem halt...

Also ich habs jetzt hinbekommen, dass ich mit Delphi den jmp befehl an die stelle schreibe, habs mit array of byte gemacht, auch wenn ich von selbst schon drauf gekommen war XD aber hab jetzt 2 probleme...

1. kann ich die sprungadresse, die ich in CE benutzt habe nicht beschreiben... muss ich in delphi da noch iwas vorher senden oder den speicherbereich erst freigeben oder so?
2. kommt es wie du schon angedeutet hast im homescreen oder beim laden des lvls zum crash...
ich denke mal, dass es momentan einfach daran liegt, dass der jump geschrieben wird, aber dort nix steht, der jump quasi ins nirvana führt, aber kann auch noch andere ursachen haben, die ich nicht testen kann, solange ich dort nicht reinschreiben kann :(
Deswegen hatte ich ja beim Pointertrainer auch die Abfrage drin, dass er erst den Wert ändert, wenn er größer 0 ist... müsste bei cave doch auch klappen oder? Also prüfen, wenn > 0 dann ändern sonst code normal ausführen

LG Darius83
Es gibt 10 verschiedene Typen von Personen, die, die ich mag und die, die ich nicht verstehen kann...
Suchen
Antworten
iNvIcTUs oRCuS Offline
Super Moderator
****
Beiträge: 2.688
Themen: 529
Registriert seit: Aug 2010
Bewertung: 19
#27
10.09.2012, 01:47
Das ist richtig...
Zu allererst müsstest Du z.B. am einfachsten mit Cheat Engine nachverfolgen ob die Daten so geschrieben wurden wie Du es beabsichtigt hast. Also der Jump zur Codecave und die Codecave selbst.
Ich denke mal das der Jump geschrieben wurde, aber je nachdem wo deine Codecave steht kann es natürlich sein das dein Trainer keine Schreib-/Zugriffsrechte auf diesen Speicherbereich hat. Vom Trainer selbst her würdest Du das wahrscheinlich nicht bemerken, aber mit einem Debugger oder eben dem Dissassembler von CE könntest Du z.B. nachvollziehen ob alles korrekt geschrieben ist.
Wenn das nicht der Fall ist, dann liegts eben daran das der Trainer die Daten zwar vermutlich schreibt diese aber nicht in den Prozess injeziert werden weil eben die Schreibrechte fehlen. Diese Schreibrechte kannst Du dir mit der API VirtualProtectEx zusichern.

[code=MSDN]BOOL WINAPI VirtualProtectEx(
_In_ HANDLE hProcess,
_In_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flNewProtect,
_Out_ PDWORD lpflOldProtect
);[/code]


Zitat:hProcess [in]

A handle to the process whose memory protection is to be changed. The handle must have the PROCESS_VM_OPERATION access right. For more information, see Process Security and Access Rights.
lpAddress [in]

A pointer to the base address of the region of pages whose access protection attributes are to be changed.

All pages in the specified region must be within the same reserved region allocated when calling the VirtualAlloc or VirtualAllocEx function using MEM_RESERVE. The pages cannot span adjacent reserved regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx using MEM_RESERVE.
dwSize [in]

The size of the region whose access protection attributes are changed, in bytes. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.
flNewProtect [in]

The memory protection option. This parameter can be one of the memory protection constants.

This value must be compatible with the access protection specified for the pages using VirtualAlloc or VirtualAllocEx.
lpflOldProtect [out]

A pointer to a variable that receives the previous access protection of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.
Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer !!!

Traineranfragen per PM werden prinzipiell gelöscht...

[Bild: signatur6akm7.gif]
Suchen
Antworten
darius83 Offline
Junior Member
**
Beiträge: 34
Themen: 2
Registriert seit: Sep 2012
Bewertung: 0
#28
11.09.2012, 00:36
Ok, jetzt hats geklappt... Musste mir allerdings erstmal eine andere Speicheradresse suchen für den Cave... Anscheinend erstellt CE über Auto Assemble - CodeCave extra Speicher für die Cave, jedenfalls ist ebendieser Bereich bei mir auch mit VirtualProtectEx nicht beschreibbar gewesen... :/ Wie kann ich sowas denn in Delphi realisieren? Naja ich poste morgen Abend mal, was ich so gebastelt habe Wink

LG Darius83
Es gibt 10 verschiedene Typen von Personen, die, die ich mag und die, die ich nicht verstehen kann...
Suchen
Antworten
Acubra Offline
Trainermaker
****
Beiträge: 904
Themen: 127
Registriert seit: Oct 2010
Bewertung: 6
#29
11.09.2012, 16:03
(11.09.2012, 00:36)darius83 schrieb: Anscheinend erstellt CE über Auto Assemble - CodeCave extra Speicher für die Cave
Hey,
entweder du benutzt die "Scan for CodeCaves" Funktion von Cheat Engine (siehe mein CodeCave Tutorial), oder du verwendest die VirtualAlloc (bzw. VirtualAllocEx) Funktion (http://msdn.microsoft.com/en-us/library/...85%29.aspx) um selber Speicher zu alloziieren.
In C++ sieht das Ganze so aus : http://homeofgamehacking.de/showthread.php?tid=842
"Auf dieser Welt gibt es mehr Scheisse als auf Festivalklos"
[Bild: hoglogo_smalpxga.jpg]
Homepage Suchen
Antworten
darius83 Offline
Junior Member
**
Beiträge: 34
Themen: 2
Registriert seit: Sep 2012
Bewertung: 0
#30
11.09.2012, 23:45 (Dieser Beitrag wurde zuletzt bearbeitet: 12.09.2012, 22:38 von darius83.)
(11.09.2012, 16:03)Acubra schrieb:
(11.09.2012, 00:36)darius83 schrieb: Anscheinend erstellt CE über Auto Assemble - CodeCave extra Speicher für die Cave
Hey,
entweder du benutzt die "Scan for CodeCaves" Funktion von Cheat Engine (siehe mein CodeCave Tutorial), oder du verwendest die VirtualAlloc (bzw. VirtualAllocEx) Funktion (http://msdn.microsoft.com/en-us/library/...85%29.aspx) um selber Speicher zu alloziieren.
In C++ sieht das Ganze so aus : http://homeofgamehacking.de/showthread.php?tid=842

Hmm das mit VirtualAllocEx muss ich mir mal genauer anschaun... Weiss aber jetzt schon, dass ich da wieder Probleme bekomme, weil dann ja die JMP Befehle nicht mehr fest sind und ich ka habe, wie ich dann rausbekomme, welche Bytes ich dafür schreiben muss XD

Naja hier erstmal mein momentaner Code und @sILeNt heLLsCrEAm:
Du hast jetzt auch deinen Shortcut drin :P




[code=delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, tlhelp32, ExtCtrls, StdCtrls;
type
TWMHotkey = record
Msg: Cardinal;
idHotKey: Word;
Modifiers: Integer;
VirtKey: Integer;
end;

type
TForm1 = class(TForm)
Timer1: TTimer;
Memo1: TMemo;
procedure Timer1Timer(Sender: TObject);
private
procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
public
end;

var
Form1: TForm1;
CheatAktiv: Boolean = False;

implementation

{$R *.dfm}

const
PROCESS : String = 'game.dat'; // Prozessname des Spiels
GOLDSAMMELN: Integer = $00566d77; // Adresse 1 Gold
GOLDAUSGEBEN: Integer = $00566cd5; // Adresse 2 Gold
CAVEADRESS1: Integer = $004001E6; // Einfache Caveadresse mit 30Bytes Platz
CAVEADRESS2: Integer = $00401529; // Einfache Caveadresse mit 30Bytes Platz
ID = $FF;
JmpGoldSammeln:array[0..10] of byte = ($E9,$6A,$94,$E9,$FF,$90,$90,$90,$90,$90,$90);
JmpGoldSammelnOriginal:array[0..10] of byte = ($89,$46,$04,$C7,$44,$24,$74,$FF,$FF,$FF,$FF);
JmpGoldAusgeben:array[0..10] of byte = ($E9,$4F,$A8,$E9,$FF,$90,$90,$90,$90,$90,$90);
JmpGoldAusgebenOriginal:array[0..10] of byte = ($89,$47,$04,$C7,$44,$24,$74,$FF,$FF,$FF,$FF);
// $00004E20; 20000 Gold (Bytes 2-5)
CodeCave1:array[0..20] of byte = ($B8,$20,$4E,$00,$00,$89,$46,$04,$C7,$44,$24,
$74,$FF,$FF,$FF,$FF,$E9,$87,$6B,$16,$00);
CodeCave2:array[0..20] of byte = ($B8,$20,$4E,$00,$00,$89,$47,$04,$C7,$44,$24,
$74,$FF,$FF,$FF,$FF,$E9,$A2,$57,$16,$00);

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 GetID

function GetAdress(Pidhandle: Integer; BasePointer: Cardinal; Offsets: Array of Cardinal) : Cardinal;
var
i, Anzahl: Integer;
Written: Cardinal;
begin
Written := 0;
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, 4, Written);
Result := Result + Offsets[i];
end;
end;
end; // function GetAdress

procedure WriteBytesToMem(Processhandle, Adress, Written: Cardinal;
ByteArray: Array of Byte);
var i: Cardinal;
begin
for i := 0 to high(ByteArray) do
WriteProcessMemory(Processhandle, Pointer(Adress+i),@ByteArray[i] , 1, Written);
end; // procedure WriteBytesToMem

procedure Start();
var
Pid: Integer;
Written, lpBuffer, lBuf, Adress, Pidhandle: Cardinal;
Offsets: Array of Cardinal;
begin
RegisterHotKey(Form1.Handle, ID, MOD_Alt, Ord('C'));
Pid := 0;
Adress := $0096c9b0;
SetLength (Offsets, 3);
Offsets[1] := $0C;
Offsets[2] := $34;
if GetID(PROCESS, Pid) then begin
Pidhandle := OpenProcess(PROCESS_ALL_ACCESS,False,Pid);
try
lBuf := GetAdress(Pidhandle, Adress, Offsets);
ReadProcessMemory(Pidhandle, Pointer(lBuf), @lBuf, 4, Written);
if lBuf > 0 then begin
VirtualProtectEx(Pidhandle, Pointer(CAVEADRESS1), 30, PAGE_EXECUTE_READWRITE, lpBuffer);
VirtualProtectEx(Pidhandle, Pointer(CAVEADRESS2), 30, PAGE_EXECUTE_READWRITE, lpBuffer);
WriteBytesToMem(Pidhandle, GOLDSAMMELN, Written, JmpGoldSammeln);
WriteBytesToMem(Pidhandle, GOLDAUSGEBEN, Written, JmpGoldAusgeben);
WriteBytesToMem(Pidhandle, CAVEADRESS1, Written, CodeCave1);
WriteBytesToMem(Pidhandle, CAVEADRESS2, Written, CodeCave2);
CheatAktiv := true;
Form1.Timer1.Enabled := false;
end;
finally
closehandle(Pidhandle);

end;
end;
end; // procedure Start

procedure Change();
var
Pid: Integer;
Written, Pidhandle: Cardinal;
begin
Pid := 0;
Written := 0;
if GetID(PROCESS, Pid) then begin
Pidhandle := OpenProcess(PROCESS_ALL_ACCESS,False,Pid);
try
if not CheatAktiv then begin
WriteBytesToMem(Pidhandle, GOLDSAMMELN, Written, JmpGoldSammeln);
WriteBytesToMem(Pidhandle, GOLDAUSGEBEN, Written, JmpGoldAusgeben);
CheatAktiv := true;
end else begin
WriteBytesToMem(Pidhandle, GOLDSAMMELN, Written, JmpGoldSammelnOriginal);
WriteBytesToMem(Pidhandle, GOLDAUSGEBEN, Written, JmpGoldAusgebenOriginal);
CheatAktiv := false;
end;
finally
closehandle(Pidhandle);
end;
end;
end; // procedure Change

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Start();
end;

procedure TForm1.WMHotKey(var Msg: TWMHotkey);
begin
case Msg.IdHotKey of
ID:
begin
Change();
end;
// Abhängig von der ID wird entschieden, was getan werden soll.
end;
inherited;
end;

end.
[/code]

Es gibt 10 verschiedene Typen von Personen, die, die ich mag und die, die ich nicht verstehen kann...
Suchen
Antworten
Share Thread:            
Seiten (7): « Zurück 1 2 3 4 5 ... 7 Weiter »


  • Druckversion anzeigen
  • Thema abonnieren


Benutzer, die gerade dieses Thema anschauen:
1 Gast/Gäste

  • Kontakt
  • Forum team
  • Forum stats
  • Nach oben
 
  • RSS-Synchronisation
  • Lite mode
  • Home of Gamehacking - Archiv
  • Help
 
Forum software by © MyBB - Theme © iAndrew 2014



Linearer Modus
Baumstrukturmodus