Microsofts Detours Library 2.1 mit BCB?



  • Die DLL selbst mit dem C++Builder zu kompilieren dürfte nicht ohne weiteres machbar sein, da sie sehr MSVC-spezifisch ist. Aber die Importe sollten sich auch im BCB verwenden lassen.



  • Nun habe ich selbst einen Fall, in dem ich Detours einsetze, und ich stelle fest, daß ich meine Vermutung relativieren muß: Detours läßt sich wunderbar mit dem C++Builder übersetzen.

    Lege einfach ein Library-Projekt an, füge creatwth.cpp, detours.cpp, image.cpp, disasm.cpp und modules.cpp hinzu und erstelle es. Dabei erhältst du einige Warnungen, und zumindest zwei davon sollten dich zu einer kleinen Änderung veranlassen: nämlich stehen einige nicht suffizierte 64-Bit-Integer-Konstanten im Code, die eine Integer-Overflow-Warnung verursachen. Hänge bei den beiden Konstanten einfach "ULL" an, um sie als unsigned long long zu markieren.

    Analog kannst du auch die detoured.dll erstellen, indem du ein neues DLL-Projekt anlegst, detoured.cpp hinzufügst und in detoured.cpp und detoured.h die Funktion Detoured() um extern "C" und __declspec (dllexport) erweiterst.



  • So, musste in der detours.h das hier rausnehmen:

    Zeile 360 - 374

    #if (_MSC_VER < 1299)
    #include <imagehlp.h>
    typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
    typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
    typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
    typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
    
    static inline
    LONG InterlockedCompareExchange(LONG *ptr, LONG nval, LONG oval)
    {
        return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval);
    }
    #else
    #include <dbghelp.h>
    #endif
    

    dann noch die "dbghelp.h" wieder inkludiert, sonst hätte es in der modules.cpp eine Fehlermeldung gegeben bei einer Funktiondeklarierung. (Zeile 118)

    in Detours.cpp sowie disasm.cpp

    #define DETOURS_X86
    

    hinzugefügt.

    Warnungen hab ich die hier bekommen: (nehme mal an das sind die die du gemeint hast?):

    [C++ Warnung] creatwth.cpp(431): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] detours.cpp(417): W8098 Ungültige mehrstellige Zeichenkonstante
    [C++ Warnung] detours.cpp(451): W8056 Überlauf in mathematischem Integer-Ausdruck
    [C++ Warnung] detours.cpp(452): W8056 Überlauf in mathematischem Integer-Ausdruck
    [C++ Warnung] detours.cpp(1189): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] detours.cpp(1283): W8098 Ungültige mehrstellige Zeichenkonstante
    [C++ Warnung] detours.cpp(1290): W8098 Ungültige mehrstellige Zeichenkonstante
    [C++ Warnung] detours.cpp(1291): W8098 Ungültige mehrstellige Zeichenkonstante
    [C++ Warnung] detours.cpp(1292): W8098 Ungültige mehrstellige Zeichenkonstante
    [C++ Warnung] detours.cpp(1293): W8098 Ungültige mehrstellige Zeichenkonstante
    [C++ Warnung] detours.cpp(1354): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(776): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(954): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(970): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(1118): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(1276): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(1658): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] image.cpp(1889): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] modules.cpp(491): W8012 Vergleich von signed- und unsigned-Werten
    [C++ Warnung] modules.cpp(542): W8012 Vergleich von signed- und unsigned-Werten
    

    Ansonsten wurd die DLL erzeugt. Muss morgen dann testen ob sie auch funktioniert.

    Auf jedenfall ein dickes danke 🙂 👍



  • Maverick schrieb:

    in Detours.cpp sowie disasm.cpp

    #define DETOURS_X86
    

    hinzugefügt.

    Stimmt, das vergaß ich zu erwähnen. Aber die Fehlermeldung ist ja recht eindeutig.

    Maverick schrieb:

    Warnungen hab ich die hier bekommen: (nehme mal an das sind die die du gemeint hast?):

    Genau die. Zumindest die beiden Überlauf-Warnungen würde ich beheben wie oben vorgeschlagen.

    Maverick schrieb:

    Ansonsten wurd die DLL erzeugt. Muss morgen dann testen ob sie auch funktioniert.

    Wie ich bei näherer Betrachtung feststellte, ist die eigentliche Funktionalität gar nicht in der DLL - die lediglich als Marker dient -, sondern in der statischen Bibliothek. Kein Wunder, daß IMPLIB und COFF2OMF nicht helfen konnten.

    Bei mir funktioniert es nun jedenfalls ohne Probleme.



  • Die Integer-Überläufe motzt er ja hier an: (detours.cpp Zeile 451 + 452)

    PDETOUR_TRAMPOLINE pHi = (PDETOUR_TRAMPOLINE)
            ((pbTarget < (PBYTE)0xffffffff80000000)
             ? pbTarget + 0x7ff80000 : (PBYTE)0xfffffffffff80000);
    

    Aber welche Konstanten muss ich dann wie ändern? Du hast zwar geschrieben das ich ULL voranstellen muss aber so ganz hab ich das nicht geschnallt (also welche konstanten das betrifft).

    Die sind ja etwas weiter oben deklariert: (Zeile 417 - 422)

    const ULONG DETOUR_REGION_SIGNATURE = 'Rrtd';
    const ULONG DETOUR_REGION_SIZE = 0x10000;
    const ULONG DETOUR_TRAMPOLINES_PER_REGION = (DETOUR_REGION_SIZE
                                                 / sizeof(DETOUR_TRAMPOLINE)) - 1;
    static PDETOUR_REGION s_pRegions = NULL;            // List of all regions.
    static PDETOUR_REGION s_pRegion = NULL;             // Default region.
    

    Die DLL funktioniert. Habe allerdings nur das "tracetcp" Beispiel ausprobiert.

    €dit:

    Nachdem du dich ja schon etwas damit beschäftigt hast: Wie müsste ich das den machen damit ich die detoured.dll in die statische Lib einbinden kann? So braucht man ja 2 DLLs. Meine damit ich von 2 DLLs auf 1 reduzieren kann.

    Vor allem hab ich noch eines nicht begriffen:
    Im "samples" Verzeichnis ist ja ein DLL Injecter dabei ("withdll"), hier muss man allerdings den Pfad zur detoured.dll angeben. Habe allerdings meinen "eigenen" Injecter der mit einer anderen API Hook DLL tadellos funktioniert.

    "withdll" setzt allerdings voraus das man den Prozess damit startet damit die Hook DLL sowie der Marker geladen wird. In meinem Fall geht das allerdings nicht da mein Targetprocess von einem anderen Process gestartet wird, so muss ich mit meinem eigenen Injecter auf den Process warten damit ich die DLL injezieren kann.

    Den Code von "withdll" hab ich mir schon angesehen. Hier wird scheinbar (?) die detoured.dll irgendwie geladen bevor die Hook DLL injeziert wird. Leider hab ich da den Code noch nicht ganz verstanden damit ich verstehen kann, wie ich meinen eigenen Injecter erweitern muss. Alternativ könnte man die detoured.dll einfach ins Windows System Verzeichnis kopieren, sauber wäre es aber nur bedingt.



  • Maverick schrieb:

    Die Integer-Überläufe motzt er ja hier an: (detours.cpp Zeile 451 + 452)

    PDETOUR_TRAMPOLINE pHi = (PDETOUR_TRAMPOLINE)
            ((pbTarget < (PBYTE)0xffffffff80000000)
             ? pbTarget + 0x7ff80000 : (PBYTE)0xfffffffffff80000);
    

    Aber welche Konstanten muss ich dann wie ändern? Du hast zwar geschrieben das ich ULL voranstellen muss aber so ganz hab ich das nicht geschnallt (also welche konstanten das betrifft).

    Ich schrieb 'suffizieren', nicht 'präfizieren' 😉

    0xffffffff80000000ull
    

    Maverick schrieb:

    Nachdem du dich ja schon etwas damit beschäftigt hast: Wie müsste ich das den machen damit ich die detoured.dll in die statische Lib einbinden kann? So braucht man ja 2 DLLs. Meine damit ich von 2 DLLs auf 1 reduzieren kann.

    Wie kommst du an zwei DLLs? detoured.cpp wird zu einer DLL kompiliert, aber aus dem Rest solltest du doch eine statische Bibliothek gemacht haben!?

    Maverick schrieb:

    Hier wird scheinbar (?) die detoured.dll irgendwie geladen bevor die Hook DLL injeziert wird.

    Nicht ganz. withdll benutzt das Detours-API, uimdie Import-Tabelle des Prozesses so zu verändern, daß einerseits detoured.dll, also der Marker, andererseits die von dir angegebene DLL beim Start vom PE-Loader dazugelinkt werden.

    Wenn die Anwendung, in die du eingreifen willst, schon läuft, bleibt dir in der Tat nichts anderes übrig, als deine DLL auf einem der üblichen Wege zu injizieren.



  • audacia|off schrieb:

    0xffffffff80000000ull
    

    Huch, nun gehts 😃

    audacia|off schrieb:

    Wie kommst du an zwei DLLs? detoured.cpp wird zu einer DLL kompiliert, aber aus dem Rest solltest du doch eine statische Bibliothek gemacht haben!?

    Na ganz einfach: Meine DLL + detoured.dll

    audacia|off schrieb:

    Wenn die Anwendung, in die du eingreifen willst, schon läuft, bleibt dir in der Tat nichts anderes übrig, als deine DLL auf einem der üblichen Wege zu injizieren.

    Hmm, also wenn ich die detoured.dll in das Windoof System Verzeichnis kopier, und dann meine DLL in den Zielprozess injeziere funktioniert es. Scheinbar lädt meine DLL dann die DLL wegen den Detours Funktionen?

    Ich hab bei dem erstellen der detoured.dll wohl irgend einen Fehler gemacht bzw. etwas übersehen? Wenn ich das "tracetcp" mit dem BCB kompilieren will, krieg ich Fehler vom Linker:

    [Linker Fehler] Error: Ungelöste externe 'DetourRestoreAfterWith' referenziert von <pfad>\DEBUG_BUILD\TRACETCP.OBJ
    [Linker Fehler] Error: Ungelöste externe 'DetourTransactionBegin' referenziert von <pfad>\DEBUG_BUILD\TRACETCP.OBJ
    [Linker Fehler] Error: Ungelöste externe 'DetourUpdateThread' referenziert von <pfad>\TRACETCP\DEBUG_BUILD\TRACETCP.OBJ
    [Linker Fehler] Error: Ungelöste externe 'DetourAttach' referenziert von <pfad>\TRACETCP\DEBUG_BUILD\TRACETCP.OBJ
    [Linker Fehler] Error: Ungelöste externe 'DetourTransactionCommit' referenziert von <pfad>\TRACETCP\DEBUG_BUILD\TRACETCP.OBJ
    [Linker Fehler] Error: Ungelöste externe 'DetourDetach' referenziert von <pfad>\TRACETCP\DEBUG_BUILD\TRACETCP.OBJ
    

    Die LIB hab ich natürlich eingebunden, habe aber jetzt gesehen das man scheinbar 2 Libs importieren muss, da die die o.g. Exports in der detours.lib drin stehen, aber nicht in der detoured.lib. Ist wohl der Grund warum der Linker das nicht findet.

    Einstellungen diszgl. wegen "_" voran stellen habe ich in den Projektoptionen nicht gemacht.

    Also die detoured.dll hab ich erstellt wie von dir geschrieben, d.h. das Projekt enthält:
    - creatwth.cpp
    - detoured.cpp
    - detoured.h
    - detours.cpp
    - detours.h
    - disasm.cpp
    - image.cpp
    - modules.cpp



  • Maverick schrieb:

    Hmm, also wenn ich die detoured.dll in das Windoof System Verzeichnis kopier, und dann meine DLL in den Zielprozess injeziere funktioniert es. Scheinbar lädt meine DLL dann die DLL wegen den Detours Funktionen?

    Nein, die sollten eigentlich statisch in deine DLL hineingelinkt sein! detoured.dll dient nur als Marker. Das steht übrigens auch in der Dokumentation; lies die doch einfach mal.

    Maverick schrieb:

    Einstellungen diszgl. wegen "_" voran stellen habe ich in den Projektoptionen nicht gemacht.

    Sollte auch nicht nötig sein.

    Maverick schrieb:

    Also die detoured.dll hab ich erstellt wie von dir geschrieben, d.h. das Projekt enthält:
    - creatwth.cpp
    - detoured.cpp
    - detoured.h
    - detours.cpp
    - detours.h
    - disasm.cpp
    - image.cpp
    - modules.cpp

    So habe ich das aber nicht geschrieben. Lies mal genauer 😉

    audacia schrieb:

    Lege einfach ein Library-Projekt an, füge creatwth.cpp, detours.cpp, image.cpp, disasm.cpp und modules.cpp hinzu und erstelle es. [...]

    Analog kannst du auch die detoured.dll erstellen, indem du ein neues DLL-Projekt anlegst, detoured.cpp hinzufügst und in detoured.cpp und detoured.h die Funktion Detoured() um extern "C" und __declspec (dllexport) erweiterst.

    Das Library-Projekt kannst du vorzugsweise "detours.lib" nennen 😉

    Und falls es daran scheitern sollte: mit "Library-Projekt" bezog ich mich auf eine statische Bibliothek.



  • Konnte nu alles kompilieren, aber meine Test DLL (bzw. das mit bcb kompilierte Beispiel funzt noch). Da wird der "Nullexport" nicht exportiert.

    Zum anderen wird auch noch witzigerweise die Detours() Funktion exportiert was eigentlich nicht sein sollte 😞

    @audia

    Ich hatte dir vorgestern eine Mail geschrieben, die is wohl scheinbar nicht angekommen oder du hast sie nicht gelesen, ka was zutrifft. Muss hier allerdings noch anmerken das ich den Absendernamen im EMail Client falsch eingestellt hab 😞



  • Maverick schrieb:

    Ich hatte dir vorgestern eine Mail geschrieben, die is wohl scheinbar nicht angekommen oder du hast sie nicht gelesen, ka was zutrifft. Muss hier allerdings noch anmerken das ich den Absendernamen im EMail Client falsch eingestellt hab 😞

    Die ist angekommen, aber ich schaue zzt. nur an Wochenenden, und diesesmal eben erst sonntagabends, nach meinen Mails. Derzeit muß ich für eine etwas responsivere Kommunikation leider das Forum empfehlen 😞



  • Es klappt jetzt.

    Habe das total übersehen mit Statischer Library in der Objektgallerie *schäm*

    Witzig ist aber, dass Antivir die DLL als Malware erkennt 🤡

    €dit

    Naja, ein Problem hab ich jetzt noch.

    Wenn ich das tracetcp Beispiel jetzt kompiliere, fehlt der NullExport.

    Wenn ich dann im tracetcp.cpp das abändere auf

    extern "C" __declspec (dllexport) NullExport()
    

    krieg ich vom Linker:

    [Linker Fehler] Error: Das als public deklarierte Symbol für EXPDEF 'NullExport' wurde nicht in Modul <pfad>\tracetcp\tracetcp.cpp gefunden
    

    Habs direkt bei der Funktion gemacht, aber auch wenn ich es am Anfang deklariere krieg ich die Meldung immer noch.



  • So, muss den Thread nochmal hochholen.

    Also die Lib, die DLL sowie das Tracetcp Beispiel kann ich kompilieren.

    Wenn ich jetzt aber mit Withdll die DLL z.B. in Fireforx lade passiert nichts. Die Beispiel DLL ist mehr oder weniger "Standard", d.h. ich habe daran keine änderungen vorgenommen (Beep() mal aussen vorgelassen).

    Wenn ich die DLL nehme dich ich mit Vc++ 2008 kompiliert habe funktioniert es.
    Es funktioniert auch wenn ich "meine" Detoured.dll" mit der von VC++ austausche. (meine, wenn ich meine mit BCB übersetzte detoured.dll mit der im VC++ Bin Verzeichnis austausche, d.h. ich überschreibe die VC DLL mit meiner BCB DLL).

    Firefox wird via "withdll" geladen. Setdll hab ich noch nicht ausprobiert, gehe aber davon aus das es damit auch nicht funktionieren wird!

    Es sieht so aus als wäre doch noch irgendwo der Hund begraben, fraglich ist wo:

    Die Projekt Files sehen so aus (Inhaltsmässig):
    Detoured.dll:
    - _detoured.cpp
    - _detoured.h (beide umbenannt weil ich das DLL Projekt genauso genannt habe)

    Detours.lib
    - _detoured.h
    - _detours.cpp
    - creatwth.cpp
    - disasm.cpp
    - image.cpp
    - modules.cpp

    tracetcp.dll
    - _detoured.cpp
    - _detoured.h
    - _detours.cpp
    - detours.h
    - syelog.cpp
    - syelog.h
    - detours.lib
    - detoured.lib

    Änderungen an den Dateien hab ich nicht vorgenommen, abgesehen von dem NullExport in der tracetcp.cpp sowie den Export in der (_)detoured.h für den Export von Detoured().

    Den Nullexport für tracetcp habe ich so gemacht:
    extern "C" __declspec (dllexport) __stdcall void NullExport();

    Die DLL ansich exportiert nur den NullExport sowie den CPP Debug Hook.

    Irgendwas hab ich noch falsch gemacht, aber was 😕



  • Maverick schrieb:

    Irgendwas hab ich noch falsch gemacht, aber was 😕

    Eine Vermutung hätte ich da; bei meinen Versuchen trat ein Problem auf, dessen nicht eben naheliegende Lösung mit einem Unterschied zwischen BCC und MSVC in der Behandlung der statischen Referenzierung von DLL-Importen zusammenhing.

    Im Beispiel "simple" in simple.cpp wird das Detouring folgendermaßen durchgeführt:

    VOID (WINAPI * TrueSleep) (DWORD dwMilliseconds) = Sleep;
    
    VOID WINAPI TimedSleep(DWORD dwMilliseconds)
    {
        DWORD dwBeg = GetTickCount();
        TrueSleep(dwMilliseconds);
        DWORD dwEnd = GetTickCount();
    
        InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
    {
        LONG error;
        (void)hinst;
        (void)reserved;
    
        if (dwReason == DLL_PROCESS_ATTACH) {
            printf("simple.dll: Starting.\n");
            fflush(stdout);
    
            DetourRestoreAfterWith();
    
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
            error = DetourTransactionCommit();
    ...
    

    Zunächst wird also die globale Variable TrueSleep mit dem WinAPI-Import Sleep initialisiert (Z. 1), dann später an DetourAttach() übergeben (Z. 26). Was trivial klingt, ist die Ursache unseres Problems; um das nachvollziehen zu können, ist es nötig zu wissen, wie DLL-Importe funktionieren.

    Der Linker erstellt für alle Funktionen, die als __declspec (dllimport) markiert sind, eine Tabelle von Minimal-Stubs, die lediglich aus einer JMP-Anweisung mit einer Dummy-Adresse bestehen - eine Sprungtabelle. Der PE-Loader trägt, wenn das Modul geladen wird, in dieser Tabelle die tatsächlichen Adressen der Funktionen ein. Durch diesen Umweg wird dem Loader einiges an Arbeit erspart (unabhängig davon, wie oft eine importierte Funktion referenziert wurde, muß der Loader ihre tatsächliche Adresse nur einmal in der Sprungtabelle eintragen).
    Dies läßt sich sehr einfach im Disassembler (Strg+Alt+C) nachvollziehen. Wenn du probehalber den folgenden Code in simple.cpp einfügst:

    Sleep (0);
    

    , dann resultiert er in diesem Assembler-Code:

    simple.cpp.40: Sleep (0);
    003712A0 6A00             push $00
    003712A2 E8B51B0000       call $00372e5c
    

    Folgst du der CALL-Anweisung mit F7 (Einzelne Anweisung), so landest du in der Sprungtabelle:

    ...
    00372E50 FF2510713700     jmp dword ptr [$00377110]
    00372E56 FF2514713700     jmp dword ptr [$00377114]
    00372E5C FF2518713700     jmp dword ptr [$00377118] ; <-- hier
    00372E62 FF251C713700     jmp dword ptr [$0037711c]
    00372E68 FF2520713700     jmp dword ptr [$00377120]
    ...
    

    Folgst du auch der JMP-Anweisung mit F7, bist du am Ziel:

    kernel32.Sleep:
    7C802442 8BFF             mov edi,edi
    7C802444 55               push ebp
    7C802445 8BEC             mov ebp,esp
    7C802447 6A00             push $00
    7C802449 FF7508           push dword ptr [ebp+$08]
    7C80244C E84BFFFFFF       call $7c80239c
    7C802451 5D               pop ebp
    7C802452 C20400           ret $0004
    7C802455 90               nop 
    7C802456 90               nop 
    7C802457 90               nop 
    7C802458 FFFF             db $ff $ff 
    7C80245A FFFF             db $ff $ff 
    7C80245C 0000             add [eax],al
    7C80245E 0000             add [eax],al
    7C802460 322480           xor ah,[eax+eax*4]
    7C802463 7C90             jl $7c8023f5
    7C802465 90               nop
    

    Der BCC behandelt statische Referenzierungen importierter Funktionen so wie einen gewöhnlichen Funktionsaufruf. Deshalb bewirkt diese Anweisung

    VOID (WINAPI * TrueSleep) (DWORD dwMilliseconds) = Sleep;
    

    , daß in TrueSleep die Adresse der Stub-Funktion in der Sprungtabelle eingetragen wird. Hier - allerdings ist das nur eine auf der Tatsache, daß die mitgelieferten Beispiele dort funktionieren, basierende, nicht verifizierte Vermutung - verhält sich MSVC anders: nämlich wird dort entweder vom PE-Loader oder vom Startup-Code der Anwendung in TrueSleep die tatsächliche Adresse der importierten Funktion eingetragen.

    Dies hat nun aber zur Folge, daß du, wenn du DetoursAttach() mit TrueSleep aufrufst, die Adresse des Sprungtabellen-Stubs übergibst. Demnach sieht die Sprungtabelle nach dem Aufruf der Detours-Funktionen so aus:

    ...
    00372E50 FF2510713700     jmp dword ptr [$00377110]
    00372E56 FF2514713700     jmp dword ptr [$00377114]
    00372E5C E9E3E3FFFF       jmp TimedSleep(unsigned long)
    00372E61 CC               int 3
    00372E62 FF251C713700     jmp dword ptr [$0037711c]
    00372E68 FF2520713700     jmp dword ptr [$00377120]
    ...
    

    Detours hat wunschgemäß die Funktion, auf die der übergebene Funktionszeiger verwies, umgelegt - den Stub in der Sprungtabelle. Jeder weitere Aufruf von Sleep() aus dem Modul, in dem die Detours-Funktionen aufgerufen wurden, erfolgt über diese Sprungtabelle und endet daher auch wie erwartet in TimedSleep(). Jedoch hat jedes Modul natürlich seine eigene Sprungtabelle, und die Sprungtabelle von sleep5.exe bleibt von obiger Aktion natürlich völlig unberührt und verweist nach wie vor auf die tatsächliche WinAPI-Funktion Sleep in kernel32.dll.

    Das Problem kannst du lösen, indem du die TrueSleep zur Laufzeit zuweist:

    typedef VOID (WINAPI * Sleep_t) (DWORD dwMilliseconds);
    Sleep_t TrueSleep;
    
    VOID WINAPI TimedSleep(DWORD dwMilliseconds)
    {
        ...
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
    {
        LONG error;
        (void)hinst;
        (void)reserved;
    
        if (dwReason == DLL_PROCESS_ATTACH) {
            printf("simple.dll: Starting.\n");
            fflush(stdout);
    
            DetourRestoreAfterWith();
    
            TrueSleep = reinterpret_cast <Sleep_t> (GetProcAddress (GetModuleHandle (TEXT ("kernel32.dll")),
                "Sleep")); // <--
    
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
            error = DetourTransactionCommit();
    

    Danach verweist TrueSleep auf die tatsächliche Adresse der Funktion, und entsprechend verändert DetourAttach() auch die WinAPI-Funktion selbst (natürlich nur für den aktuellen Prozeß):

    kernel32.Sleep:
    7C802442 E9FDEDB683       jmp TimedSleep(unsigned long)
    7C802447 6A00             push $00
    7C802449 FF7508           push dword ptr [ebp+$08]
    7C80244C E84BFFFFFF       call $7c80239c
    7C802451 5D               pop ebp
    7C802452 C20400           ret $0004
    7C802455 90               nop
    ...
    


  • Danke für die ausführliche Erklärung. Werde das heute abend dann mal versuchen 🙂



  • vorab, hut ab, klasse thread und klasse inhalt.
    nur ich komm nicht weiter.

    hab beide statische libs detoured (16kb), detours (269kb) erstellt.
    danach ein projekt angefangen, worin ich ws32.send detouren will.

    habs nach deinem verfahren gemacht @audacia.

    True_Send = reinterpret_cast <PSEND> (GetProcAddress(GetModuleHandle("Ws2_32.dll"),"send"));
    

    in True_Send steht die addy von w32.send aber die detour libs wollen partout
    kein jmp erstellen.

    woran kann es jetzt liegen Oo?
    hab ich die libs falsch kompeliert?
    schafft vielleicht einer von euch ws32.send zu detouren?

    wäre cool, wenner mir da irgendwie weiterhelfen könntet.

    Greetz 🙂



  • retn schrieb:

    True_Send = reinterpret_cast <PSEND> (GetProcAddress(GetModuleHandle("Ws2_32.dll"),"send"));
    

    in True_Send steht die addy von w32.send aber die detour libs wollen partout
    kein jmp erstellen.

    Zunächst setzt die Verwendung von GetModuleHandle() natürlich voraus, daß das fragliche Modul bereits mit LoadLibrary() oder als statischer Import vom PE-Loader in den Prozeß geladen wurde. Weiterhin geben DetourAttach(), DetourAttachEx() und DetourTransactionCommit() einen Fehlercode zurück, der bei der Diagnose evtl. hilfreich ist. Und den Typen PSEND brauchst du auch nicht selbst zu deklarieren.

    Folgendes funktioniert einwandfrei bei mir:

    #define INCL_WINSOCK_API_TYPEDEFS 1
    #include <winsock2.h>
    #include <detours.h>
    
    WINSOCK_API_LINKAGE int WSAAPI replacement_send (SOCKET s, const char FAR * buf,
        int len, int flags)
    {
    
    }
    
    LPFN_SEND true_send;
    
    ...
    
        LoadLibrary (TEXT ("ws2_32.dll"));
    
        true_send = reinterpret_cast <LPFN_SEND> (GetProcAddress (
            GetModuleHandle (TEXT ("ws2_32.dll")), "send"));
    
        DetourTransactionBegin ();
        DetourAttach (&(PVOID&) true_send, replacement_send);
        DetourTransactionCommit ();
    


  • In True_Send stand ja die richtige Addy, von daher muss es geladen sein, habs ja nachgeguckt.
    Stimmt, an den Error code hab ich net gedacht und da ich den nun kenne, deprimiert es mich noch mehr xP.
    Fehlercode: (8) ERROR_NOT_ENOUGH_MEMORY kam bei rum. Und wenn ich mir die detours.cpp anschaue, gibts 3 möglichkeiten, die relevant wären.
    Irgendeine Idee? 😞
    Soviel Aufwand fürn kleinen Detour. ^^



  • retn schrieb:

    Irgendeine Idee? 😞

    Eine Debug-Version von detours.lib erstellen und mal durchsteppen? 🙂



  • geht net klar 😃
    hab mich auf die detour lib gefreut wien fuchs... und nu 😣
    nunja mal sehen, dtrotzdem thanks 😃



  • re 🙂

    also ich hab mal wieder ka. 😃

    in vc08 hab ich die detours ohne probs hinbekommen. jetzt zu borland.
    bin noch der überzeugung, dass ich die libs, dlls net richtig erzeuge, bzw. falsch oder garnet einbinde.

    also ich erstelle eine statische lib mit folgenden dateien:
    creatwth.cpp
    detours.cpp
    image.cpp
    disasm.cpp
    modules.cpp

    danach erstelle ich eine dll mit:
    detoured.cpp
    detoured.h

    mit extern "C" __declspec( dllexport ) HMODULE WINAPI Detoured();
    ein und kompeliere.

    k. klappt soweit.

    um detours zu verwenden, adde ich zu meinem dll projekt die statische lib.
    dann kommt folgendes
    [Linker Error] Error: Unresolved external 'Detoured' referenced from C:\DETOUR_BCB\DETOURS.LIB|detours

    so, wie verbinde ich jetzt die detoured.dll mit meiner dll und der statischen lib "detours"? 🙂

    hoffe, ihr guckt noch in den thread.

    greetz


Anmelden zum Antworten