Autor |
Beitrag |
Swordooo
      
Beiträge: 119
W2K, Windows XP Professional
Delphi 2005 Personal, Delphi 7 Personal
|
Verfasst: Sa 04.04.09 20:29
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 ^^: www.delphi-library.d...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  .
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
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Sa 04.04.09 21:12
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
Swordooo 
      
Beiträge: 119
W2K, Windows XP Professional
Delphi 2005 Personal, Delphi 7 Personal
|
Verfasst: 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
Swordooo
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 05.04.09 10:27
Was meinst Du mit DMAs?
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Swordooo 
      
Beiträge: 119
W2K, Windows XP Professional
Delphi 2005 Personal, Delphi 7 Personal
|
Verfasst: So 05.04.09 11:53
Ist DMA nicht die Abkürzung für "dynamic memory addresses"? Wie gesagt bin neu in diesem Themengebiet  .
MfG Swordooo
|
|
MagicRain
      
Beiträge: 154
WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
|
Verfasst: 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
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: 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.
_________________ wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
|
|
MagicRain
      
Beiträge: 154
WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
|
Verfasst: 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
      
Beiträge: 114
Erhaltene Danke: 14
|
Verfasst: 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
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 24.04.09 12:54
Vielleicht hilft Dir dieser Code weiter:
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
Hält's aus hier
Beiträge: 15
Win XP, SCO Unix, Linux
Delphi 2010 Architect
|
Verfasst: 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:
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
|
|
|