Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding > Coding Tutorials
You last visited: Today at 11:53

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[C++] Eigene Detours Teil1

Discussion on [C++] Eigene Detours Teil1 within the Coding Tutorials forum part of the General Coding category.

Reply
 
Old   #1
 
xNopex's Avatar
 
elite*gold: 0
Join Date: May 2009
Posts: 827
Received Thanks: 471
[C++] Eigene Detours Teil1

Ein dickes Hallo an alle ,

Ich möchte euch mit diesem Tutorial den Umgang mit Detours zeigen. Zu allererst klären wir die spannende Frage, was ein Detour ist:

Ein Detour führt eine bestimmte Funktion von dir aus, sobald eine andere Funktion, die von dir bestimmt wird, aufgerufen wird. So ruft man bei Trainer mit einem D3D-Menü immer dann die eigene Methode zum Zeichnen des Menüs auf, wenn die Funktion EndScene() aus der D3D.dll aufgerufen wird. Also brauchst du für ein Ingame-Menü ein Detour

Okay damit sollte hoffentlich klar sein, was ein Detour ist, wenn nicht, fragt einfach nochmal nach. So jetzt kommen wir zu der Theorie, wie der Detour funktionieren soll. Erstmal geh ich grob auf nötiges Backgroundwissen ein, damit du verstehst, warum wir was machen. Jede Funktion nimmt im Speicher eines Prozesses eine bestimmte Adresse und Größe ein. Zum Beispiel kann eine Funktion an der Adresse 0x0040CCE1 beginnen und an der Adresse 0x0040CE00 enden. Weiterhin solltest du wissen, dass jede Adresse ein Byte speichert. Ein Byte nimmt die Werte von 0x00 bis 0xFF ein. Die Bytes werden auch OP-Codes genannt. Jetzt haben einige OP-Codes ein spezielle Bedeutung. Zum Beispiel bedeutet 0x90 NOP, d.h. die Adresse ist ohne Funktion. Das Byte 0xE8 ist ein CALL. Ein CALL ruft eine andere Funktion auf. Das Byte 0xE9 ist ein JMP (Jump). Ein Jump springt an eine gewisse Adresse im Adressenraum. Natürlich habe ich nicht zufällig diese drei OP-Codes näher erläutert Diese sind besonders für unseren Detour später interessant, also solltest du dir deren Bedeutung gut merken. So nachdem du dir jetzt im schnell-Exkurs wichtiges Backgroundwissen angeeignet hast, können wir zur Theorie eines Detours übergehen. Zuallererst brauchen wir die Start-Adresse der Funktion, die wir mit unserem Detour versehen wollen. Diese bekommen wir mithilfe eines Debuggers, zum Beispiel OllyDbg. Nun werden wir die Funktion so verändern, dass sie unsere Funktion aufruft und dann erst ihren Ablauf abarbeitet. Und zwar ersetzen wir das erste Byte der Funktion durch 0xE8. Wie oben bereits erwähnt steht 0xE8 für den CALL Befehl. Nach dem CALL-Befehl folgen vier Bytes, die die Adresse der Funktion angeben, die durch CALL aufgerufen werden soll. Das klingt nicht nur einfach, das ist auch einfach Aber leider etwas zu einfach, denn es gibt ein Problem: Wenn wir die ersten fünf Bytes der Funktion überschreiben, dann geht der alte Code verloren. Wenn das jetzt wichtiger Code war, dann stürzt das Programm ab. Darum müssen wir da Vorkehrungen treffen. Und zwar speichern wir zuvor die OP-Codes, die überschrieben werden. Dann fordern wir neuen Speicher an und schreiben die überschriebenen Bytes dorthin. Danach springen ( JMP ;] ) wir aus der alten Funktion zu den angeforderten Speicherblock, wo der ursprüngliche (wichtige) Code ausgeführt wird und anschließend zurück zur alten Funktion. Ich hoffe du kommst noch mit

Zusammenfassend:

1. Adresse der Ur-Funktion, die umgeleitet werden soll herausfinden
2. Neuen Speicher anfordern
3. Alte OP-Codes im neuen Speicher sichern
4. Bytes der Ur-Funktion mit CALL auf neue Funktion überschreiben
5. Bytes der Ur-Funktion mit JMP auf Sicherung überschreiben
6. Ende des Speicherblocks mit JMP auf Ur-Funktion überschreiben


So dann fangen wir mal an die nötige Funktion dafür zu programmieren:

Als erstes sollten wir überlegen, welche Parameter wir brauchen. Zum einen brauchen wir die Adresse der Ur-Funktion, dann die Adresse der neuen Funktion und zu guter letzt die Anzahl an Bytes, die gesichert werden sollen:

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    return true;
}
Was war schritt 1 nochmal? *Oben nachgucken* Okay, für das Programmieren brauchen wir vorerst die Adresse der Ur-Funktion nicht (wird später als Parameter übergeben), also fangen wir mit Schritt 2 an, das Anfordern von neuem Speicher. Dafür gibt es die schöne Funktion malloc(). Sie erwartet als Parameter die Größe des angeforderten Speicherblocks in Bytes und liefert als return-Wert einen void-Zeiger auf den Adressraum. An dieser Stelle sollten wir uns überlegen: Wie groß muss der Speicherblock sein? Dazu sollten wir uns überlegen, was in den Speicherblock "kommt". Zum einen die gesicherten OP-Codes aus der Ur-Funktion, also muss der Speicherblock schonmal mindestens die Anzahl Bytes fassen können, die wir als Parameter len an die DetourFunc() übergeben haben. Zum anderen müssen wir von dem Speicherblock wieder zurück zur Ur-Funktion springen können. Dazu muss der Speicherblock noch einen zusätzlichen Byte für den Spring-Befehl aufnehmen können (0xE9) und nochmals vier weitere für die Zieladresse. Macht insgesamt fünf Bytes. Die Gesamtgröße ist also 5+len Bytes:

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    BYTE* newMem4base = NULL;
    
    newMem4base = ( BYTE* )malloc( 5+len );
    if( newMem4Base == NULL )
        return false;

    for( DWORD i = 0; i < ( len+5 ); i++ )
        newMem4base[i] = 0x90;

    return true;
}
newMem4base enthält also den Zeiger auf den neuen Speicherblock. Wenn die Funktion fehlschlägt, der Zeiger also NULL ist, schlägt die Funktion fehl und gibt false zurück. Danach belegen wir jeder Speicheradresse mit einem NOP ( entspricht nichts machen).
Der nächste Schritt wäre das Speichern der alten Bytes im neuen Speicherblock. Dazu müssen wir uns erstmal die nötigen Rechte verschaffen, um auf den Speicher zuzugreifen. Das geschieht mittels VirtualProtect(). MSDN liefert nähere Informationen zu der Funktion. Danach kopieren wir mithilfe von memcpy() die Bytes. memcpy() erwartet als ersten Parameter die Ziel-Adresse, als zweiten die Quelle und als dritten die Anzahl Bytes, die kopiert werden sollen:

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    BYTE* newMem4base = NULL;
    DWORD dwOld;
    
    newMem4base = ( BYTE* )malloc( 5+len );
    if( newMem4Base == NULL )
        return false;

    for( DWORD i = 0; i < ( len+5 ); i++ )
        newMem4base[i] = 0x90;

    VirtualProtect( oldFunc, len, PAGE_READWRITE, &dwOld );
    memcpy( newMem4base, oldFunc, len );

    return true;
}
Langsam kommen wir zum Ende Nachdem wir also die Bytes gesichert haben, müssen wir den CALL auf unsere neue Funktion einrichten. Dazu überschrieben wir das erste Byte der Ur-Funktion mit dem OP-Code für CALL (0xE8):

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    BYTE* newMem4base = NULL;
    DWORD dwOld;
    
    newMem4base = ( BYTE* )malloc( 5+len );
    if( newMem4Base == NULL )
        return false;

    for( DWORD i = 0; i < ( len+5 ); i++ )
        newMem4base[i] = 0x90;

    VirtualProtect( oldFunc, len, PAGE_READWRITE, &dwOld );
    memcpy( newMem4base, oldFunc, len );
    oldFunc[0] = 0xE8;

    return true;
}
So unmittelbar nach dem CALL-Byte folgen vier Bytes, die die Adresse der Funktion angeben, die aufgerufen werden soll. Diese Adresse muss relativ zu der aktuellen Adresse sein. Wir haben als Parameter jedoch die absolute Adresse unserer Funktion angegeben, also müssen wir erst an die relative Adresse kommen. Dazu gibt es zum Glück eine gültige Regel:

relativeAdresse = absoluteAdresse - aktuelleAdresse -5;

Die absoluteAdresse ist in unserem Fall die Adresse der neuen Funktion, die aktuelleAdresse ist die Adresse der Ur-Funktion. Damit ergibt sich folgendes:

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    BYTE* newMem4base = NULL;
    DWORD dwOld;
    
    newMem4base = ( BYTE* )malloc( 5+len );
    if( newMem4Base == NULL )
        return false;

    for( DWORD i = 0; i < ( len+5 ); i++ )
        newMem4base[i] = 0x90;

    VirtualProtect( oldFunc, len, PAGE_READWRITE, &dwOld );
    memcpy( newMem4base, oldFunc, len );
    oldFunc[0] = 0xE8;
    *( DWORD* )( oldFunc+0x01 ) = DWORD( newFunc-oldFunc-5 );

    return true;
}
Damit wäre der CALL auf unsere Funktion fertig. Nachdem unsere Funktion aufgerufen wurde, müssen wir nun zu unserem neuen Speicherblock springen, an dem die alten OP-Codes gespeichert wurden, damit unsere Ur-Funktion auch noch ordnungsgemäß ausgeführt wird. Dazu setzen wir das Byte der nächsten Adresse auf 0xE9 und die nächsten 4Bytes wieder auf die Adresse, zu der gesprungen werden soll. Auch hier müssen wir erst aus den absoluten Adressen relative machen:

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    BYTE* newMem4base = NULL;
    DWORD dwOld;
    
    newMem4base = ( BYTE* )malloc( 5+len );
    if( newMem4Base == NULL )
        return false;

    for( DWORD i = 0; i < ( len+5 ); i++ )
        newMem4base[i] = 0x90;

    VirtualProtect( oldFunc, len, PAGE_READWRITE, &dwOld );
    memcpy( newMem4base, oldFunc, len );
    oldFunc[0] = 0xE8;
    *( DWORD* )( oldFunc+0x01 ) = DWORD( newFunc-oldFunc-5 );
    oldFunc[5] = 0xE9;
    *( DWORD* )( oldFunc+0x06 ) = DWORD( newMem4base-( oldFunc+0x5 )-5 );

    return true;
}
Kaum zu glauben, aber wir sind fast fertig! Nur noch zwei Schritte:

1. Wir müssen von unserem Speicherblock wieder zurück zu der Ur-Funktion springen

2. Wir müssen "Zu viel" gesicherte Bytes aus der Ur-Funktion mit NOP's versehen


Diese Punkte sollten keine Probleme mehr bereiten. Zum ersten Schritt: Zuerst erhöhen wir die Adresse des neuen Speicherblocks, um die Anzahl der gesicherten Bytes, damit die Adresse auf freien Speicher zeigt. Danach überschreiben wir wieder das erste Byte mit 0xE9 (JMP) und die nächsten vier Bytes mit der relativen Adresse, zu der gesprungen werden soll. Zum zweiten Schritt: Insgesamt nehmen der CALL und der JMP aus der Ur-Funktion 10Bytes ein. Sollte die Anzahl der zu sichernden Bytes, die als Parameter überegben wurde, größer als 10Bytes sein, müssen wir die restlichen Bytes aus der Ur-Funktion NOPen, damit diese nicht doppelt ausgeführt werden:

Code:
#include <windows.h>

bool DetourFunc( ( BYTE* )oldFunc, ( BYTE* )newFunc, DWORD len )
{
    BYTE* newMem4base = NULL;
    DWORD dwOld;
    
    newMem4base = ( BYTE* )malloc( 5+len );
    if( newMem4Base == NULL )
        return false;

    for( DWORD i = 0; i < ( len+5 ); i++ )
        newMem4base[i] = 0x90;

    VirtualProtect( oldFunc, len, PAGE_READWRITE, &dwOld );
    memcpy( newMem4base, oldFunc, len );
    oldFunc[0] = 0xE8;
    *( DWORD* )( oldFunc+0x01 ) = DWORD( newFunc-oldFunc-5 );
    oldFunc[5] = 0xE9;
    *( DWORD* )( oldFunc+0x06 ) = DWORD( newMem4base-( oldFunc+0x5 )-5 );
    newMem4base += len;
    newMem4base[0] = 0xE9;
    *( DWORD* )( newMem4base+0x01 ) = DWORD( ( oldFunc+10 )-newMem4base-5 );

    for( DWORD i = 10; i <len; i++ )
        oldFunc[i] = 0x90;

    return true;
}
So damit ist die DetourFunc() fertig programmiert. Bleibt eine spannende Frage: Wie wende ich die Funktion denn jetzt an? Diese spannende Frage werde ich im zweiten Teil des Tutorials mithilfe eines Beispiels erklären Also gedulded euch, bis es fertig ist


Wenn ihr Fragen habt, könnt ihr sie gerne stellen.

Und wenn ihr Fehler findet (sei es Formulierungsfehler oder Falschaussagen), bitte melden; ansonsten freue ich mich auch über Feedback.




Credits:
Nope
xNopex is offline  
Thanks
16 Users
Old 04/05/2010, 21:01   #2


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Auch hier ist zu beachten, dass man entweder den Code disassemblieren muss und dann die richtige Anzahl an Bytes sichern muss oder nur API Funktionen hooken darf.
Denn wenn dort eine Instruction ist, die mehr oder weniger als 5 Bytes belegt, dann machst du sie durch den Hook kaputt.
MrSm!th is offline  
Old 04/05/2010, 21:06   #3
 
Blackbirds's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 2,662
Received Thanks: 1,713
Das Tutorial kommt für mich genau richtig, da ich mich garde mit d3d9 und Hooking und den ganzen Kram beschäftige... thx
Blackbirds is offline  
Old 04/05/2010, 21:15   #4
 
elite*gold: 0
Join Date: May 2008
Posts: 489
Received Thanks: 210
Quote:
Originally Posted by xTheLast View Post
Das Tutorial kommt für mich genau richtig, da ich mich garde mit d3d9 und Hooking und den ganzen Kram beschäftige... thx
Lieber 'mal mit'm Dativ beschäftigen.
schlurmann is offline  
Old 04/05/2010, 21:23   #5
 
Blackbirds's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 2,662
Received Thanks: 1,713
Quote:
Originally Posted by schlurmann View Post
Lieber 'mal mit'm Dativ beschäftigen.
|
v

Quote:
Originally Posted by schlurmann View Post
Und ich würde mich über Megan Fox auf meinem ***** freuen...

viel sinnvolles kommt von dir irgendwie nicht, oder? leute wie dich, deren geistiger horizont niedriger ist als der von einem meter feldweg sollten eigentlich sofort gebannt werden

und btw: wer außer du achtet eig schon auf groß-und kleinschreibung?
Blackbirds is offline  
Old 04/05/2010, 22:23   #6
 
xNopex's Avatar
 
elite*gold: 0
Join Date: May 2009
Posts: 827
Received Thanks: 471
Quote:
Originally Posted by MrSm!th View Post
Auch hier ist zu beachten, dass man entweder den Code disassemblieren muss und dann die richtige Anzahl an Bytes sichern muss oder nur API Funktionen hooken darf.
Denn wenn dort eine Instruction ist, die mehr oder weniger als 5 Bytes belegt, dann machst du sie durch den Hook kaputt.
Das kommt alles in Teil2
xNopex is offline  
Old 04/06/2010, 16:22   #7


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Quote:
Originally Posted by xNopex View Post
Das kommt alles in Teil2
ja, da schreibst du deine eigene disassemble lib? o.O
Quote:
Originally Posted by xTheLast View Post
|
v




viel sinnvolles kommt von dir irgendwie nicht, oder? leute wie dich, deren geistiger horizont niedriger ist als der von einem meter feldweg sollten eigentlich sofort gebannt werden

und btw: wer außer du achtet eig schon auf groß-und kleinschreibung?
i lol'd 'bout this fail
MrSm!th is offline  
Old 05/27/2010, 20:50   #8
 
elite*gold: 0
Join Date: May 2008
Posts: 489
Received Thanks: 210
Quote:
Originally Posted by Blackbirds View Post

und btw: wer außer du achtet eig schon auf groß-und kleinschreibung?
Keine Ahnung. Bill Gates, Albert Einstein, Steven Hawking? Die Liste ist lang.

Der Dativ ist übrigens ein Fall und hat nichts mit Groß- und Kleinschreibung zu tun.
schlurmann is offline  
Thanks
4 Users
Old 05/27/2010, 21:04   #9
 
Bl@ze!'s Avatar
 
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
Wieso nicht Microsoft Detours lib benutzen? Funktioniert doch. <.<
Außerdem glaube ich, dass ich genau diese DetourFunc() schonmal in einem Forum gesehen habe, vor einigen Monaten aber, bis auf die Variabel mem4base, die hieß anders.
Bl@ze! is offline  
Old 05/27/2010, 21:10   #10


 
Ende!'s Avatar
 
elite*gold: 1
Join Date: Feb 2009
Posts: 6,378
Received Thanks: 7,996
Quote:
Originally Posted by Blackbirds View Post
|
und btw: wer außer du achtet eig schon auf groß-und kleinschreibung?
Ja, genau, wer außer du macht das schon? Ist ja total behindernd beim Lesen!

Damit das hier kein Spamm ist: An sich ein hübsches Tutorial, ich würde aber trotzdem lieber MS Detours benutzen, einfach weil du ein Problem hast, wenn zufällig genau in dem Moment der Code ausgeführt wird, den du überschreibst. Außerdem hab ich bei GameDeception so ziemlich genau diese Funktion schon mal gesehen. Für Anfänger ist dein Tutorial jedoch vielleich ganz hilfreich, weil sie so den Stoff so besser verstehen.
Ende! is offline  
Old 06/05/2010, 20:09   #11
 
elite*gold: 1300
Join Date: Oct 2009
Posts: 327
Received Thanks: 26
ist eig autoit leichter zu programmieren oder C++ ?
RedKelly is offline  
Old 07/13/2010, 18:29   #12
 
●ROBBY●'s Avatar
 
elite*gold: 1
Join Date: Jun 2009
Posts: 1,142
Received Thanks: 158
Quote:
Originally Posted by RedKelly View Post
ist eig autoit leichter zu programmieren oder C++ ?
AutoIt aber das gehört hier nicht rein.

B2T. Nettes Tutorial.
●ROBBY● is offline  
Old 03/27/2011, 22:18   #13
 
elite*gold: 0
Join Date: Nov 2009
Posts: 343
Received Thanks: 45
Schön und gut das ganze nur du solltest aufjeden Fall noch die Bytes die du überschreibst sicher und dann die Adresse des Arrays zurückgeben. In diesem Array muss aber noch darauf geachet werden, dass ein JMP zum alten Code vorhanden ist. Dann kannst du dir einen Functionpointer erstellen und dann läuft die Sache sicher.

MfG
yihaaa is offline  
Old 04/01/2011, 03:36   #14

 
Flyff_Service's Avatar
 
elite*gold: 0
Join Date: Oct 2008
Posts: 680
Received Thanks: 337
Die meisten Anti Hacks erkennen das leider schon, aber zum Glück gibts ja auch noch andere Methoden
Flyff_Service is offline  
Old 04/03/2011, 19:25   #15
 
elite*gold: 0
Join Date: Nov 2009
Posts: 343
Received Thanks: 45
Ja BP's zum Beispiel. Und zum Thema detected kann man nur sagen, dann hast du nicht richtig reversed :P

MfG
yihaaa is offline  
Reply


Similar Threads Similar Threads
[Tutorial] Microsoft Detours
07/24/2013 - Coding Tutorials - 74 Replies
Eine kleine .dll wird geschrieben, die mithilfe der Microsoft Detours Library die MessageBoxA Funktion detourt, und den Text ersetzt, sobald sie in einen Prozess injeziert wird. Ich hoffe ich konnte es einigermaßen verständlich erklären (mein Gedankenfluss ist manchmal etwas wirr). Es ist auf Deutsch. Detours Video Tutorial
[C++] Eigene Detours Teil2
06/21/2011 - Coding Tutorials - 25 Replies
Ein zweites dickes Hallo an Alle, Nachdem wir uns in Teil 1 des Tutorials darum gekümmert haben, die Detour Funktion zu programmieren, geht’s in Teil 2 darum, diese Funktion richtig anzuwenden. Dazu schreiben wir uns zuerst ein „Opfer“-Programm: #include <iostream> #include <windows.h> using namespace std;
SonyVegas Pro9-Intro-Tutorial-Teil1 +Teil2
08/14/2010 - Video Art - 8 Replies
Hey Com, Ich sah zwar das XxCrankxX ein gemacht hat indem es so ziemlich ums gleiche geht, jedoch habe ich ein Video-Tutorial gemacht...und möchte euch das nun zeigen=) Teil-1 meines Tutorials: SonyVegas Pro9-Intro-Tutorial-Teil1 YouTube - SonyVegas Pro9-Intro-Tutorial-Teil1
MS Detours 1.5
07/16/2010 - Kal Online - 10 Replies
hi, i'm having problem trying to compile my dll using ms detours 2.1 (not 1.5, sorry) detours.lib(detours.obj) : error LNK2001: unresolved external symbol "struct HINSTANCE__ * __stdcall Detoured(void)" (?Detoured@@YGPAUHINSTANCE__@@XZ) G:\KalOnline\d3dx9_29.dll : fatal error LNK1120: 1 unresolved externals could someone tell me how to solve it? could not google it.
Can EDX Detours be used for multibotting
06/19/2010 - SRO Private Server - 12 Replies
After editing source code can this be done? In EDX Detours thread he wrote this app can be used for another programs after tweaking the source. But i don't have any programming skills,so anyone who knows c++ please take a look at it http://www.elitepvpers.com/forum/sro-guides-templat es/308740-guide-using-windows-detours-redirect-sil kroad-proxy.html



All times are GMT +1. The time now is 11:53.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.