Hi coco07,
Zuerstmal solltest du dir selbst ueberlegen, wozu du den Cheat schreiben willst. Um selbst zu cheaten oder aber um damit Geld zu verdienen? Oder aber willst du was lernen und hast nicht vor, ihn 'in the wild' einzusetzen.
Ich gehe jetzt einfach mal vom letzteren aus, die ersten beiden Gruende sind imho nicht sonderlich moralisch, aber das ist auch nur meine Meinung.
Ein "Cheat" zu schreiben ist in der regel ganz einfach, bei Wallhacks sieht es da meistens schon was anders aus. Es gibt einen grossen Unterschied zwischen "mal eben einen Wert auf 99999 freezen, damit man unendlich Geld hat" und einem Wallhack/Hitboxen und whatever es alles bei den "pr0 cheatz" gibt.
Nun, ich programmiere seit einem Jahr in Java und habe schon zahlreiche Android Apps geschrieben. Wie aber schreibe ich ein Programm für ein Spiel? Der Weg dürfte entweder sein, ein Programm zu schreiben, was verschiedene Anfangswerte setzt und dann das Spiel startet und evtl. vortäuscht die richtigen Daten zu verwenden oder dem Spiel während der Laufzeit andere Werte zuzuweisen.
Hast du schonmal versucht, ein Spiel zu schreiben? Versuch mal den logischen Aufbau vom Spiel nachzuvollziehen, z.B. du hast Spieler, jeder Spieler hat Koordinaten und eine Blickrichtung. Zusaetzlich hat er noch HP, Munition und was auch immer. Diese Daten muessen ja irgendwo im Speicher sein. Dh der erste Schritt ist, diese Speicherstrukturen zu rekonstruieren. Das kann man z.B. mit "CheatEngine" machen. (aufpassen, der Installer will einem mittlerweile leider Adware und stuff andrehen -.-) Das ganze wird oftmals noch etwas vereinfacht, wenn man sich einen Disassembler greift wie z.B. IDA. Mit der Kombination kann man schon nach einigen Stunden viele Aussagen machen.
Wenn man das gemacht hat, hat man im Endeffekt folgende Informationen:
1.) Struktur, Beispiel:
Code:
stuct Player{
float X, Y, Z;
int HP;
int maxHP;
int team;
bool isAlive;
char playername[32];
//...
}
2.) Die Speicheradresse von dem Player.
Da quasi alle Spielwerte bei vielen Spielen auf dem Heap liegen ist die Adresse jedes mal anders. Dh sie ist nicht statisch im Sinne von programmname.exe+offsetX adressierbar.
Stattdessen wird irgendwo an einer statischen Adresse ein Pointer zu dem Heap sein, wo die Daten dann sind.
Beispiel:
Code:
// .. includes
Player* player[MAX_PLAYER] = {0};
// ...
void init_game(int num_player){
// validiere werte
for(int i = 0; i < num_player; i++) player[i] = new Player;
// ...
}
Das Array aus Player-Pointern ist an einer statischen Adresse, die Player ansich nicht. Um nun mit einem externen Programm an die Player-Werte zu kommen musst du erst das Pointer-Array auslesen und gucken, an welcher Adresse die Werte stehen.
Das kann natuerlich beliebig tief sein:
Code:
class Team{
// ...
Player* player[MAX_PLAYER];
// ...
}
class Level{
// ...
Team* teams[MAX_TEAMS];
// ...
}
class Game{
//...
Level* currentLevel;
// ...
}
// Und dann global:
Game* game_instance = new Game();
Somit muesstest du dann in den Game-Ptr aufloesen, dann da dem Level-Ptr folgen, dann dem Teamptr um dann zum User-Ptr-Array zu kommen, dem du dann zu den gesuchten Werten folgen kannst.
Das ganze hat aber ja jetzt nichts mit einem Wallhack zu tun, oder?
Jain. Fuer Wallhacks gibt's verschiedene Techniken. Bei OpenGL kann man einfach den DEPTHTEST Modus deaktivieren, dann ueberprueft OGL nicht, ob das zu zeichnende Objekt vllt hinter einer Wand ist und zeichnet es drueber. Das Resultat: Entities sind durch Waende sichtbar[1]. Funktioniert natuerlich nur bei OpenGL, vllt gibt es bei DX aehnliche Funktionen, ich weiss es nicht.
Eine andere Technik ist es, die Koordinaten von den Spielern zu nehmen und diese mit Boxen zu umranden. Dafuer brauch man die Koordinaten, die man dann ja jetzt hat.
Es gibt bestimmt noch weitere findige Methoden, aber das reicht vorerst mal.
Aber wie zeichnet man / deaktiviert man den Modus?
Dafuer benoetigt man code-execution in dem Zielprozess. Dh man injiziert eine DLL die die gewuenschten Funktionen hookt in den Zielprozess oder schreibt eine Wrapper-DLL (OpenGL), die die Funktionen dann einfach mit ggf geaenderten parametern weiterleitet.
Hab ne DLL im Prozess, und wie zeichne ich jetzt was?
Was benutzt der Zielprozess fuer eine Grafikschnittstelle? DX9/10/11? OpenGL? SDL? <Whatever>?
Lies dir die Manuals durch. Im Endeffekt programmierst du jetzt selber etwas fuer DX/OGL/...
Wenn du z.B. ein Spiel hast, dass eine Lib Acme benutzt, die eine DrawRect(int x, int y, int w, int h) Funktion besitzt und du ein Rechteck zeichnen willst machst du das etwa so:
Code:
// Dll code, hook render-loop vom Game kurz vorm buffer-flip (oder sogar die buffer flip Funktion hooken)
void hook_awesome(){
Player* player = // Lade irgendwie die Adresse vom Spieler
int screen_x, int screen_y;
translate_player_coords_in_screen_coords(player, &screen_x, &screen_y);
DrawRect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT);
original_awesome(); // Originalfunktion aufrufen nicht vergessen.
}
Die Funktion translate_player_coords_in_screen_coords und die Konstanten musst du natuerlich selber implementieren. Die Funktion soll die 2 bzw 3D-Position vom Spieler mit dem Viewport der Kamera verrechnen um dann an die pixel-Positionen des Spielers auf dem Bildschirm zu kommen, wo dann das Rechteck drum gezeichnet wird.
Ist es überhaupt möglich mit Java solche Programme zu schreiben, oder ist vll. c# oder python o.ä. besser geeignet?
Jain. Ich bin mir nicht sicher, ob man mit Java auf Speicherbereiche fremder Prozesse zugreifen kann. In jedem Fall ist eine Code-Execution im fremden Prozess ausgeschlossen (wenn das Spiel nicht auch in Java geschrieben ist..), da dieser keine Java-Opcodes sondern natives x86(_64) ausfuehrt. Deswegen ist C# und python auch nicht wirklich geeignet. Du brauchst eine Sprache, die wirklich Maschinencode erzeugt, eg C(++). Es gibt bestimmt auch wege, dies mit anderen Sprachen zu machen, aber da kenne ich mich nicht so recht aus. Es gibt Wrapper um z.B. lua-Funktionen aus C/C++ heraus aufzurufen, daher wird es bestimmt auch gehen, (mithilfe von einem in C/C++ geschriebenen Loader) Funktionen im Spiel mit Lua zu "erweitern", allerdings benoetigen diese halt eine Wrapper-Umgebung die den Sprung von assembly -> Lua und zurueck macht.
Mir würde schon eine grobe Vorgehensweise reichen, um erstmal den richtigen Pfad anzunehmen, den Rest "ertaste" ich mir dann selbst
Ich hoffe, ich konnte dir eine grobe Richtung geben und hab mich nicht zu kompliziert ausgedrueckt.
ChiefWiggum
[1]
OpenGL:Making your first wall hack in OpenGL - UnKnoWnCheaTs Game Hacking Wiki