Entwickler-Ecke
Windows API - ReadProcessMemory
Swordooo - Sa 04.04.09 20:29
Titel: ReadProcessMemory
Hallo an alle Delphianer!
Ich beschäftige mich seit neustem mit dem Thama "ReadProcessMemory" bzw. Trainer erstellen etc.
Ich habe mir dieses Tutorial durchgelesen, doch bin nicht wirklich daraus schlau geworden ^^:
http://www.delphi-library.de/topic_Spiele+Trainer+erstellen_34077.html
Könnte mir jemand freundlicher Weise die Parameter von ReadProcessMemory mitteilen, da mir diese noch nicht so ganz klar sind. Auch würde mich interessieren, wie ich DMAs auslesen kann, obwohl diese ja immer ihren "Ort" wechseln (Pointer).
Code-Beispiele wären für beide Probleme nett :wink: .
In der Suche habe ich auf die Schnelle nichts passendes gefunden. :(
Ggf. helfen auch Tutorials - ich habe jedoch keins außer das oben genannte gefunden.
MfG Swordooo
Swordooo - Sa 04.04.09 21:38
Okay danke! Jez müsste ich nur noch wissen wie man DMAs ausliest mit Pointer, dann wärs perfekt :P
Swordooo
BenBE - So 05.04.09 10:27
Was meinst Du mit DMAs?
Swordooo - So 05.04.09 11:53
Ist DMA nicht die Abkürzung für "dynamic memory addresses"? Wie gesagt bin neu in diesem Themengebiet :wink: .
MfG Swordooo
MagicRain - So 05.04.09 13:45
Zum Beispiel bei einem spiel das DMA ( (Dynamic Memory Address) ) benutzt werden sich die gefunden Adressen bzw. Speicherstände bei jedem neu start oder Level Wechsel ändern! Das heißt wenn ich nun die Adresse für mein gold in meiner Speicher gefunden habe zum Beispiel mit CheatEngine oder irgendeinen anderen Memory-Searcher wird sich diese Adresse beim neu start geändert haben und der wert zum Beispiel für mein gold liegt nun an einer anderen Adresse nun muss man halt den Pointer finden der das ganze regelt und kann sich schön sein Cheat zusammen bauen das ganze fordert eine CodeInjection zu schreiben aber dann läuft das ganze. Würde mir einfach mal paar Tutorials durch lesen und so weiter und bischen auf GameHacking boards rumschauen wirst sicher noch ne mänge lernen können.
MfG
uall@ogc - So 05.04.09 14:00
Naja code injection braucht man dafür nicht.
Im Prinzip hast du eine Adresse gefunden in der dein "Geld" steht. Diese Adresse kann sich jedoch immer ändern, da das Spiel sich den Speicher dynamisch holt. Auf diese Speicherstelle verweist aber meistens direkt eine andere feste Adresse.
Im Grunde in der Art:
Delphi-Quelltext
1: 2: 3: 4:
| asm mov eax, [pointerzumgeld] mov eax, [eax] end; |
mit CheatEngine etc bekommst du immer nur den Wert der sich verändert. Im Grunde muss man dann wenn man die Adresse hat, diese wieder im Speicher suchen. Diese sollte innerhalb eines Modules (einer dll, bzw. einer exe des Spiels liegen)
Wenn man z.b. das spiel debuggen kann, dann ist es relativ einfach wenn man die adresse des aktuellen geldes kennt. man macht dann einfach einen HardwareBP bzw. MemoryAccessBP (z.b. ollydbg) drauf und bekommen den code der die stelle ausliest. diesen muss man dann reverse engineeren (also rausfinden wie der generell abläuft)
das problem ist es kann auch sowas wie:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| asm mov eax, [wichtigeaddr] add eax, $124 shl eax, 1 mov edx, [eax] end; |
sein. Dann ist es das ziel "wichtigeaddr" auszulesen (die statisch ist) und alle operationen danach per hand auszuführen um an die gewollte adresse zu gelangen.
MagicRain - So 05.04.09 16:14
Sicherlich ist oftmals eine CodeInjection nicht erforderlich jedoch auch eher Professional also eher was für Leute die sich mit dem Thema besser auskennen da muss ich dir recht geben. Um ein sauberen Hack zu schreiben jedoch dringend erforderlich. Auch für bestimmte Hacks nicht verzichtbar eine Injection zu schreiben wenn man sich eigene Optionen zusammen bauen möchte wie GodMod, OneHitKill und so aber das ist eher was für fortgeschrittene also nichts o relevant hier denk ich mir mal.
MfG
Mr_Emre_D - Fr 10.04.09 14:10
Codeinjection ist nur dann sinnvoll, wenn etwas automatisiert werden muss
(Bsp.: Gold hat sich verringert, was soll nun geschehen?)
MfG
mholup13 - Fr 24.04.09 12:54
Vielleicht hilft Dir dieser Code weiter:
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:
| const buffer: packed array[0..1] of Byte = ($EB, $09); var StartInfo: TStartupInfo; ProcInfo: TProcessInformation; CreateOK: Boolean; ErrorCode: DWord; AppDone: DWord;
lpflOldProtect: Cardinal; lpNumberOfBytesWritten: Cardinal; begin ErrorCode := 0; FillChar(StartInfo, SizeOf(TStartupInfo), #0); FillChar(ProcInfo, SizeOf(TProcessInformation), #0); StartInfo.cb := SizeOf(TStartupInfo);
CreateOK := Windows.CreateProcess(nil, PChar(ExecuteFile + ' ' + paramstring), nil, nil, False, CREATE_NEW_PROCESS_GROUP + IDLE_PRIORITY_CLASS + SYNCHRONIZE + CREATE_SUSPENDED, nil, nil, StartInfo, ProcInfo); WaitForInputIdle(ProcInfo.hProcess, INFINITE); if CreateOK then begin VirtualProtectEx(ProcInfo.hProcess, Ptr($00801FA1), SizeOf(buffer), PAGE_EXECUTE_READWRITE, lpflOldProtect); WriteProcessMemory(ProcInfo.hProcess, Ptr($00801FA1), @buffer[0], SizeOf(buffer), lpNumberOfBytesWritten); ResumeThread(ProcInfo.hThread); if wait then begin repeat AppDone := WaitForSingleObject(ProcInfo.hProcess, 10); ProcessMessage; until AppDone <> WAIT_TIMEOUT; CloseHandle(ProcInfo.hProcess); CloseHandle(ProcInfo.hThread); end else procid := ProcInfo.hProcess; end; GetExitCodeProcess(ProcInfo.hProcess, ErrorCode); Execute_Program := ErrorCode; |
neuronet - Do 09.12.10 10:34
Da ich nicht ersehen kann ob das Problem mit den Pointern bereits erledigt ist, hier mal meine Lösung dafür:
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: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private function PointerSolve(Process: integer; p_array: array of integer): integer; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var WindowName: Integer; Pidi: Integer; Wert:DWORD ; Window1: Integer; lBuf: integer; addr_array: array[0..4] of integer; begin addr_array[0]:=StrToInt('$100000'); addr_array[1]:=StrToInt('$7B8'); addr_array[2]:=StrToInt('$C'); addr_array[3]:=StrToInt('$30'); addr_array[4]:=StrToInt('$24B8'); WindowName :=FindWindow(nil,'TEST'); GetWindowThreadProcessId(WindowName ,@pidi); Window1 :=OpenProcess(PROCESS_VM_READ ,False , pidi); lBuf:=PointerSolve(Window1, addr_array); ReadProcessMemory(Window1 ,ptr(lBuf),@lBuf,4,Wert); Edit1.Text :=IntToStr(lbuf); CloseHandle(Window1); end;
function TForm1.PointerSolve(Process: integer; p_array: array of integer):integer; var pointercount: integer; i: integer; base_addr: integer; offset: integer; temp: integer; Wert:DWORD ; begin pointercount:=length(p_array); base_addr:=p_array[0]; for I := 1 to pointercount-1 do begin ReadProcessMemory(Process, ptr(base_addr), @temp, 4, Wert); base_addr:= temp + p_array[i]; end; result:=base_addr; end; end. |
Das Array enthält an Index 0 die Basisadresse gefolt von den Offsets....
Hoffe damit geholfen zu haben...
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!