[C++] [Noob Friendly] Warrock NoMenu Base

08/30/2011 19:48 vwap#1
Abend.

Da ich gerade selber an einem Warrock Hack arbeite, würde ich euch gerne meine aktuelle NoMenu Base mit der "Superjump" Funktion erklären.

Vorrausetzungen
  • Microsoft Visual Studio 2010 oder Microsoft Visual C++ Express 2010
  • Vorkenntnisse in C++ sind vom Vorteil

Schritt 1 : Ein neues Projekt erstellen

Wir öffnen unsere Entwicklungsumgebung und erstellen ein neues leeres C++ Projekt.

[Only registered and activated users can see links. Click Here To Register...]

Schritt 2: Unsere erste .cpp Datei

Jetzt haben wir ein leeres Projekt.
Wie der Name schon sagt: leer.
Das heißt, wir müssen eine "Hauptdatei" hinzufügen.
Dazu machen wir einen Rechtsklick rechts beim "Projektmappen-Explorer" auf "Unser Warrock Hack", klicken auf "Hinzufügen" und "Neues Element".

[Only registered and activated users can see links. Click Here To Register...]

Nun erscheint ein Fenster.
Dort wählen wir die "C++ Datei (.cpp)" aus und nennen diese "main.cpp".

[Only registered and activated users can see links. Click Here To Register...]

Schritt 3 : Projekt Eigenschaften

Da ein leeres C++ Projekt standartmäßig versucht, eine ausführbare Datei, also eine ".exe" zu erzeugen, ändern wir dies in den Projekteigenschaften.
Wir klicken auf "Projekt" und dann auf "Unser Warrock Hack-Eigenschaften".

[Only registered and activated users can see links. Click Here To Register...]

Nun klicken wir auf "Allgemein" und wählen bei "Konfigurationstyp" "Dynamische Bibliothek (.dll)" aus.

[Only registered and activated users can see links. Click Here To Register...]

Schritt 4 : Includes und DllMain

Zunächst includen wir windows.h und stdio.h:
Code:
#include <windows.h>
#include <stdio.h>
Jetzt kommen wir zur Hauptfunktion unserer DLL.
Sie wird aufgerufen wenn etwas mit unserer DLL passiert.
Beispielsweise wenn sie in einen Prozess injeziert wird.

Also fangen wir an:
Code:
bool WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) {

   return true;
}
Da diese Funktion aber auch aufgerufen wird, wenn unsere DLL wieder aus dem Prozess "genommen" wird, müssen wir den Aufruf spezifizieren.
Das geht wiefolgt:
Code:
bool WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) {
   switch (reason) {

      case DLL_PROCCESS_ATTACH:

      break;

   }

   return true;
}
Das sollte nun so aussehen:

[Only registered and activated users can see links. Click Here To Register...]

Schritt 5 : Die "Hackfunction"

Nun erstellen wir uns eine neue Funktion.
Diese wird aufgerufen, sobald unsere DLL injeziert wird:
Code:
void HackThread() {
	for (;;) {
		if (GetAsyncKeyState(VK_NUMPAD1)) {

		}
	}
}
Das "for (;;)" bewirkt eine Endlosschleife.
In dieser Schleife wartet unsere DLL, bis der Benutzer die Taste NUMPAD 1 betätigt.

Jetzt müssen wir noch folgenden Code im Case Block der DllMain hinzufügen:
Code:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE) HackThread, 0, 0, 0);
Schritt 6 : Memory Adressen

Für unsere Memory Adressen erstellen wir eine neue Header Datei.
Dazu macht ihr wieder beim "Projektmappen-explorer" auf "Unser Warrock Hack" einen Rechtsklick, klickt auf "Hinzufügen" und dann auf "Neues Element".

Dann wählen wir die "Headerdatei (.h)" aus und nennen diese "addresses.h".

[Only registered and activated users can see links. Click Here To Register...]

Die aktuellesten Adressen gibt es hier: [Only registered and activated users can see links. Click Here To Register...]

Dann definieren wir in unserer neu angelegten Datei "addresses.h" folgendes:
Code:
#define PTR_PLAYER							0x009D8AF0
#define OFS_PLAYER_POS_Z					0x00102E4
[Only registered and activated users can see links. Click Here To Register...]

Schritt 7 : Der Superjump

Nun müssen wir noch unsere Adressen-Datei in der main.cpp includen:
Code:
#include "addresses.h"
Jetzt fügen wir noch in unserer Tastenabfrage den eigentlichen "Superjump" Code ein:
Code:
*(float*) (*(DWORD*) PTR_PLAYER + OFS_PLAYER_POS_Z) = 2000;
Dies sollte nun so aussehen:

[Only registered and activated users can see links. Click Here To Register...]

Jetzt klickt ihr noch oben auf "Erstellen" und dann auf "Unser Warrock Hack erstellen".
Jetzt befindet sich unser Hack im Project Ordner unter "Debug".
Diese DLL jetzt einfach mit einem Injector, z.B. PerX in WarRock.exe inijzieren und dann Ingame die Taste "Numpad 1" drücken.

Schlussaufgabe

Da ihr ja jetzt eigendlich etwas gelernt haben solltet, stelle ich euch eine Aufgabe:
Derzeit crasht das Spiel, wenn man Numpad 1 drückt, und man nicht im Spiel selbst ist.
Wie kann man das verhindern?
Ich gebe euch einen Tipp: Ihr braucht dazu nur den Player Pointer und eine If Abfrage.

- Headpuster
08/31/2011 00:40 .BritainAndy#2
1.Find ich gut dass du dir ein wenig mühe gemacht hast, aber was ich nicht ganz verstehe:
- 1. Du erklärst wie man ne cpp datei hinzufügt, ne header dater ...
~ ich denke das sollte man wissen wenn man sich mit dem gamehacking befasst
- 2. Du erklärst folgendes gar nicht:
Code:
*(float*) (*(DWORD*) PTR_PLAYER + OFS_PLAYER_POS_Z) = 2000;
sieht für mich nach C&P aus weil du das kein bisschen erklärst aber wie man ne header datei erstellt schon. Also meines Erachtens nach hast du gar keine genaue Ahnung was da überhaupt passiert
08/31/2011 06:27 buFFy!#3
ein paar kleine ding:

statt dem switch kannst du auch if nehmen wenn du sowieso nur dll_process_attached abfragst. da kannst du auch direkt noch disablethreadlibrarycalls aufrufen!

und wenn ich nicht will das das spiel crasht brauch ich dafür keinen playerpointer sondern pack das einfach in nen try-except block.

for( ;; ) ist sehr unsauber, nimm stattdessen while(true).
kann sein das nur ich das so sehe, aber ich find das ist ein verdammt schlechter stil oO

und wenn ich ein programm nutzen will dann kompilier ich es ganz sicher nicht als debug.

dein dllmain returned immer true.
entweder ist dir das ausversehen passiert oder du hast keine ahnung was du da eigentlich machst.

bei deiner numpad1-abfrage nutzt du getasynckeystate nur 1x. der wert wird dann wahrscheinlich um die 50x geschrieben, halt auf jeden fall mehr als 1x.
besser wäre du fragst ab ob's gedrückt ist, und wartest dann solange bis es nichtmehr gedrückt ist, um eben zu verhindern das der wert sinnlos oft geschrieben wird.

ansonsten schließe ich mich meinem vorposter an.
08/31/2011 06:29 insong#4
how to do this?
08/31/2011 09:45 vwap#5
Danke für eure Kritik,
bei .BritianAndy's Aussage, das ich nicht weiß, was da passiert, muss ich korrigieren.

Dort wird der Offset der Z Koordinate zum Playerpointer addiert.
Folgende Interne Schritte laufen dann ab:
  • Die neue Speicheradresse wird zum Schreiben konfiguriert.
  • Der Wert 2000 wird in die "Schachtel" der Adresse geschrieben.
  • Die Speicheradresse wird wieder freigegeben.

Und ja while (true) ist schöner, wobei es unsauber ist, die Abfrage einfach in einen try - catch block zu schreiben.
08/31/2011 12:06 yihaaa#6
aber wieso float?

MfG
08/31/2011 13:44 vwap#7
Weil die Koordianten float Angaben sind und wir diese auch so referenzieren müssen.
08/31/2011 14:13 yihaaa#8
Aber 2000 ist doch kein float.
MfG
08/31/2011 15:53 vwap#9
Wird aber durch die referenzierung zu einem Float gemacht.
09/01/2011 16:48 Ende!#10
while(1) > for(;;)
Allerdings eigentlich nur der Gewohnheit, nicht dem Stil wegen. Technisch setzt der Compiler (zumindest MSVC++) das gleich um und auch dem Stil tut das imo keinen großen Abbruch.

Quote:
wobei es unsauber ist, die Abfrage einfach in einen try - catch block zu schreiben.
Stimme ich dir teilweise zu. Es ist wesentlich performanter ein IsBadReadPtr zu verwenden, als das Programm ohne Rücksicht in eine Access Violation rennen zu lassen. Allerdings kann ein zusätzlicher __try,__except Block nie schaden. Wenn man tatsächlich nur einen Memread/write hat, ist das natürlich überflüssig, bei größeren 'Hacks' aber durchaus sehr sinnvoll.

@yihaaa: Das Spiel speichert die Höhenangabe aber offenbar in einer float-Variable, also musst du diese auch als solche behandeln, wenn du sie verändern willst ;o
09/02/2011 11:35 xNopex#11
Quote:
Es ist wesentlich performanter ein IsBadReadPtr zu verwenden, als das Programm ohne Rücksicht in eine Access Violation rennen zu lassen.
Evtl. mal in der MSDN nachlesen, warum das falsch ist. Memory-"Hacking" ist so ein exotisches Gebiet, da gibt es sowas wie "guten Stil" nicht. Ihr könnt keine Thread-Synchro, gar nichts, garantieren, wenn ihr euch in den Prozess mit fragwürdigen Methoden einklingt. Es ist immer eine Art russisches Roulette.
09/02/2011 11:53 Ende!#12
Quote:
Originally Posted by xNopex View Post
Evtl. mal in der MSDN nachlesen, warum das falsch ist.
Whoops, wie ich den Hinweis halt übersehen hab. Nunja, ich bin in der Vergangenheit immer recht gut damit gefahren. Dennoch muss ich meinen Einwand dann natürlich zurücknehmen, zumal wir hier ja über "guten Stil" diskutieren. Nunja, dann müsste man auf VirtualQuery ausweichen, wobei das dann vermutlich nochmal wesentlich langsamer ist, als das Programm direkt in die AV Exception rennen zu lassen.

Quote:
Originally Posted by xNopex View Post
Memory-"Hacking" ist so ein exotisches Gebiet, da gibt es sowas wie "guten Stil" nicht. Ihr könnt keine Thread-Synchro, gar nichts, garantieren, wenn ihr euch in den Prozess mit fragwürdigen Methoden einklingt. Es ist immer eine Art russisches Roulette.
Das sollte jedem bewusst sein, der sich mit diesem Gebiet bewegt. Aber man sollte sich ja wohl dennoch Mühe geben, die Gefahr eines Crashes so niedrig wie nur möglich zu halten, oder? Genau darüber reden wir doch gerade.
10/13/2011 20:23 muddaa#13
hilfeeee ich möchte gerne selber sowas wie einen sirosix (mir fiel kein anderer ein ) hack machen habe aber keine ahnung ( voll nooob) könntet ihr mir weiter helfen ??

edit:aso und ich brauche nicht mehr als chams no recoil nfd und eventuell superjump zu lernen wäre nett wenn ihr mir helfen könntet danke im vorraus:-)

nochmal edit: habe meine frage jetzt ins warrock forum in den Thread Hilfe verlegt
10/13/2011 22:03 MrSm!th#14
Quote:
Originally Posted by xNopex View Post
Evtl. mal in der MSDN nachlesen, warum das falsch ist. Memory-"Hacking" ist so ein exotisches Gebiet, da gibt es sowas wie "guten Stil" nicht. Ihr könnt keine Thread-Synchro, gar nichts, garantieren, wenn ihr euch in den Prozess mit fragwürdigen Methoden einklingt. Es ist immer eine Art russisches Roulette.
Das kommt von dem, der mir verbieten will, den Exit Code eines Remote Threads (den ich Mit GetExitCodeThread abfragen kann, wenn ich den Rückgabewert einer injizierten Funktion abfragen will) als Pointer oder anderen Rückgabewert zu missbrauchen? o.O

@TE:

Es ist nicht schlüssig, an welche Zielgruppe dein Tutorial ist.
Angesichts der Tatsache, dass du ein Tutorial über Gamehacking geschrieben hast und den Code eher so als c&p Code hinklatschst, könnte man meinen, es ist ein Source Code Release für Könner.
Allerdings hätten die weder das nötig, noch eine Anleitung, wie man ein Projekt erstellt o.o
Also was ist das? Eine Anleitung zum Happy Copypasting?

Und verdammt nochmal, ein Thread hat den Prototypen DWORD WINAPI (LPVOID) nicht void!
Es müsste DWORD WINAPI HackThread(LPVOID param); heißen!

Quote:
for( ;; ) ist sehr unsauber, nimm stattdessen while(true).
Da muss ich dir und Ende! widersprechen.

Wie Ende! schon sagte, beides wird gleich umgesetzt.
Vom Stil her sehe ich beides oft, soweit ich weiß ist keins von beidem mehr oder weniger gern gesehen.

Also wäre das letzte Kriterium, um die Stile zu vergleichen der Aufwand. Und for( ;; ) ist kürzer als while(true) und als while(1)!

Da es sich aber bei letzterem nur um eine Differenz von 1 handelt, ist es so ziemlich egal und Geschmackssache.
07/11/2012 13:05 K1ngPr0g4mer#15
Bei mir kommt der fehler


1> main.cpp
1>main.cpp(16): error C2065: 'DLL_PROCCESS_ATTACH': nichtdeklarierter Bezeichner
1>main.cpp(16): error C2051: case-Ausdruck ist keine Konstante
1>main.cpp(20): warning C4060: switch-Anweisung enthält weder 'case'- noch 'default'-Marken

was nun machen ???
wenn der fehler beim erstellen der base kommt ??