CSS Cheat schreiben?

Hey Community,

da ich ziemlich häufig CS:S zocke und immer wieder irgendwelche Wallhacker sehe, habe ich mir gedacht selber mal solch einen Cheat zu schreiben. 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.
Ist es überhaupt möglich mit Java solche Programme zu schreiben, oder ist vll. c# oder python o.ä. besser geeignet?
Mir würde schon eine grobe Vorgehensweise reichen, um erstmal den richtigen Pfad anzunehmen, den Rest "ertaste" ich mir dann selbst ;)

grüße coco07!
 
Zuletzt bearbeitet:
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
 
Zuletzt bearbeitet:
Hey ChiefWiggum,

vielen vielen Dank für deine wirklich ausführliche Antwort. TOP!
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.
Das ganze dient natürlich nur der Übung für mich selbst. Die Cheats sollen nicht veröffentlich werden oder sonstiges.

Ich werde mal sehen, wie weit mich das ganze bringt und dann mal feedback geben, wenn ich Resultate erreicht hab.

Vielen Dank nochmal :)

grüße coco07!
 
Eins noch: Steam versucht Cheater natuerlich zu erkennen, VAC/VAC2 heisst der Spass, dh wenn dir dein Steam-Account lieb ist und du nicht gerne als Cheater gebannt werden willst solltest du nicht mit deinem Steam-Account cheaten. Ich weiss nicht, ob das System komplett deaktiviert ist, wenn man nicht auf VAC-aktivierte Server geht (koennte man dann ja lokal aufmachen), das solltest du dann recherchieren.
 
Nur eine kleine Anmerkung zu:
Deswegen ist C# und python auch nicht wirklich geeignet.

Da muss ich widersprechen.
Gray Hat Python(google: 'type:pfd Gray Hat Python') zeigt beispielsweise ganz gut wie man das ganze in Python bewerkstelligen kann.
Für Code Injection (im Gegensatz zur Manipulation) sind c(besser Assembler) Kenntnisse trotzdem von Vorteil (unabdingbar ?)
 
Es gibt bestimmt auch wege, dies mit anderen Sprachen zu machen, aber da kenne ich mich nicht so recht aus.
Widersprichst mir ja nicht, ergaenzt nur meinen Post :)

Habe mal kurz die Topics ueberflogen, die Hooks in Python scheinen per debugging & breakpoints geregelt zu sein, was dort aber nicht moeglich ist, ist andere Funktionen zu callen? Bzw auch wenn's da interfaces gibt, jedes mal den Prozess zu breaken ist jetzt bestimmt nicht die performateste Methode.

CodeExecution: Es wird Asm-Code injected, kein Python-Code.

Was das DLL injecten betrifft: Der DLL-injector ist in Python geschrieben, die DLL ansich aber ja nicht. Diese ist dann wieder in einer Programmiersprache und keiner Scripting-Sprache geschrieben.

Wenn ich irgendwie falsch liege, korrigier mich bitte, aber so wie es fuer mich aussieht ist Python hier nur dafuer zustaendig, den Asm-Code in den Prozess zu bringen und nicht wirklich um ihn zu produzieren.
 
Du hast natürlich recht das kein python code injected wird.

Man kann allerdings mit CreateRemoteThread/NtCreateThreadEx funktionen mit einem Parameter ausführen, oder auch shellcode einfügen und laufen lassen.

[size=-2]Ich habe da vor einiger Zeit mal was gebastelt was sich wie folgt bedienen lässt:[/size]
Code:
    code = sh_funcHeader
    code += sh_someFunc("kernel32.dll", "Sleep", (c_int32(2000),), False)
    code += sh_someFunc("kernel32.dll", "ExitProcess", (c_int32(0x1D1ed),), False)
    code += sh_funcFooter
    rHandler.injectCode( code, waitForIt=True)

Also als fazit: Python zum injecten in ordnung (Vlt. sogar ein wenig komfortabler als c). Wen es allerdings um komplexere Anforderungen geht ist c sicherlich die bessere Wahl.
 
Zuletzt bearbeitet:
C ist auf Dauer ziemlich umständlich: editieren, kompilieren, injecten...

LuaJIT liefert eine zeitsparende REPL-Umgebung und kann trotzdem sehr gut mit Strukturen und Pointer umgehen. Man kann selbst Lua-Funktionen als C-Callbacks setzen.

FFI Library

Generell kann man natürlich jede Skriptsprache ala Java und Python verwenden, einfach nach "embed $name" googlen.
 
Und wodrin ist die LuaJIT Lib geschrieben? C - Ueberraschung :P Auf die schnelle habe ich jetzt da aber keine Moeglichkeit gefunden, funktionen zu hooken, oder ist das damit auch moeglich?
Generell kann man natürlich jede Skriptsprache ala Java und Python verwenden, einfach nach "embed $name" googlen.
Aber nicht as-it-is, da muss immer noch eine "uebersetzungsschicht" zwischen sein, die dann in Assembly ist. Anders kann ich mir das nicht vorstellen. Wenn ich falsch liege, gibt mir bitte ein Beispiel.
 
Um noch etwas zu ergänzen:
Code Injection ist doch absolut nicht nötig.

einfach drüberzeichnen würde es doch genauso tun ;) ?
 
Natuerlich kann man sich auch auf Werte auslesen + ueberzeichen beschraenken, aber wie will man zuverlaessig rausfinden, wann neu gezeichnet werden muss? Und wie sollen Tastatureingaben angefangen werden?
Die "sauberste" Loesung ist imho Code Injection.
 
Natuerlich kann man sich auch auf Werte auslesen + ueberzeichen beschraenken, aber wie will man zuverlaessig rausfinden, wann neu gezeichnet werden muss?

Hat sich der Wert geändert == neuzeichnen != nix zeichnen ?!!:rolleyes:


Und wie sollen Tastatureingaben angefangen werden?

RegisterHotKey über die user32.dll wäre eine von vielen Möglichkeiten.:thumb_up:

Die "sauberste" Loesung ist imho Code Injection.
Meiner Meinung nach nicht, aber dass ist nur meine Meinung :D
 
Hat sich der Wert geändert == neuzeichnen != nix zeichnen ?!!:rolleyes:
Und wenn sich das Frame aendert dh das Spiel das Spiel den "Hack" ueberzeichnet, den Wert aber nicht aendert? Dann hast du ein ganzes Frame lang etwas ueberzeichnet, sehr huebsch.
In einer busy loop ueberzeichnen? = Flackern. Spiele benutzen nicht ohne Grund Double oder sogar Triple Buffering.

RegisterHotKey über die user32.dll wäre eine von vielen Möglichkeiten.:thumb_up:
Scheint mir aber eher fast die einzige zu sein. Und wie ist das wenn man die Taste gedrueckt hat? Afaik wird die WM_HOTKEY msg nur einmal geschickt.
Falls du jetzt mit anderen Moeglichkeiten GetAsyncKeyState meinst - Eine busy loop ist jetzt doch nun wirklich alles andere als performant. Schreit auch foermlich nach einen nicht noetigen zweiten Thread. Und zu hooks: Rate mal was die machen. DLL(=Code) injection ;) [Ausser die _LL varianten]
 
Und wenn sich das Frame aendert dh das Spiel das Spiel den "Hack" ueberzeichnet, den Wert aber nicht aendert? Dann hast du ein ganzes Frame lang etwas ueberzeichnet, sehr huebsch.
In einer busy loop ueberzeichnen? = Flackern. Spiele benutzen nicht ohne Grund Double oder sogar Triple Buffering.


Ich zeichne ja in meiner Variante nicht in das spiel rein ;-) Daher kann mir das egal sein :):)


Scheint mir aber eher fast die einzige zu sein. Und wie ist das wenn man die Taste gedrueckt hat? Afaik wird die WM_HOTKEY msg nur einmal geschickt.
Falls du jetzt mit anderen Moeglichkeiten GetAsyncKeyState meinst - Eine busy loop ist jetzt doch nun wirklich alles andere als performant. Schreit auch foermlich nach einen nicht noetigen zweiten Thread. Und zu hooks: Rate mal was die machen. DLL(=Code) injection ;) [Ausser die _LL varianten]

Gibt auch noch GetKeyState :wink: GetAsyncKeyState sollte man sowieso nicht hernehmen :thumb_down:. Gerade nicht, wenn hohe prozessorlast vorhanden ist. Performance hin oder her. Das sollte micht jetzt nicht so stören wenn ich n PC habe wo ich drauf zocke :D So viel frisst das nicht ;)

Wenn ich dass allerdings via Hooks löse, ist aber keine Code Injection innerhalb von CSS nötig, sehe ich das schon richtig oder?

Also meiner Meinung ist mein Beispiel aus dem Grund besser, da er UD bleibt, bis er tatsächlich von Valve gefunden, und entsprechend dann erkannt wird. Da die sonst ja von seiner Existenz nicht wissen können.

Die Code Injection könnten Sie doch rausfinden ..?
 
Bliebt aber trotzdem ja auch noch ein moeglicher Delay, je nachdem was du zeichnest. Und ist das ganze dann auch Screenshot-proof?

GetKeyState benoetigt ja aber auch eine loop und je schneller auf Eingaben reagiert werden soll desto kleiner darf der Delay in der loop sein wenn ich nicht falsch liege.

Was jetzt den detectable-Aspekt betrifft(der wurde ja bis jetzt noch gar nicht beruecksichtigt) wird code injection natuerlich ziemlich noisy sein.
Ich glaube aber nur mit speicher lesen + zeichnen wird man jetzt nicht die besten Resultate erzielen. Gerade weil Valve da auch so das eine oder andere "Feature" eingebaut hat. Ich habe mich allerdings auch nie mit VAC(2) o.Ae ausenandergesetzt, kann demnach da nicht viel Wissen beitragen.
 
Bliebt aber trotzdem ja auch noch ein moeglicher Delay, je nachdem was du zeichnest. Und ist das ganze dann auch Screenshot-proof?

Ingame Screenshot proof: Kann sein, ich weis nicht was da aufgenommen wird, allerdings sicher nicht gegen spezielle Anti-Cheat Systeme die den Bildschirm aufnehmen.

GetKeyState benoetigt ja aber auch eine loop und je schneller auf Eingaben reagiert werden soll desto kleiner darf der Delay in der loop sein wenn ich nicht falsch liege.

Korrekt, aber für was brauchst du bei nem Wallhack&Aimbot soviele Tasten? Einmal für aktivieren und einmal deaktivieren reicht doch.

Was jetzt den detectable-Aspekt betrifft(der wurde ja bis jetzt noch gar nicht beruecksichtigt) wird code injection natuerlich ziemlich noisy sein.
Ich glaube aber nur mit speicher lesen + zeichnen wird man jetzt nicht die besten Resultate erzielen. Gerade weil Valve da auch so das eine oder andere "Feature" eingebaut hat.

Tja so ist das in der IT.. Ständig kommen neue Anforderungen :P:D:wink:
Also meiner (CS:GO) klappt ohne code injection. Ist zwar manchmal bisschen buggy, gezeichnete Objekte sind plötzlich vor einem u.ä. :D, aber sonst lief er damals problemlos. Wurde ja nur zu Lernzwecken entwickelt, da muss er ja nicht in allen Details einwandfrei funktionieren. Und nein, ich verwende den nicht, nur singleplayer wenn ich mal abundzu dazu komm drann rum zu schrauben... :)
 
Zuletzt bearbeitet:
@CodeInjection (wenn man z.B unbedingt aktuelle Werte braucht und nicht über ReadProcMem pollen möchte) - es zwingt doch niemand einen, unbedingt eine DLL über den "offiziellen" Weg einzuschmuggeln (LoadLibrary&Co) - und damit in der Modul-Liste des Prozesses einzutragen ;)

Mit etwas Aufwand lässt sich so ein Teil auch "zu Fuß" (also kleine Assemly-Stub) laden und initialisieren. Dann bleibt für den "Detector" ein regelmäßiges Abklappern aller Speicherregionen (und dann: schwarze Magie :) ) und/oder ggf. der "Einschmuggelvorgang" selbst. Allerdings hat die "Spielerei" mit solchen Codeinjections noch vor ein paar Jahren ganz gut bei den "marktführenden Softwareprotectoren" geklappt - und die haben teilweise einen "Heidenaufwand" (bzgl. Aufwand/CPU-Last der "Gegenmethoden") betrieben.
 
@CodeInjection (wenn man z.B unbedingt aktuelle Werte braucht und nicht über ReadProcMem pollen möchte) - da zwingt doch niemand einen, unbedingt eine DLL über den "offiziellen" Weg einzuschmuggeln (LoadLibrary&Co) - und damit in der Modul-Liste des Prozesses einzutragen

Das bedeutet aber nicht, das VAC2 nicht in der lage wäre, diese Code Injection feststellen zu können, right?
 
Korrekt, aber für was brauchst du bei nem Wallhack&Aimbot soviele Tasten? Einmal für aktivieren und einmal deaktivieren reicht doch.
Naja, das Dach muss halt auch nicht ganz dicht sein, weil es nur 2x im Jahr regnet?
Ich mags gerne sauber.

Tja so ist das in der IT.. Ständig kommen neue Anforderungen :P:D:wink:
Sicher, aber das ist in dem Gebiet fuer mich persoenlich nicht so wichtig. Wenn ich irgendwann mal Lust auf ein Puzzel hab guck ich mir sowas an.

Das bedeutet aber nicht, das VAC2 nicht in der lage wäre, diese Code Injection feststellen zu können, right?
Hab mal gelesen, dass um "kritische Codestellen" checksums verifiziert werden. Was aber, wenn VAC2 nicht mehr in der Lage ist, korrekt zu verifizieren, weil es selbst @ runtime ein nettes "feature" dazu bekommen hat?
 
Hab mal gelesen, dass um "kritische Codestellen" checksums verifiziert werden. Was aber, wenn VAC2 nicht mehr in der Lage ist, korrekt zu verifizieren, weil es selbst @ runtime ein nettes "feature" dazu bekommen hat?

Viel Erfolg dabei :D
Wenn es als Dienst aktiv ist, was VAC2 sein muss damit es als "korrekt laufend" erkannt wird (wenn mich nicht alles täuscht), wird dir wohl die Datenausführungsverhinderung dazwischen grätschen bei dem Versuch :D. Wobei ich nicht weis ob mit "und Dienste" alle Dienste gemeint sind ?
 
Zuletzt bearbeitet:
Zurück
Oben