# Andere Programme "manipulieren"



## Tobias K. (13. November 2004)

moin


Ich beschäftige mich zur Zeit damit, den Speicher anderer Programme zu manipolieren.
Also z.B. den Wert einer bestimmten Variable eines anderen Programms zu verändern.

Das geht aber mit der Methode nur wenn ich die adresse der Variable kenn, wie gehe ich im Prinzip vor wenn ich nur den Wert der Variable weiss?


mfg
umbrasaxum


----------



## Beichtpfarrer (13. November 2004)

Hm, das wird sowieso schwer, heutzutage läuft das meiste im Protected Mode, da kannst du gar nicht auf Speicher zugreifen, der nicht zu deinem Programm gehört.
Möglichkeiten, das zu umgehen, kenne ich nicht, außer den Prozess per LoadLibrary für dich zugänglich zu machen, es gibt aber sicher noch weitere.

Und wenn du nur Werte einer Variablen kennst, dann ist die einzige Möglichkeit, den Speicher zu durchsuchen.... das würde ich an deiner Stelle nicht machen.


----------



## Tobias K. (13. November 2004)

moin


Ich hätte dazu nochmal sagen sollen das ich das schon gemacht hab und es ist nciht schwierig die nötigen Rechte dafür zubekommen, eigentlich isses ein Kinderspiel!

Ja speicher durchsuchen das verfahren ist mir bekannt, auch wie man eingrenzen kann wo man suchen muss. Auch kein großes ding!

Dachte mehr an sowas das ich in den Programmcode des fremden Programm gehe und dort gucken wie die Variable heisst oder irgendwas in der Art, weiss es ja auch nicht.


mfg
umbrasaxum


----------



## Beichtpfarrer (13. November 2004)

Im Programmcode eines fremden Programms stehen keine Variablennamen mehr.
Die verschwinden bei der Compilation.

Achja nebenbei: kannst ja auch gleich schreiben, wie du die nötigen Rechte bekommen hast.


----------



## Tobias K. (13. November 2004)

moin


Ja und die werden dann in Register verfrachtet?!
Kenn mich da nciht so aus.


mfg
umbrasaxum


----------



## Beichtpfarrer (13. November 2004)

Zur Laufzeit tauchen überhaupt keine Namen mehr auf.
Zur Laufzeit wird nur noch mit Offsets und Speicheraddressen gearbeitet.
Normalerweise wird es (grob) so geregelt: Globale Variablen erhalten eine Programm-globale Addresse (welche schon zur Kompilationszeit bekannt ist), lokale Variablen erhalten einen Offset zum ebp-Register, welches auf eine Stelle im Stack zeigt. Bei Betritt einer Funktion wird ebp gesichert, dann neu zugewiesen.

Wenn ich noch näher beschreibe, bringt dir das auch nichts, dafür müsstest du mit Assembler umgehen können.


----------



## Tobias K. (13. November 2004)

moin


Aber es gibt ja auch sogenannte "Trainer" zu Maipulation von Spielen zur Laufzeit.


mfg
umbrasaxum


----------



## Beichtpfarrer (13. November 2004)

Jo, die Programmierer von denen ham sich die Spiele disassembliert, dann den Assembler-Code ganz genau angeschaut und dann daraus gefolgert, an welchen Stellen sie etwas manipulieren können.
Aber was meinst du, warum es relativ wenige Trainer gibt? Es ist schwer, das zu tun.

Erstmal musst du dafür Assembler schreiben und Lesen können und wenn du soweit bist,
versuch mal ein Programm in Assembler zu verstehen, erstmal ein kleines selbstprogrammiertes, dann mal ein größeres eigenes oder irgendwann mal ein fremdes (wo du selbst einen Ablauf, Sinn erkennen musst).....


----------



## MCIglo (13. November 2004)

So wenig Trainer gibt es aber garnicht.


----------



## basd (13. November 2004)

Naja die alten Trainer waren ja zu Amiga Zeiten ziemlich "primitiv" . Die Speicherbereiche überwacht und wenn ein Leben verloren wurde , wurden halt die Unterschiede untersucht und wenn man clever ist findet man relativ schnell wo sich die Information für die Anzahl Leben befindet. 

Wie kann man den Speicher eines anderen Prozesses lesen ? Ich bräuchte das weil ich mir ein Visual Studio Plug IN geschrieben habe dass den Speicherbereich zeichnet aber das ist ziemlich unperformant, da ständig einzelne array Werte über die COM Schnittstelle abgefragt werden müssen ... und wenn ich den Speicher direkt lesen könnte wäre das perfekt


----------



## Tobias K. (13. November 2004)

moin


Hier ein ganz simples Beispiel.

Dies ist mein "Opfer" Programm bei dem die variable xxx vom "Täter" Programm um eins erhöht werde soll, hab es nochmal Kommentiert:

```
#include <windows.h>
#include <iostream>

int main()
{
	int xxx = 5;          // Zu ändernde Variable

	SetConsoleTitle("cracking opfer");          // Umsicher zu gehen das das Programm auch                                                                     // wirklich den Fenstertitel hat nach dem wir                                                                    // suchen

	std::cout<< xxx << "    " << &xxx << std::endl;   // Zeile spricht für sich
	Sleep(10000);						// Während diesen 10 sek wird das Täter Programm gestartet
	std::cout<< xxx << "    " << &xxx << std::endl;	// Hier kann man den geänderten Wert 									// von xxx sehen
	Sleep(10000);

	return 0;
}
```


Nun muss das Programm erstmal gestartet werden um die Adresse zu sehen, sie ist beim starten immer gleich, außer man ändert die Position der exe auf der Festplatte, sprich anderer Ordner.

Nun das Täter Programm:

```
#include <windows.h>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
	HWND hwnd;
	DWORD ID;
	DWORD rw=0;
	HANDLE handle;

	int puffer = 0;
	unsigned adresse = 0x0012FEE4;                  // Die Adresse bekommt man durch einen                                                                             // Probelauf des opfers, wir dbei euch                                                                             // anders sein

	hwnd = FindWindow(NULL, "cracking opfer");          // Fenster suchen
	if(!hwnd)                                                               // Wenn nciht gefunden gleich raus
	{
		std::cout<<"Fehler! Konnte Opfer nicht finden";
		Sleep(1000);
		return 0;
	}

	GetWindowThreadProcessId(hwnd, &ID);                 // Nun brauchen wir die ProcessID
                                                                                     // des opfers für die nächste                                                                                            // Funktion
	handle = OpenProcess(PROCESS_ALL_ACCESS, false, ID);       // Hier holen wir uns
                                                                                                        // das handle des                                                                                                            // opfers

	ReadProcessMemory(handle, (LPCVOID)adresse, &puffer, sizeof(puffer), &rw);
	std::cout<< puffer;                                                            // Test ob es wirklich der                                                                                                 // gesucht Wert xxx ist

	WriteProcessMemory(handle, (LPVOID)adresse, &(puffer+=1), sizeof(int), &rw); 
                                   // Und nun den Wert überschreiben

	Sleep(2000);
	CloseHandle(handle);                 // Extrem wichtig!
	return 0;
}
```


Hoffe es ist verständlich!


mfg
umbrasaxum


----------



## Tobias K. (13. November 2004)

moin


Hab es mir nochmal durch den Kopf gehen lassen.
Und zwar frag ich mich immernoch wie Trainer den Wert im Speicher finden.
Denn sie wissen ja nicht unterwelcher Adresse er zu finden ist, da die Adresse einer Variable ja auf jeden Sytem verschieden ist.

Das würde dann doch auf die Methode den gesamten Speicher zu durchsuchen hinweisen. Wei es geht den Wert zu finden und zu überprüfen ob er wirklich zu dem Programm gehört ist mir bekannt, allerdings was ist wenn der Wert in 2 Variablen vorkommt?!


mfg
umbrasaxum


----------



## C Coder (14. November 2004)

Hi,

Das mit der gleichen Adresse dürfte kein Problem sein. Man disassembliert den Code der Exe und findet 
raus(vom Stack 'n Abbild machen nehm ich mal) wo entsprechende Variable liegt. 
Da der Stack vor dem Start reserviert und bereitgestellt wird, sich also nicht mehr ändert, merkt man sich die 
relative Addresse zum Anfang. 
Im Trainer sucht man nun den Anfang der Stack addresse und voila, man hat die Variable!


----------



## Tobias K. (14. November 2004)

moin


Also,
ich hab mich mal ein bsichen mit nem Debugger vertraut gemacht, dort hab ich gesehen von welcher bis zu welcher Adresse der Stack für mein Opferprogramm geht.
In ihm fand ich auch meinen gescuhten werd unter der Adresse die ich schon wusste hatte. Und ich weiss auch die Entfernung des Wertes von Anfang zum Stack.

Wie kann ich jetzt weiter vorgehen?
Ich kann zwar über die Anfangsadresse im Stack + die Entfernung der Variable zum Anfang des Stacks auch auf den Wert zu greifen, aber die Anfangsadresse des reservierten Bereichs im Stack ist doch auch je nach System verschieden.


mfg
umbrasaxum


----------



## Beichtpfarrer (14. November 2004)

Ich sag dir nur nochmal, ohne Assembler kannst du keine Rückschlüsse ziehen.
Lern Assembler und innerhalb von 3 Tagen wird dir das ganze Problem sowas von klar sein.....

Aber nochmal:
Globale Variablen usw werden immer Programmintern addressiert, also relativ zum ersten Byte der Exe (glaub ich jdf), sie erhalten einen Platz im Datensegment. So gilt die gleiche Addresse für jeden Programmaufruf.
Lokale Variablen, von denen also zur Kompilationszeit nicht sicher ist, wie oft, wie lange, usw sie gebraucht werden, können erst zur Laufzeit reserviert werden.
Das macht man, indem man einfach ebp sichert, ebp auf esp setzt, esp dekrementiert, je nachdem, wieviele Variablen man haben will und nun hat man einen ungenutzten Bereich, über den man per Offset (und der Offset ist natürlich auch bei jedem Programmstart gleich....) von ebp zugreifen kann, hier sind die Variablen.


----------



## Tobias K. (14. November 2004)

moin


Na gut hast mich schon fast überzeugt.
Wollte mich schon immer mal mit Assembler anfangen fand aber nie Zeit, vielleiht isses jetzt soweit.

Kennst du vielleicht auch noch gute Seiten bzw. Tutorials?


mfg
umbrasaxum


----------



## Beichtpfarrer (14. November 2004)

gute Asm-Tut-Seite weiss ich nicht, ich hab einfach mal in google gesucht un dann mal hier mal da gelesen. Eine davon hab ich noch in den Favoriten, viellleicht hilft die dir:
http://andremueller.gmxhome.de/befehle.html

Dann hab ich noch nen Interrupt Table:
http://www.ctyme.com/intr/int.htm

3 einigermassen gute Befehlsreferenzen:
http://palacebuilders.pwp.blueyonder.co.uk/Pentium.htm
http://faydoc.tripod.com/cpu/ja.htm
http://homepages.compuserve.de/fmatth01/8086Assembler/Asm.htm


----------



## Terrance & Philipp (14. November 2004)

Schau dir mal dieses Tool an:
http://www.cheat-it.com/memhack/


----------

