C++ Wrapper DLL für System DLL

llxp

Grünschnabel
Hallo,

ich würde gerne wissen, wie es möglich ist, eine System-DLL von Windows mit einer selbst-geschriebenen DLL zu wrappen. Also die alte DLL umzubenennen und die eigene DLL mit dem Namen der System-DLL versehen.

Ich würde gerne einige Daten in der Wrapper-DLL aus der System-DLL abgreifen und dann den Function-Call an die System-DLL weiterleiten.
Ich habe gelesen, dass so etwas möglich ist, allerdings finde ich keine Beispiele, bzw. Tutorials o.ä. dazu.
Das was ich finde sind leider immer nur Wrapper-DLLs für C/C++ --> C#. Ich suche allerdings C/C++ --> C/C++.

Kennt sich vielleicht jemand damit aus oder hat Beispiele, wie sowas umzusetzen geht?
 
Hi

nein, wirklich unproblematisch geht das nicht.
Weil:
a) Windows hat mehrere Sachen, die auf jede Änderung an SystemDLLs reagieren und den Originalzustand wiederherstellen.
b) Auch wenn man alles davon umgeht (was nicht trivial ist): Spätestens das nächste Update macht dir alles wieder kaputt
c) Bist du dir wirklich sicher, das gesamte DLL-Interface richtig nachbauen zu können? Schon das ist nicht ganz einfach. Angefangen mit Zeug wie Callconvention, Name padding; dann eine Menge Spezialfälle bei Datenstrukturenalignments/paddings die nirgends dokumentiert sind, dann generell undokumentierte seltsame Byteblobs in manchen, die man nur findet wenn man sie schon kennt, usw.usw.usw.

Was willst du damit eigentlich erreichen? Vielleicht gibts ja einen besseren Weg.
 
Hi,

ich möchte in der Wrapper-DLL Daten aus der DLL für die Fenster-Darstellung die Grafikdaten von Fenstern abgreifen, bevor diese gerendert werden, um eventuell das Rendern sogar zu verhindern.
 
Hallo

ich möchte in der Wrapper-DLL Daten aus der DLL für die Fenster-Darstellung die Grafikdaten von Fenstern abgreifen, bevor diese gerendert werden, um eventuell das Rendern sogar zu verhindern.
Mir fällt da gerade DLL-Injection ein, womit du möglicherweise zumindest für bestimmte Programme etwas hinbiegen kannst.

Allerdings bewegst du dich (egal auf welchem Weg) im Bereich der Virenscannerpanik (und evtl. sogar auf illegalem Gebiet!).

Du kannst sicher versuchen, die WinAPI-Befehle abzufangen, indem du die DLL "ersetzt", allerdings gibt es da einige tausend Funktionen, die du schreiben müsstest.

Je nachdem sind einige Dateien noch digital signiert, was dann das Fälschen unmöglich macht.

Die grundsätzlichen Messages solltest du mit Hooks abfangen können, allerdings scheint das Read-Only zu sein.

Also: Auslesen geht, Verändern wird wohl eher schwierig.

Gruss
cwriter
 
Ich möchte als Hauptziel gerne die kompletten Bilddaten aller Fenster abzufangen, um diese z.B. an eine VR-Brille zu senden.
Ich hatte verschiedene Ansätze, das zu lösen:
1. Einen Treiber zu entwickeln, also an der untersten Schicht anzufangen. Allerdings kann ich da vermutlich nur den gesamten Bildschirm als Textur abgreifen und nicht jedes Fenster als solches.
2. Die System-DLL vom DesktopWindowManager zu wrappen/hooken und dort die Fensterdaten abzugreifen.
 
Hallo

Ich möchte als Hauptziel gerne die kompletten Bilddaten aller Fenster abzufangen, um diese z.B. an eine VR-Brille zu senden.
"Bilddaten" wird da schon schwierig. Windows zeichnet schlussendlich zwar auch nur Bilder, allerdings werden die vorher auf eine gewisse Auflösung (annehmbarerweise < VR-Auflösung) gerendert.

1. Einen Treiber zu entwickeln, also an der untersten Schicht anzufangen. Allerdings kann ich da vermutlich nur den gesamten Bildschirm als Textur abgreifen und nicht jedes Fenster als solches.
Du musst ja ohnehin einen Bildschirm haben (ob in einer Brille oder auf einem Ständer auf dem Schreibtisch ist da egal), d.h. du müsstest dann das Bild nicht "abfangen", sondern es dir vom Betriebssystem geben lassen. Allerdings: Treiberebene. Das gibt eine Menge zu tun.

Link zu Code für einfaches "Screenshotten": http://stackoverflow.com/questions/5069104/fastest-method-of-screen-capturing
(Hat sowohl Wege für DX als auch GDI)

Der Vollständigkeit halber (aus Link oben):
C++:
HDC hdc = GetDC(NULL); // get the desktop device context
HDC hDest = CreateCompatibleDC(hdc); // create a device context to use yourself

// get the height and width of the screen
int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);

// create a bitmap
HBITMAP hbDesktop = CreateCompatibleBitmap( hdc, width, height);

// use the previously created device context with the bitmap
SelectObject(hDest, hbDesktop);

// copy from the desktop device context to the bitmap device context
// call this once per 'frame'
BitBlt(hDest, 0,0, width, height, hdc, 0, 0, SRCCOPY);

// after the recording is done, release the desktop context you got..
ReleaseDC(NULL, hdc);

// ..and delete the context you created
DeleteDC(hDest);
Du kannst durch Modifikation der 1. Zeile auch den Device Context für ein einzelnes Fenster bekommen.

2. Die System-DLL vom DesktopWindowManager zu wrappen/hooken und dort die Fensterdaten abzugreifen.
Mittels der Hooks, die ich dir verlinkt habe, solltest du die meisten der Rendermessages lesen und damit das Bild auf deiner Brille reproduzieren können, falls du das komplette Rendering selbst machen wolltest.

Gruss
cwriter
 
Hallo, danke,

ja, Screenshots bzw. screencapturing hab ich schon mit GetDC() gemacht, allerdings war das screencapturing in meinem Fall nicht sehr performant und die Fenster werden leider auch dann "doppelt" gerendert.
Ich würde gerne eine Art Offscreen-Rendering der Fenster ermöglichen, um die Fenster dann direkt in der VR-Brille zu rendern ohne diese vorher auf dem Bildschirm darzustellen. Denn wenn ich ein Fenster doppelt rendere geht das sehr auf die Performance und es werden mehr resourcen benötigt. Ich möchte quasi die Fensterausgabe umleiten auf einen memorystream o.ä..
Ich habe mir gerade den Link mit den Hooks angesehen und das sieht dem schon recht ähnlich, was ich versuche zu erreichen.
Mittels WH_GETMESSAGE sollte es mir möglich sein, auf die message queue zuzugreifen und dort eventuell auch die Bilddaten abzugreifen. Meines Wissens nach werden sogar DirectX-Fenster darüber dargestellt, also müsste ich damit auch die Frames abgreifen können.
Ich hab gerade noch einmal den Ursprung her, wo ich die Idee mit der Wrapper-DLL her hatte: Youtube.
 
Denn wenn ich ein Fenster doppelt rendere geht das sehr auf die Performance und es werden mehr resourcen benötigt.
Das ist so, ja. Da deine Brille aber wohl ohnehin an einem Grafikchip hängt: Zählt das nicht auch als Monitor? (sorry, habe keine :p)
Wenn ja, kannst du ja einfach den Monitor ausschalten und einmal direkt rendern.
Und Win32-Applikationen sollten eigentlich nicht so teuer zu zeichnen sein, dass es einen grossen Unterschied macht. (Klar kostet es, aber wenn es keinen anderen Weg gibt...)

Etwas ähnliches für den ganzen Desktop gibt es hier: http://store.steampowered.com/app/382110/
Details kenne ich da natürlich auch nicht, aber ich nehme mal schwer an, dass der Desktop einfach als Textur kopiert wird. (I.e.: Screenshot -> Textur übernehmen. 1x rendern, 1x kopieren, 1x blitten).
Halt mit der Auflösungslimitierung.

Mittels WH_GETMESSAGE sollte es mir möglich sein, auf die message queue zuzugreifen und dort eventuell auch die Bilddaten abzugreifen. Meines Wissens nach werden sogar DirectX-Fenster darüber dargestellt, also müsste ich damit auch die Frames abgreifen können.
Message queue: Sicher. Bilddaten? Nicht ganz so sicher. Du müsstest das wohl wie gesagt selbst rendern.

Ich hab gerade noch einmal den Ursprung her, wo ich die Idee mit der Wrapper-DLL her hatte: Youtube.
Also er schreibt in einem Kommentar:
Well, the idea was to hook IDirect3DDevice9::CreateTexture() in milcore.dll in DWM.exe. Once that is done, make all created texture shared (by appending a texture handle before the real call). And finally, I printed this handle in the console residing inside DWM.exe (see AllocConsole()), and copy/paste that handle in the 3D program. See, when I say not reliable, I mean it :)
Das ist im Prinzip ein Hack. Das Video ist von 2007, es kann also niemand wissen, ob das überhaupt noch funktioniert.

Gruss
cwriter
 

Neue Beiträge

Zurück