Re: Speicherbereich einer Anwendung ermitteln
Hat jetzt jemand vieleicht eine Idee.
Mein Gedankengang ist folgender:
Code:
müsste doch so gehn oder.
1. Suche die Adresse des 1. Offsets des Spieles im Speicher
2. Addiere zum 1.Offset die Adresse des Modifikationspunktes (aus TSearch) 3. WriteProcess auf die Adresse Wenn ja Wie erhalte ich das 1.Offset des Spieles. |
Re: Speicherbereich einer Anwendung ermitteln
Dann muss ich mir wohl ein neues zulegen :mrgreen:
Nee, mal ensthaft: Ich dachte, gerade das wäre der Trick an den virtuellen 32-Bit Adressen. Bei Win 3.1 gabs das nicht, da war das System auch nur multitaskingfähig, wenn sich die Programme "kooperativ" gezeigt haben (so hab ichs mal wo gelesen). Außerdem haben die sich manchmal gegenseitig gestört (glaub ich) wenn man nicht sehr umsichtig programmiert hatte, weil sie eben nebeneinander im selben Speicherbereich lagen. Das werd ich nochmal etwas überdenken müssen... Wie sollten sonst auch Sachen wie die Zwischenablage, OLE oder einfach das Nachrichtensystem von Windows funktionieren... Na egal, genug OT jetzt!! :mrgreen: bundy kann ich leider nicht helfen, ich hätte es ihm ausgeredet. Snuffi |
Re: Speicherbereich einer Anwendung ermitteln
@snuffmaster23:
ich glaube du bist irgendwo in der win9x-zeit hängen geblieben ... ^^ [edit]Aber im grunde hast du recht, jedes programm hat unter nt-systemen seinen eigenen adressraum, in dem es tun und lassen kann was es will ;) Daher kann es mit sehr hoher wahrscheinlichkeit auch passieren, dass das Programm jedesmal an exakt die gleiche Stelle geladen wird, und somit auf vielen rechnern läuft, und durch zufall auf einem anderen nicht, weil in diesen ein modul mehr geladen ist, und das den speicher schon irgendwo besetzt -> diverse variablen werden an anderen stellen alloziert -> problem für trainer ...[/edit] @bundy: Ich vermute also, dass du das modulehandle des modules benötigst, dem der speicherbereich "gehört". Naja, theoretisch gesehen könntest du das via GetModuleHandle das betreffliche handle erfahren, allerdings nur, wenn du dich IM fremden Prozess befindest ... und sobald du sowas versuchst, wirds kompliziert. Also musst du wohl EnumProcessModules verwenden, die daraus resultierenden module-handles sollten die Startadressen der geladenen Module (z.B. dlls) sein. Die könntest du als Anhaltspunkte verwenden, allerdings würde ich es nicht darauf ankommen lassen (ich hab diese methode verwendet, um aus relativen funktions-adressen absolute adressen zu bekommen, soweit funktioniert das, aber ob du das auch mit den adressen irgendwelcher, möglicherweise dynamisch allozierter variablen machen kannst, ist eine andere frage). ciao, Philipp |
Re: Speicherbereich einer Anwendung ermitteln
Ich hab das Programm jetzt auf meinen 2. Pc getestet, da funktioniert es auch wunderbar.
Warum sieht mein Kumpel nicht die gleichen Werte. Stimmt der Speicherbereich des Spieles, nicht mit meinem überein? Ich hab das Game schon zick mal mit Tsearch aufgemacht, und meinen PC dazwischen immer neu gestartet und die Adressen der Modifikations Offsets sind immer die gleichen. Wie händelt das denn TSearch, wenn ich nach einem Wert suche. Tsearch such ja auch nur im Speicherbereich des Spieles oder? Ich glaub ich denk da irgendwie verkehrt. Oder wird jeder Applikation die 0000000000-FFFFFFFFFF (4 GB) zugesichert ? lg Bundy |
Re: Speicherbereich einer Anwendung ermitteln
Genau, jeder Applikation werden 4 GB Speicher versprochen, so hab ich das jedenfalls bis vorhin verstanden. Und da niemand so viele GBs Speicher in seinen PC reinsteckt, gibts das Pagefile :)
Die Adressen für jedes Programm gehen von $00000000 bis $FFFFFFFF aber die sind virtuell, sagen also außerhalb des Programms nichts. Drum versteh ich auch nicht, wieso du danach fragst... egal. |
Re: Speicherbereich einer Anwendung ermitteln
Ich glaub ich weiss warum es beim meinem Kumpel nicht geht.
Er verwändet einen NoCD Patch, der dürfte ein anderer sein, den ich verwände. Das würde auch den unterschieldlichen Speicherbereich erklären . Ich bedanke mich an alle die mir hier geholfen haben :thumb: |
Re: Speicherbereich einer Anwendung ermitteln
Zitat:
Aber die physikalische Adresse interessiert auch nicht mehr sonderlich, denn mit WriteProcessMemory() schreibst du in den virtuellen Adressraum des Programmes. Die Adressen, mit denen man arbeitet, sind zwar immer noch virtuell, aber dafür sind es die des anderes Prozesses und nicht deines eigenen. No magic ;-) Zitat:
Zitat:
Zitat:
@bundy: Wenn du großartig debuggen willst, solltest du dich auch mal über die Tool Help API schlau machen. Rumgefummele mit Modulhandles würde ich beispielsweise nicht wagen, denn niemand garantiert mir, daß der numerische Wert des Handles die Basisadresse des Moduls ist. Mir Module32First() und Module32Next() kannst du aber durch die Module eines Przesses iterieren, das gesuchte rausfischen und kommst laut API an die Basisadresse. Bei Microsoft gibt's dazu auch ein Beispiel (Funktion ListProcessModules() ist für dich interessant). Eigentlich ist es aber so, daß das Prozessmodul (also die Exe) immer an der gleichen Stelle geladen wird, wenn ich mich richtig erinnere ist das mittlerweile 0x400000, sofern dort Platz ist, und das sollte beim Laden des Prozesses ja immer der Fall sein. Bist du denn sicher, daß dein Freund die gleiche Version (Patchlevel) wie du benutzt? Mitunter ändern die Hersteller die Position der Variablen gerne von Patchlevel zu Patchlevel, um gerade solche Hacks zu erschweren. |
Re: Speicherbereich einer Anwendung ermitteln
Ja das denke ich auch, das er ne andere EXE Version verwändet.
Kann ja nur so sein, wenn die Applikation auf Offset $400000 geladen wird, dann ist das ja ein fixer Startpunkt. Wenn dann bei Offset z.B $4000E0 nicht der selbe Wert wie bei mir steht, dann kann ja nur die Struktur der Applikation ne andere sein. Wer bestimmt das laden an Offset $400000, das Speichermangement oder die Applikation selbst ? lg Bundy |
Re: Speicherbereich einer Anwendung ermitteln
Zitat:
@0x00400000 Die Applikation hat das im PE Header stehen. Dieser Wert wird vom compiler festgelegt. Bei Delphi kann man das unter Projekt -> Optionen -> Linker einstellen. Als Standard hat sich dise Adresse etabliert. Man kann auch jede andere wählen, sollte diese belegt sein (durch die kernel32.dll oder ntdll.dll oder unterhalb der 0x00100000 Grenze liegen) dann wird die EXE an einer anderen Stelle geladen und durch die Relocation Tabelle die Globalen Variablen usw. wieder richtig hergetsellt. |
Re: Speicherbereich einer Anwendung ermitteln
Zitat:
die entsprechenden speicheradressen einpflegen. andererseits ist es auch möglich dass die speicheradressen durch verschiedene windows-dll's bei der heap-verwaltung andere adressen zurückliefern, dann kannst du nur nach signifikanten byteketten in bestimmten speicherbereichen suchen. als beispiel kann ich dir mal nen trainer posten, den ich für pokemon auf dem vba geschrieben habe
Delphi-Quellcode:
program pokerubyhack;
{$APPTYPE CONSOLE} uses sysutils, windows, messages; type pcardinal = ^cardinal; function EnumCb(hnd: hwnd; lParam: cardinal):BOOLEAN; stdcall; const bufsize = 256; var strResult: string; begin setlength(strResult,bufsize); zeromemory(@strResult[1],bufsize); //lastHnd := cardinal(hnd); GetWindowText(hnd,@strResult[1],bufSize); //if strResult[1] <> #0 then asm int 3 end; if copy(strResult,1,16) = 'VisualBoyAdvance' then begin pcardinal(lParam)^ := hnd; result := false end else result := true; end; function findwnd:hwnd; var lparam: cardinal; begin result := 0; lParam := cardinal( @result ); EnumWindows(@EnumCb,lparam); end; procedure haltp(c:integer;s:string); begin writeln(s+#13#10'press any key to continue');readln; halt(c); end; type ppokestat = ^pokestat; pokestat = packed record CHP:word; AHP:word; ATT:word; DEF:word; INI:word; SPA:word; SPD:word; end; const START_OFFSET = $1560000; DIST2REC = 6; pokedef : array[1..7]of string[3] =('CHP','AHP','ATT','DEF','INI','SPA','SPD'); var hnd: hwnd; pid : dword; dwread: dword; hp : thandle; s: string; p, buf, pend,pokedata: pointer; pokeptr: pointer; j: integer; c,d: char; newstat: pokestat; pm: pword; nv: word; procedure hackStats(pokeNum:byte); var dwWritten : dword; begin writeln(#13#10'trying to patch pokemon #'+ inttostr(pokenum)); writeprocessmemory(hp,pointer(cardinal(pokedata)+DIST2REC+((pokenum -1) * $64 )),@newstat,sizeof(pokestat),dwWritten); if dwWritten > 0 then writeln(format(#13#10'successful: %d bytes written',[dwWritten])) else writeln(#13#10'an error occured'); end; begin writeln('retnygs pokemon trainer for visual boy advance v 1.0'); writeln('===================================================='); writeln('tested with 2006 pokemon ruby 1.2 and VBA Link 1.7.3L'#13#10'supported cmd line parameters: number of pokemon to patch [1-6]'#13#10'patch is temporary and will be removed on next level up.'#13#10#13#10); hnd := findwnd; if (Hnd <> 0) then begin GetWindowThreadProcessId(hnd,@pid); //Get ProcessID and ignore ThreadID hp:=openprocess(ProCEsS_aLL_ACCESS,false,pid); if (hp = 0) or (pid = 0) then haltp(1,'could not find hacker process'); setlength(s,$640000); buf:=@s[1]; cardinal(p):=START_OFFSET; // weise startadresse des zu suchenden speicherbereiches zu readprocessmemory(hP,p,buf,length(s),dwRead); pokedata := nil; if dwread > 0 then begin //writeln('could read something'#13#10); setlength(s,dwread); cardinal(pend) := cardinal(buf) +dwread; while cardinal(buf) < cardinal(pend)-$64-(DIST2REC-1) do begin inc(pbyte(buf)); // durchsuche speicher nach gewisser bytefolge die typisch ist if (pcardinal(buf)^ = $0) and (pbyte(cardinal(buf)+(DIST2REC-1))^ = $FF) and (pcardinal(cardinal(buf)+$64)^ = $0) and (pbyte(cardinal(buf)+$64+(DIST2REC-1))^ = $FF) then begin cardinal(pokeptr):= cardinal(buf); cardinal(pokedata) := START_OFFSET + cardinal(buf) - cardinal(@s[1]); writeln('pokemon list found at adress: ' + inttohex(cardinal(pokedata),8)); writeln; break; end; end; if pokedata <> nil then begin writeln('pokemon #: CHP AHP ATT DEF INI SPA SPD'); writeln('______________________________________'); for j := 1 to 6 do begin writeln('pokemon '+inttostr(j)+':'+ format(' %.3d %.3d %.3d %.3d %.3d %.3d %.3d', [ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.CHP, ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.AHP, ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.ATT, ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.DEF, ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.INI, ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.SPA, ppokestat(cardinal(pokeptr)+DIST2REC+((j-1)*$64))^.SPD ]) ); end; with ppokestat(@newstat)^ do begin CHP:=999; AHP:=999; ATT:=999; DEF:=999; INI:=999; SPA:=999; SPD:=999; end; if paramcount > 0 then c := paramstr(1)[1] else begin writeln(#13#10'please enter a pokemon number [1-6] that you want to boost or [0] to abort, [A] for all'); readln(c); end; case c of '1'..'6' : if paramcount > 0 then hackstats(byte(c)-48) else begin writeln ('Automatic hack will set all values to 999'#13#10'manual hack will allow you to enter the values yourself'#13#10'type A for automatic or M for manual'); read(d); if d in ['a','A'] then hackstats(byte(c)-48) else if d in ['m','M'] then begin newstat := ppokestat(cardinal(pokeptr)+DIST2REC+(((byte(c)-48)-1)*$64))^; pm:=@newstat.chp; for j := 1 to 7 do begin write('enter new value for ' + pokedef[j] + ', current: ' + inttostr(pm^) + ' :'); readln(nv); pm^ := nv; inc(pm); end; hackstats(byte(c)-48) end else writeln('wrong input'); end; '0' : writeln('aborted'); 'A','a' : for j := 1 to 6 do hackstats(j); else haltp(1,'error - undefined input'); end; end; end else writeln('couldnt read from target process'); closehandle(hp); haltp(0,#13#10); end else haltp(1,'could not find VBA window'); end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:30 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