Gancio OpenGL / DirectX – Simile a FRAPS

È ansible rilevare quali applicazioni utilizzano OpenGL o DirectX in modo simile a ciò che fa FRAPS? (Forse usando qualche forma di hook)? Probabilmente non avrò bisogno di disegnare effettivamente alla finestra, ho solo bisogno di sapere quali processi stanno facendo una qualche forma di rendering 3D per il momento.

(Modifica 🙂 Se non si ha familiarità con esso, FRAPS è un programma che può essere utilizzato per disegnare un contatore “Frame-per-second” su un’applicazione 3D. FRAPS trova tutte le applicazioni 3D in esecuzione da solo senza che sia necessario specificare il nome del processo.

Esempio di contatore “Frame Per second” disegnato per un gioco esterno: inserisci la descrizione dell'immagine qui

Probabilmente il modo più semplice è verificare la presenza delle librerie di base OpenGL e DirectX, probabilmente anche una buona idea per aggiungere le DLL OGL del driver (come nvogl), questo può essere fatto tramite EnumProcesses & EnumProcessModulesEx , usando p / invocate, questo vi darà almeno un insieme iniziale di processi possibilmente usando OGL o DX.

Naturalmente alcune applicazioni caricano entrambe le API e ne usano solo una, o usano solo condizionatamente una delle API GFX (anche se quest’ultima si verifica solo con strumenti specializzati e simili), per questo, IMO, il modo migliore per controllare è eseguire una qualche forma di iniezione o attaccamento al processo come farebbe un debugger, quindi agganciare Present for DX o wglSwapBuffers per OGL.

Si potrebbe essere in procinto di cavarsela senza usare un hook enumerando gli handle GDI e cercando i contesti di rendering DXGI o OGL, quanto sia fattibile, non lo so.

Da quello che ho capito, FRAPS usa un approccio relativamente brutale per determinare dove posare il negozio. Il processo inizia con SetWindowsHookEx per richiedere che il sistema operativo carichi la DLL dell’aghook FRAPS in ogni processo in esecuzione che può [e processi futuri]. La magia nella DLL si riduce a eseguire una serie di test procedurali utilizzando GetModuleHandleA per osservare se il processo a cui è collegato ha caricato tutti i moduli OpenGL / DirectX. Se tutte le chiamate restituiscono NULL, l’hook tenta di rimuoverlo dal processo.

D’altra parte, se il processo li ha caricati, semplicemente aggancia la funzione di rendering appropriata da quella libreria rimuovendo la protezione e iniettando un hook JMP. wglSwapBuffers è in genere l’unico rilevante in OpenGL. Quando il processo chiama questa funzione, finisce per chiamare il modulo FRAPS e quindi FRAPS acquisisce il buffer posteriore nella sua coda per la codifica in AVI e ne rende la piccola indicazione. Quindi elabora la richiesta originale di wglSwapBuffers e restituisce l’esecuzione al programma.

Per quanto riguarda le query in C # … consulta EasyHook (http://easyhook.codeplex.com/) e vedi se non funziona per te. Personalmente non ho esperienza con questa API.

Dovresti dare un’occhiata a Come sovrapporre la grafica sui giochi Windows? e l’articolo collegato http://www.ring3circus.com/gameprogramming/case-study-fraps/ .

Il secondo link ha un codice di concetto che dovrebbe fare la parte del hook reale. Inoltre, fornisce maggiori dettagli su come e perché mi sembra di copiare e incollare in questa risposta.