Detours - Echte Dynamik



  • Hallo,

    Ich würde gerne das klassische Szenario von Detours (API Hooking von Microsoft entwickelt - http://research.microsoft.com/en-us/projects/detours/) etwas erweitern, hänge da gerade allerdings etwas.
    Auf kurz gesagt, will ich den Hook Vorgang etwas dynamischer machen.

    Beispielsweise will ich die Funktion memcpy hooken, unter der Annahme, dass ich die Argumente und Argumentgrößen nicht weiß.
    Die "Stellvertreter"methode soll nichts anderes machen als die Orginalfunktion (memcpy) aufzurufen.

    Denke hier muss man etwas mit Assembler rumbasteln, bin da aber etwas überfordert.. hat da jemand Ahnung von?

    Noch ein "Beispiel", das natürlich nicht funktioniert, und nur symbolisch zeigen soll was erreicht werden soll:

    typedef void* (WINAPI *pFunc)(void*);
    pFunc TrampolineBackToOrginalMethod;
    void WINAPI MagicHookingFunction(void* someParameter)
    {
    //kann man hier evtl. den stack auslesen, und gleich wieder auf den stack schreiben? oder statt void* someParameter mit "..." arbeiten?
    
    register_function_call_to(orginal);
    
    //aufruf der orginal funktion
      TrampolineBackToOrginalMethod(someParamater);
    }
    
    int main()
    {
       DetourTransactionBegin();
       FuncToDetour = memcpy;
       DetourAttachEx(&(PVOID&)FuncToDetour, MyFunc,&reinterpret_cast<DETOUR_TRAMPOLINE*&>(TrampolineBackToOrginalMethod));
       FuncToDetour = memset;
       DetourAttachEx(&(PVOID&)FuncToDetour, MyFunc,&reinterpret_cast<DETOUR_TRAMPOLINE*&>(TrampolineBackToOrginalMethod));
    
       return 0;
    }
    

    Wie bereits geschrieben sollte in obrigen beispiel die Funktion MagicHookingFunction bei jedem Aufruf der Funktionen memcpy und memset dazwischenfunken, jedoch die Parameter ungefiltert direk weiter an die Orginalfunktionen geben..

    Kennt sich da jemand aus?
    Vielen Dank,
    Timo


  • Mod

    Nein kannst Du nicht, denn Du weißt nicht wieviel des Stacks eigentlich benötigt wird. Darüber kann Dir nichts Auskunft geben.

    BTW: memcpy und memset sind meistens keine Funktionen sondern fast immer intrinsic functions.



  • Es eigentlich ganz einfach:

    (x86) Ersetzte die ersten 5 Bytes der Methode durch einen Long-Jump auf Deine eigene Funktion.
    Dort kannst Du dann machen, was Du willst....

    Jetzt kommt aber die kniffelige Arbeit: Du musst die 5 Bytes die Du ersetzt hast "aufrufen" und dann zu der nächsten gültigen Stelle nach den 5 Bytes springen. Und das ist genau das, was detours macht. Und dazu brauchst Du einen Deassembler, der Dir die "gültige" Grenze der Befehle ermittelt.

    Viel Spass.



  • Vielen Dank erstmal für die Antworten.. Habe nach langer nachforschung noch eine "andere" Methode gefunden.. Ist folgender Ansatz "gefährlich" o.ä.?

    __declspec(naked) void* hooking_function()
    {
    	//do something
    	__asm {
    		jmp org_function;
    	}
    }
    

    Effektiv ist org_function die Trampolin Funktion.. durch __declspec(naked) sollte nichts am stack geändert werden.. Soweit richtig?

    Dies würde dann genau das erfüllen was ich benötige.. Folgender Ansatz funktioniert z.B (wobei org_func_normal als void* definiert ist, genau wie org_function)

    DetourTransactionBegin();
    	DetourUpdateThread(GetCurrentThread());
    	org_func_normal = memcpy_s;
    	DetourAttachEx(&(PVOID&)org_func_normal, hooking_function,&reinterpret_cast<DETOUR_TRAMPOLINE*&>(org_function),0,0);
    	if(DetourTransactionCommit() == NO_ERROR) {
    		int k=0;
    	}	
    
    	int j=0;
    	int f=2;
    	int kfk = memcpy_s(&j,sizeof(int),&f,sizeof(int));
    

Anmelden zum Antworten