BitBlt Hooken über Detours



  • Der Ausdruck da oben stellt einen Funktionszeiger-Typen dar. Einem Typen weist man nichts zu, einer Variable schon.

    Schau dir doch mal Detours 2.1 an, wenn du willst, zeige ich dir dann sauberen Beispielcode.



  • Ok habs mal auf Detours 2.1 geschrieben, jedoch auch jetzt, er injected (application crasht auch nicht) jedoch macht er nix! Aufm Screenshot werden die Features nicht "gecleant"

    #include <windows.h>
    #include <stdio.h>
    #include "detours.h"
    
    #pragma comment(lib,"detours.lib")
    #pragma comment(lib, "detoured.lib")
    
    int		xScreen, yScreen;
    BYTE	vKey;
    
    // Target Pointers (Pointer to the real functions)
    static BOOL (WINAPI *True_BitBlt)
    	(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop) = BitBlt;
    
    // Detour functions
    BOOL WINAPI my_BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop)
    {
    	BOOL bReturn;
    
    	xScreen = GetSystemMetrics(SM_CXSCREEN);
    	yScreen = GetSystemMetrics(SM_CYSCREEN);
    	if ((nWidth == xScreen) && (nHeight == yScreen)) //BitBlt wird auf den ganzen Monitor angewendet -> wahrshceinlich Screenshot
    	{
    		// Tastendruck simulieren
    
    		keybd_event(vKey, 0, 0, 0);
    		keybd_event(vKey, 0, KEYEVENTF_KEYUP, 0);
    		Sleep(100);
    
    		bReturn = True_BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
    
    		keybd_event(vKey, 0, 0, 0);
    		keybd_event(vKey, 0, KEYEVENTF_KEYUP, 0);
    
    		return bReturn;
    	}
    	return True_BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
    }
    
    /*******************************************************************
    					Dll_MAIN
     ******************************************************************/
    BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
    {
        if (dwReason == DLL_PROCESS_ATTACH) 
    	{	
    		// ntdll laden für NtQuerySystemInformation
    		HMODULE hLib = LoadLibrary(TEXT("Gdi32.dll"));
    		True_BitBlt = (my_BitBlt);
    		GetProcAddress(hLib,"BitBlt");
    
    		//PanicKey in virtuellen Key umwandeln (unschön, aber mir fällt nichts besseres ein)
    		vKey = VK_DELETE;
    
    		// Mithilfe von MSDetours die Funktionen hooken
    		DetourRestoreAfterWith();
    
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
    		DetourAttach(&(PVOID &)True_BitBlt, my_BitBlt);
    
        return TRUE;
    	}
    }
    

    Würde wirklich nett von dir sein, wenn du mir nen Beispiel Code zeigen würdest.



  • Ah, hast eh schon bisschen was selbst gemacht. Na dann:

    int (__stdcall* RealBitBlt)(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, unsigned long dwRop) = BitBlt;
    
    int (__stdcall* TramBitBlt)(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, unsigned long dwRop);
    
    // ...
    
    int __stdcall HookBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, unsigned long dwRop)
    {
        // ...
    
        return TramBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
    }
    
    // ...
    
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttachEx(reinterpret_cast<void**>(&RealBitBlt), HookBitBlt, reinterpret_cast<DETOUR_TRAMPOLINE**>(&TramBitBlt), 0, 0);
    DetourTransactionCommit();
    

    Und vergiss die drei Zeilen bei "// ntdll laden für NtQuerySystemInformation".



  • Vielen Dank Check0r, jedoch was ich wissen will, wieso hast du "__stdcall" genommen anstatt "WINAPI" ?



  • Ist genau das gleiche

    #define WINAPI      __stdcall
    


  • Wenn du die Datei windef.h öffnest, findest du folgende Anweisung:

    #define WINAPI  __stdcall
    


  • Ah alles klar. Ich testes Gerade.



  • ach mensch, geht immer noch nicht 😞 injecten tut ehr ohne zu crashen, jedoch macht er nix, (werden nicht sauber die bilder)



  • Dann prüfe erst mal, ob HookBitBlt überhaupt aufgerufen wird (mit Beep(100, 10) zB.).
    Wenn ja, liegt der Fehler im Code darin.
    Wenn nein, dann poste mal wieder den ganzen Code.



  • BertaC schrieb:

    Es soll ne Taste Simuliert gedrückt werden um Programm Features auszuschalten und nach dem Screenshot wieder anzumachen

    ...

    BertaC schrieb:

    ach mensch, geht immer noch nicht 😞 injecten tut ehr ohne zu crashen, jedoch macht er nix, (werden nicht sauber die bilder)

    Du willst die Darstellungsparameter während eines Aufrufs zu BitBlt ändern - das kann doch gar nicht gehen, schon gar nicht wenn dein Zielprogramm BitBlt aus dem WndProc aufruft.



  • Ja mir fählt nur die Methode ein..Wie soll ich dan die Taste Simulieren ?



  • Du musst zuerst den Tastendruck simulieren und dann den Hook aktivieren bzw. verarbeiten - Das Prog. muss ja die Gelegenheit haben, sich mit geänderten Parametern neu zu zeichnen.

    Um was für ein Prog. handelt es sich den? - Erklär mal genauer was du machen willst (Screenshot via Hotkey?)...



  • Bei uns in der Uni haben die ein Hauseigenes Überwachungstool, was von jeden Computer im LAN Bilder schiesst und am Professor aufm Bild zeigt. Ich habe eben Rausgefunden das es sich um ne BitBlt Funktion handelt. Da ich nicht direkt zugriff auf die DLL habe vom Überwachungstool wollte ich einfach den Clienten mit dem BitBlt Hook injecten und immer bei nem Screenshot, soll er zB. Je nach Funktionen die ich in ne ini schreib (das wird noch implementiert wenn alles funktioniert) die kurz ausblenden, und nach dem Screen wieder anmachen. Ich hab ein anderes Programm schon geschrieben, das wenn F6 gedrückt wird, der Internet Explorer versteckt wird oder halt die Programme die gewünscht sind (Ganz gut wenn der Prof. mal ein Rundgang macht.)

    Darum will ich, das der Hook immer wenn das Überwachungstool ein Foto schiesst, die F6 Taste Simuliert.



  • ich geh mal davon aus, das das Prog schlicht und einfach vom Desktop-HDC kopiert. Das Problem hierbei ist ja nun, dass er den gesamt Bildschirminhalt sieht, und somit auch die Taskleiste ... also nicht mit minimieren - ShowWindow(,SW_HIDE / SW_SHOWNORMAL)+UpdateWindow() würde hier helfen. Die Frage ist ja, wie oft Screenshots erstellt werden...



  • Wie viel erstellt werden, hmm ich denke solang ich angemeldet bin am Computer. Das mit dem Verstecken von Fenstern und Taskleiste ect. hab ich schon. Nur das mit der BitBlt Funktion bin ich schon seit einer WOche dran.. :S Sehr müsam das ganze.



  • Warum schreibst du 2 Programme (mein Eindruck), statt die Funktionen, die die Fenster Verstecken, in deinem Hook auf zu rufen? Wenn die Fenster noch auf dem Desktop sichtbar sind dann mag das daran liegen, das sich noch nicht alle neu gezeichnet haben-> UpdateWindow().
    BTW: hast du den das "Überwachungsprogramm" zur Hand?



  • nein eben leider nicht. Also du meinst ich soll eine einzige DLL in das Überwachungsprogramm Hooken, der auch die Funktionen beinhaltet? Klingt ziemlich Kompliziert...



  • BertaC schrieb:

    Klingt ziemlich Kompliziert...

    Wie versteckst du denn den IE? - hier mal mein Vorschlag:

    #include <shlwapi.h>
    ...
    void HideIE();
    void ShowIE();
    BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);
    ...
    void HideIE()
    {
    	EnumWindows(EnumWindowsProc,SW_HIDE);
    }
    
    void ShowIE()
    {
    	EnumWindows(EnumWindowsProc,SW_SHOW);
    }
    BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
    {
    	CHAR buffer[1024];
    	buffer[0]=0;
    	if(GetWindowTextA(hwnd,&buffer[0],1024))
    	{
    		if(StrStrIA(&buffer[0],"Windows Internet Explorer"))
    		{
    			ShowWindow(hwnd,lParam);
    		}
    	}
    	return TRUE;
    }
    


  • Ich mache es Folgendermassen:

    if(GetAsyncKeyState(VK_F6)&1)
             BrowserHide();
             DokuHide();
             TestHide();
    

    Die Funktionen werden auch durch EnumWindows versteckt. Es Funktioniert alles Super das mit dem Verstecken ect. Das einzige was mir fehlt zur "perfektion" ist eben das mit der BitBlt Hooking methode. Und es Funktioniert immernoch nicht...

    Kann es möglich sein, das was mit der Simulation der F6 Taste nicht stimmt.....
    Hier nochmal mein überarbeitender- nichtfunktionierender Code:

    #include <windows.h>
    #include <stdio.h>
    #include "detours.h"
    
    #pragma comment(lib,"detours.lib")
    #pragma comment(lib, "detoured.lib")
    
    int		xScreen, yScreen;
    int		vKey = VK_DELETE;
    
    void SimKeyPress(int vKey = VK_DELETE)
    {
        KEYBDINPUT ki={0};
    
        ki.wVk = vKey;
        ki.wScan = MapVirtualKeyEx(vKey, 0, GetKeyboardLayout(0));
    
        INPUT ipEvent;
        ipEvent.type = INPUT_KEYBOARD;
        ipEvent.ki = ki;
    
        SendInput(1,&ipEvent,sizeof(INPUT));
    }
    
    void SimKeyRelease(int vKey = VK_DELETE)
    {
        KEYBDINPUT ki={0};
        ki.wVk = vKey;
        ki.wScan = MapVirtualKeyEx(vKey, 0, GetKeyboardLayout(0));
    
        INPUT ipEvent;
        ipEvent.type = INPUT_KEYBOARD;
        ipEvent.ki = ki;
        ipEvent.ki.dwFlags = KEYEVENTF_KEYUP;
    
        SendInput(1,&ipEvent,sizeof(INPUT));
    }
    
    int (__stdcall* RealBitBlt)(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, unsigned long dwRop) = BitBlt;
    int (__stdcall* TramBitBlt)(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, unsigned long dwRop); 
    
    int __stdcall HookBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, unsigned long dwRop) 
    {
    	BOOL bReturn;
    
    	xScreen = GetSystemMetrics(SM_CXSCREEN);
    	yScreen = GetSystemMetrics(SM_CYSCREEN);
    
    	if ((nWidth == xScreen) && (nHeight == yScreen))
    	{
    		// Tastendruck simulieren
    		SimKeyPress(vKey);
    		Sleep(20);
    		SimKeyRelease(vKey);
    		Sleep(100);
    		bReturn = TramBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); 
    		SimKeyPress(vKey);
    		Sleep(20);
    		SimKeyRelease(vKey);
    	}
    		return TramBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
    }
    
    /*******************************************************************
    					Dll_MAIN
     ******************************************************************/
    BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
    {
        if (dwReason == DLL_PROCESS_ATTACH) 
    	{	
    
    		//PanicKey in virtuellen Key umwandeln (unschön, aber mir fällt nichts besseres ein)
    		vKey = VK_DELETE;
    
    		// Mithilfe von MSDetours die Funktionen hooken
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttachEx(reinterpret_cast<void**>(&RealBitBlt), HookBitBlt, reinterpret_cast<DETOUR_TRAMPOLINE**>(&TramBitBlt), 0, 0);
    DetourTransactionCommit(); 
        return TRUE;
    	}
    }
    


  • BertaC schrieb:

    Kann es möglich sein, das was mit der Simulation der F6 Taste nicht stimmt

    1. VK_DELETE != VK_F6
    2. in SimKeyPress wird ki.dwFlags nicht gefüllt.
    3. ich würde die unbenutzten struktur-members auf 0 setzen
    4. was spricht den dagegen EnumWindows/EnumWindowsProc in die Dll zu integrieren?
    (5. SendInput funktioniert ab Vista nicht mehr uneingeschränkt -> sieh msdn)


Anmelden zum Antworten