[C++] dll Hacks für Anfänger

10/06/2011 21:00 XxharCs#1
Heyho,
das mein Tutorial, wie man .dll Hacks erstellen kann. Das Opfer Programm ist das Online Spiel "FantasyTennis".(Bin auf dieses gekommen, da ichs grad zockte :p )

Was brauche ich ?
  • Grundlegende Kenntnisse in C++
  • Einen C++ Compiler/IDE
  • CheatEngine/T-Search/OllyDbg/.., halt ein Memory Search Programm
  • Das Spiel verstehen
  • Und Geduld^^

Wie finden wir die Adresse bzw. den Pointer(ggf in manchen fällen MultiPointer) ?

Was wollen wir machen ?

Wir möchten den Punkte Stand in dem Single Player Modus ändern bzw. den Punkte Stand ercheaten/erhacken. (Für Multiplayer Modus müsste man es mit Packet editing machen damit man sich die Punkte erhacken kann.)

Wie finden wir die Punkte Stand Adresse ?

Wir starten Fantasy Tennis und gehen in den SinglePlayer Modus und starten das Match. Wir öffnen zb: Cheat Engine 6.1(da sie zurzeit nicht detected wird) und attachen FT.
Wir suchen dann nach 0.
Sobald die Suche beendet ist haben wir in den Suchergebnissen viele Adressen.
Deswegen lassen wir im Spiel 1 Ball durch und wir haben somit den Punktestand 0:15
Zurück in der CE suchen wir nach 1.
Jetzt haben wir wieder viele Adressen aber nicht so viele wie vorher.
Also lassen wir wieder ein Ball durch, dass wir dann einen Punktestand 0:30 haben.
In der CE suchen wir nach 2.
Jetzt lassen wir noch einmal den ball durch und haben den Punktestand 0:40. In der CE suchen wir nach 3.
Jetzt haben wir da eine Adresse stehen ! Da sie kein Pointer ist ändert sie sich nach jedem neustart von FT, also müssen wir den Pointer Suchen.
Also ziehen wir diese Adresse runter und machen ein rechtklick drauf -> "Pointer Scan for this Adress". Jetzt haben wir ein neues Fenster offen und da machen wir ein hackerl auf "Improve pointerscan with gathared heap data" und auf "Only allow static and heap adresses in path" und starten den pointerscan mit "Ok".

Wenn die Suche beendet wurde haben wir da eine Adresse: FT_Client.exe+003C5448 und seine offsets. Wir machen ein doppel Klick drauf damit wir die adresse unten in unserer Liste haben.

Den Pointer haben wir jetzt und jetzt zum Coden =)

Wie erstellen wir nun unseren .dll hack ??

Der Typ unseres Pointers ist 4 Byte, was somit bedeutet das der typ long, int oder/und float ist. In den meisten fällen ist es ein long, also verwenden wir long in unserer dll.

Der Datentyp long ist ein signed long, also geht es von –2,147,483,648 to 2,147,483,647.
Da wir aber nicht in den minus wert gehen wollen verwenden wir unsigned long. unsigned long geht von 0 to 4,294,967,295. Da wir also unsigned long haben können wir DWORD verwenden. Der DWORD ist Äquivalent unsigned long.

Erstellt ein neues Win32 Pojekt und wählt DLL aus.
So nun fangen wir mit dem coden an, und so sieht unser Grundgerüst fürs erste aus:
Code:
/*
 *Wir inkludieren die "stdafx.h und iostream(=input output)
 *iostream ist aber nicht nötig^^
*/
#include "stdafx.h"
#include <iostream>

using namespace std;

DWORD BasePointer = 0;  // Wir deklarieren den BasePointer und setzten ihm den Wert 0
#define Points 0x00000424  // Hier definieren wir unseren Offset des Pointers

bool State = false;   // Brauchen wir später für das einschalten und auschalten des Hacks

void punkte()    // unsere main funktion
{



}
Ich denke das versteht jeder ;)
Jetzt machen wir weiter mit unserer Funktion, denn wir wollen das sie auch was macht :P Wir werden mit unserem State werte setzen für das ein-und ausschalten unseres Hacks. Wir werden auch eine neue Pointer Variable definieren.

Code:
/*
 *Wir inkludieren die "stdafx.h und iostream(=input output)
 *ist aber nicht nötig^^
*/
#include "stdafx.h"
#include <iostream>

using namespace std;

DWORD BasePointer = 0;  // Wir deklarieren den BasePointer und setzten ihm den Wert 0
#define Points 0x00000424  // Hier definieren wir unseren Offset des Pointers

bool State = false;   // Brauchen wir später für das einschalten und auschalten des Hacks

void punkte()    // unsere main funktion
{
        if(State)
    {
        DWORD dwBasePointer = *(DWORD*)BasePointer;  // Unser Pointer den wir als hilfe verwenden werden um einen Wert der Adresse hinzu zufügen 
        if(dwBasePointer != 0) // Wenn der Pointer nicht 0 ist wird der Wert zugewiesen
        {
            DWORD &dwPoints = *(DWORD*)(dwBasePointer +  Points); // Hier machen wir eine neue Variable durch den Base Pointer und denn Offset und haben somit die Pointer Adresse

            dwPoints = 4; // Hier bekommt der Pointer bzw. Adresse den Wert 4, 4 macht dann für dich einen ganzen set. 
                                           //Also ball durchlassen und du bekommst den Set (1:0)

        }

    }
    else // Vom State, also deaktivieren wir hier den Hack
    {
        DWORD dwBasePointer = *(DWORD*)BasePointer;  // machen wieder eine neue Variable wie oben
        if(dwBasePointer != 0)  // wenn der Pointer nicht 0 ist wird der Wert zugewiesen
        {    
            DWORD &dwPoints = *(DWORD*)(dwBasePointer +  Points);  // wie oben definieren wir mithilfe des Pointers und Offsets die Adresse

            dwPoints = 0; //setzt den wert 0, also ist der Hack deaktiviert

        }
    }
}
So nun haben wir die main funktion =) Jetzt fehlt uns nur noch unser HackThread der das ganze halt aktiviert und halt erstellt

Code:
DWORD WINAPI HackThread(LPVOID unused)
{
    //---Hier wird unser BasePointer ausgerechnet !
    DWORD ImageBase = (DWORD)GetModuleHandle(0);  //Die Image Adresse ist in diesem fall FT_Client, holen uns also den Module Handle
    BasePointer = ImageBase + 0x003C5448;  // Um den BasePointer zu bekommen nehmen wir die Image Adresse und unsere Modul Adresse
        //---------------------------------------------

    for(; ;)  //Eine unendliche schleife weil wir die Adresse gefreezt haben wollen ;)
    {
        punkte();  //unsere main funktion wird ausgeführt
        if(GetAsyncKeyState(VK_F1)&1)State =! State; // Mit F1 aktivieren und deaktivieren wir den Hack
        Sleep(10);
    }
}
So im großen und ganzen war das schon, wir brauchen nur noch das dll Grundgerüst, also:
Code:
BOOL WINAPI DllMain(HINSTANCE mod, DWORD DWORD_GRUND, LPVOID res)
{
    switch(DWORD_GRUND)
    {
    case DLL_PROCESS_ATTACH:  //Falls die dll erfolgreich injeziert wird
        CreateThread(0, 0, &HackThread , 0, 0, 0);  // Wir erstellen den Thread in dem dann später injezierten Process
        break;
     case DLL_PROCESS_DETACH:  //Falls die dll den Process nicht mehr findet
        MessageBoxA(0, "Not Loaded", "Info",0);  //Eine Messagebox die sagt das dll nicht mehr geladen ist
        break;
    }
    return TRUE;
}
So das wars schon mit unserer .dll =)

Ich weiß, mag sein das ich vill etwas mehr in das Spiel eingegangen bin,für den Pointer und so^^, aber der rest funktioniert gleich für jedes Spiel.
Das Problem ist nur, dass die Pointer suche in jedem Spiel anders ist, aber das erstellen eines dll hacks funktioniert auf diesem Prinzip.

Also ich hoffe ihr habt was daraus gelernt :cool:

Nehme gern Verbesserungsvorschläge und Kritik an =)


Mfg XxharCs
10/08/2011 20:00 supercracker13#2
Du kommst mit wie gerufen danke

Ich werde es nachher mal testen


aber eine Frage

Ich kenne von Auto it das man den Prozess angibt
Das ist hier auch Sicher so

Wo muss man den den prozessnamen zb inkball.exe
Hinzufügen
10/08/2011 21:11 XxharCs#3
Quote:
Originally Posted by supercracker13 View Post
Du kommst mit wie gerufen danke

Ich werde es nachher mal testen


aber eine Frage

Ich kenne von Auto it das man den Prozess angibt
Das ist hier auch Sicher so

Wo muss man den den prozessnamen zb inkball.exe
Hinzufügen
Das ist eine dll was auch heißt das man den Prozess Namen nicht angeben muss. Man verwendet einfach einen Injector, wählst das Process aus das du injecten willst und wählst dann deine dll. Den rest macht die dll =)
10/09/2011 08:21 supercracker13#4
Sry das ich noch was fragen muss

Aber das Warnike wichtig


Wie mache ich das bei 5 Offsets
Ich hab mal gelesen das man den Pointer dann anders berechnen muss
Kannste mir das zeigen
10/09/2011 11:58 XxharCs#5
Quote:
Originally Posted by supercracker13 View Post
Sry das ich noch was fragen muss

Aber das Warnike wichtig


Wie mache ich das bei 5 Offsets
Ich hab mal gelesen das man den Pointer dann anders berechnen muss
Kannste mir das zeigen
Dann gibt es ein Offset der sogenannte Base Offset. Den sollte man bei jedem Pointer finden, des jeweiligen Spiels.
Du musst aber auch beachten das die Offsets nur für diese Sache jetzt bzw Handlung sind. Es gibt dann bei den Offsets auch das "EndOffset" das du dann benutzt um den wert zu geben.
In diesem Beispiel werd ich den Offset5 als den "EndOffset" nehmen.

Ganz oben wie gewöhnt definierst du normal die Offsets.
Dann rechnest immer 2 Offsets zum Pointer, also zB:
Code:
DWORD dwItemBase = *(DWORD*)(dwBasePointer + ItemBaseOffset);
DWORD dwOffset2 = *(DWORD*)(dwItemBase + Offset2);
DWORD dwOffset3 = *(DWORD*)(dwOffset2 + Offset3);
DWORD dwOffset4 = *(DWORD*)(dwOffset3 + Offset4);

*(DWORD*)(dwOffset4 + Offset5) = 5; // 5 ist jetzt nur beispiel^^
Ich persöhnlich habe bis jetzt nur mit Pointern die 4 Offsets haben gearbeitet.^^
10/09/2011 17:21 supercracker13#6
Sry das ich so nerve aber da eh nicht so viele hier frage hoffe ich das das egal ist

also

ich habe das jetzt mal versuche
aber ...

bei mir spuckt das 2 Fehlermeldungen aus
darum wollte ich fragen ob du mir das mal zeigen könntest

Ich habe mal die als bild die adresse von dem pointer angehängt
könntest du mir daraus mal die datei machen
oder wenigstens zeigen wie das damit geht

weil ich habe über 3 stunden versucht
und es hat nicht funktioniert


:handsdown::handsdown:wäre echt nett wenn du mir helfen könntest :handsdown::handsdown:


Skype : ichbinsuppi1
10/09/2011 19:45 Tyrar#7
denke das gehört an sich zu den basics, aber gute geschrieben und wie man sieht hilfts sicher einigen :D
hättest evtl. noch das ausnopen mit erklären können ;)


Code:
DWORD dwValue=1337;
DWORD dwOffset1=*(DWORD*)(0x0026DF57D4+0x63C);
DWORD dwOffset2=*(DWORD*)(dwOffset1+0x20);
DWORD dwOffset3=*(DWORD*)(dwOffset2+0x7FC);
DWORD dwOffset4=*(DWORD*)(dwOffset3+0x4A8);
DWORD dwOffset5=(dwOffset4+0x714);

*(DWORD*)dwOffset5=dwValue;
10/09/2011 20:06 XxharCs#8
Quote:
Originally Posted by HeavyHacker View Post
denke das gehört an sich zu den basics, aber gute geschrieben und wie man sieht hilfts sicher einigen :D
hättest evtl. noch das ausnopen mit erklären können ;)


Code:
DWORD dwValue=1337;
DWORD dwOffset1=*(DWORD*)(0x0026DF57D4+0x63C);
DWORD dwOffset2=*(DWORD*)(dwOffset1+0x20);
DWORD dwOffset3=*(DWORD*)(dwOffset2+0x7FC);
DWORD dwOffset4=*(DWORD*)(dwOffset3+0x4A8);
DWORD dwOffset5=(dwOffset4+0x714);

*(DWORD*)dwOffset5=dwValue;
Jo so gehts auch mit Wert zuweisen^^

Naja für den Anfang bzw für die Anfänger wird nicht wirklich ausnopen benötigt^^
10/09/2011 21:31 Tyrar#9
Quote:
Originally Posted by XxharCs View Post
Jo so gehts auch mit Wert zuweisen^^

Naja für den Anfang bzw für die Anfänger wird nicht wirklich ausnopen benötigt^^
wenns darum geht einen wert dauerhaft zu freezen wärs sinnvoller als ne loop laufen zu lassen ;)
wie schon sagst für anfänger is das ausreichend :)
10/09/2011 21:59 supercracker13#10
ist das wirklich c++

ein freund von mir meinte
das das ganz falsch
ist

bei mir kommen beim Erstellen F7
immer Fehler meldungen
warum ???

welche version haste 2010

kannste mal die dll mit meinen pointern machen

alle die ich gefragt hatte meinten das geht nicht
10/09/2011 22:04 XxharCs#11
Quote:
Originally Posted by supercracker13 View Post
ist das wirklich c++

ein freund von mir meinte
das das ganz falsch
ist

bei mir kommen beim Erstellen F7
immer Fehler meldungen
warum ???

welche version haste 2010

kannste mal die dll mit meinen pointern machen

alle die ich gefragt hatte meinten das geht nicht
Jop das C++.
Meine IDE ist Visual Studio 2010.
Geh mal auf eigenschaften deines .dll projekts und änder es auf "Multibyte Zeichensatz verwenden".
10/10/2011 01:51 Tyrar#12
Quote:
Originally Posted by XxharCs View Post
Jop das C++.
Meine IDE ist Visual Studio 2010.
Geh mal auf eigenschaften deines .dll projekts und änder es auf "Multibyte Zeichensatz verwenden".
so wie der code is sollte der eig. mit jedem compiler laufen.. vorausgesetzt man hat die header!
und mit dem zeichensatz wird das auch sicher nichts zutun haben, die einzigen funktionen die du verwendest sind GetModuleHandle, MessageBoxA... das 'A' = multibyte zeichensatz, und GetModuleHandle (was bei unicode GetModuleHandleW ist) bekommt 0... also liegts daran nich!

evtl. nen cli projekt erstellt?

€: ffu quote vom falschen post :|
10/11/2011 11:43 supercracker13#13
Es Geht immer noch nicht

Kannste mir bitte mal über Skype oder teamviewer helfen
Wäre echt nett


Macht es einen Unterschied ob c++ 2010 oder c++ 2008

????????
10/15/2011 12:35 MrSm!th#14
Quote:
*Wir inkludieren die "stdafx.h und iostream(=input output)
*iostream ist aber nicht nötig^^
Au contraire, im Gegensatz zu In- und Output ist stdafx.h nicht nötig.
Die meisten Trainer machen ohne Eingabemöglichkeiten aber keinen Sinn.
10/15/2011 14:43 Tyrar#15
Quote:
Originally Posted by MrSm!th View Post
Au contraire, im Gegensatz zu In- und Output ist stdafx.h nicht nötig.
Die meisten Trainer machen ohne Eingabemöglichkeiten aber keinen Sinn.
einspruch! wenn iostream in der stdafx.h includet wird?