Template Pointer



  • Hier ein Workaround:

    #include <Windows.h>
    
    template<typename T>
    void test(T) {}
    
    int main()
    {
        void (*fp)(int) = &test<int>;
        reinterpret_cast<DWORD>(fp);
    }
    

    oder mit auto...

    #include <Windows.h>
    
    template<typename T>
    void test(T) {}
    
    int main()
    {
        auto fp = &test<int>;
        reinterpret_cast<DWORD>(fp);
    }
    


  • template pointer schrieb:

    Wo ist für den Compiler der Unterschied? - verstehe ich ehrlich gesagt nicht.

    Kannste mal das hier ausführen?

    void test1(int a)
    {
    }
    
    template<typename T>
    void test2(T a)
    {
    }
    
    int main()
    {
    	std::cout << sizeof(DWORD) << ' ' << sizeof(long long) << '\n';
    	std::cout << sizeof(&test1) << ' ' << sizeof(&test2<int>) << '\n';
    }
    


  • Nathan schrieb:

    Kannste mal das hier ausführen?

    Nope, sizeof(&test2<int>) führt zu:

    error: address of overloaded function with no contextual type information
    


  • oenone schrieb:

    Nathan schrieb:

    Kannste mal das hier ausführen?

    Nope, sizeof(&test2<int>) führt zu:

    error: address of overloaded function with no contextual type information
    

    lol? Bei mir auch!?
    Wieso funktioniert auto und decltype, aber nicht sizeof?



  • decltype funktioniert auch nicht, dafür gibt's sogar schon einen Bugreport

    auto fp1 = &T::fn_Write; // memberfunction
    pFuncAddr2 = reinterpret_cast<DWORD>(fp2); // error
    

    Fehler 1 error C2440: 'reinterpret_cast': 'uint32_t (__thiscall Klasse::* )(TypeNr1 &,TypeNr2*)' kann nicht in 'DWORD' konvertiert werden


  • Mod

    Einen Memberzeiger darf man nicht in einen Integer konvertieren.



  • Das Problem ist mir bekannt, nur kenne ich die Lösung nicht. Das einzigste was mir einfallen würde wäre, über GetProcAddres, aber muss doch auch ohne gehen.



  • vielleicht sollte ich mal sagen was ich vor habe:
    Ich will eine Memberfunktion, deren Signatur mir bekannt ist, Detouren. Allerdings stoße ich ständig auf Bugs und Sachen die laut C++-Spec "verboten" sind.



  • so komme ich an die Adresse:

    DWORD dwFuncAddr = 0;
    auto fp = &T::func;
    __asm
    {
    	mov eax, fp;
    	mov dwFuncAddr, eax;
    }
    typedef int(__cdecl *tfp_func)(type1&, type2*);
    tfp_func pRealFp = reinterpret_cast<tfp_func>(dwFuncAddr);
    

    Wenn ich mir das im Debugger mit der Maus über pRealFp fahre, steht da:

    pRealFp = 0x0fabbb2f {Name.dll![thunk]:Klasse::`vcall'{8,{flat}}' }'}
    

    Was bedeutet dies, da wenn ich pRealFp aufrufe, komme ich nicht zur richtigen Stelle.



  • template pointer schrieb:

    Das Problem ist mir bekannt, nur kenne ich die Lösung nicht. Das einzigste was mir einfallen würde wäre, über GetProcAddres, aber muss doch auch ohne gehen.

    Also ihr wollt einen Class::*member umwandeln in einen int?
    Das geht meines Wissens nach nur mit einem Union.



  • template pointer schrieb:

    Das Problem ist mir bekannt, nur kenne ich die Lösung nicht. Das einzigste was mir einfallen würde wäre, über GetProcAddres, aber muss doch auch ohne gehen.

    Muss nicht passen.
    Der Memberfunktionszeiger könnte vielleicht sowas sein wie

    struct MFZ{
       bool virtelleFunktionOderNicht;
       void* adresse;//wird nur bei nichtvirtuellen genommen
       int indexInDerVtbl;//wird immer bei virtuellen genummen
       size_t offsetVomVprtZuThis;//Vptr stehe mal am Anfang der des Basisklassenobjekts
       //wird's bei mehrfacher Erblichkeit noch schlimmer?
    };
    

    Ich würde nicht erwarten, daß in einen int reindrücken und später wieder extrahieren zu können.



  • nurf schrieb:

    template pointer schrieb:

    Das Problem ist mir bekannt, nur kenne ich die Lösung nicht. Das einzigste was mir einfallen würde wäre, über GetProcAddres, aber muss doch auch ohne gehen.

    Also ihr wollt einen Class::*member umwandeln in einen int?
    Das geht meines Wissens nach nur mit einem Union.

    Ich will mit dem Pointer auf die Member-Function zuerst die Funktion Detouren (um etwas aus dem ersten Parameter der Funktion einen Wert zu extrahieren (könnte man auch mit Mid-Funktions-Hooking machen, wodurch das ganze kack casten, womit ich nur Probleme habe, wegfallen würde, nur wäre es dann noch komplizierter mit Adressen und Patch-Code)) und anschließend so aufrufen, dass ich das ich mit einem __cdecl-Call (indem ich den Pointer eines Objekts in ecx über inline-assembler ablege) von dem Member-Function-Pointer aufrufe.

    volkard schrieb:

    template pointer schrieb:

    Das Problem ist mir bekannt, nur kenne ich die Lösung nicht. Das einzigste was mir einfallen würde wäre, über GetProcAddres, aber muss doch auch ohne gehen.

    Muss nicht passen.
    Der Memberfunktionszeiger könnte vielleicht sowas sein wie

    struct MFZ{
       bool virtelleFunktionOderNicht;
       void* adresse;//wird nur bei nichtvirtuellen genommen
       int indexInDerVtbl;//wird immer bei virtuellen genummen
       size_t offsetVomVprtZuThis;//Vptr stehe mal am Anfang der des Basisklassenobjekts
       //wird's bei mehrfacher Erblichkeit noch schlimmer?
    };
    

    Ich würde nicht erwarten, daß in einen int reindrücken und später wieder extrahieren zu können.

    Irgendwo habe ich das schon mal gesehen, CodeProjekt oder so, wo es ein Tut gibt, wie man eine Memberfunktion über GetProcAddress aufruft.
    Ich habe schon versucht den Pointer nochmal zu dereferenzieren^^. Aber an die V-Table müsste ich ja kommen.
    Die Theorie kling so einfach, aber der Compiler machts einem einfach so verdammt schwer an die kack Adresse zu kommen, ich verstehe nicht ganz wieso, da ich ja ganz explizit sagen kann, welche Funktion ich will und die Funktion liegt ja auch irgendwo im Speicher...


Anmelden zum Antworten