Also, du injectest die Dll in den entsprechenden Prozess(dafür gibt es mehrere Wege, wie z.B. Message-Hooks per RegisterWindowsHookEx). Dann ermittelst du per LoadLibrary und GetProcAddress die Addresse der Funktion. Dann berechnest du den relativen Abstand zwischen deiner neuen Funktion und der Original-Funktion. Dann speicherst du die ersten 5 Bytes der alten Funktion und berechnest wieder den Abstand von dem Speicherort der 5 Bytes zu der Original-Funktion+5 und schreibst
E9 <relativer Abstand:Speicherort der 5 Bytes <-> Originalfunktion+5>
hinter die 5 gespeicherten Bytes (evtl. noch ein retn dahinter).
Nun schreibst du per WriteProcessMemory ein
E9 <relativer Abstand: Callback-Funtion <-> Original-Funktion>
an die Adresse der Original-Funktion.
Das hat zur Folge, dass jedesmal wenn die Original-Funktion aufgerufen wird, zu deiner Funktion gesprungen wird. Wenn du nun die alte Funktion aufrufen willst, musst du nur die gespeicherten 5-Bytes aufrufen, diese werden ausgeführt, und durch den Sprung-Befehl der vorher eingefügt wurde, springt der dann wieder in die Original-Funktion führt diese aus und kehrt zu deiner Callback-Funktion zurück und du kannst das Ergebnis nachbearbeiten und dann zurückgeben.
Das ganze ist ein wenig kompliziert, vorallem musst du bei den Aufruf-Konventionen aufpassen, dass die dir nicht den Stack kaputt machen.
Mehr Details findest du im Detours-Source und in den Intel-Docs(bzgl. der einzusetzenden Sprünge).
Wenn du willst, kann ich auch mal den Source von meinem Crackme, dass MessageBoxA hookt geben, allerdings, habe ich da die Trampoline-Funktion(die originalen 5-Bytes + Sprung in die alte Funktion) weggelassen, da ich noch MessageBoxExA zur Verfügung hatte und die alte Funktion daher nicht mehr gebraucht habe.