C# i hook globalny (?)

0

Witam!

Tak się męczę i zastanawiam na przemian, czy założenie hooka globalnego w C# jest możliwe. Na stronach supportu Microsoftu czytam, że:

Global hooks are not supported in the .NET Framework
Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework.

Ale, jeżeli stworzę sobie jedną dll'kę, która będzie ustawiała tego globalnego hooka, którego funkcja znajduje się w jeszcze innej dll'ce (bądź tej samej, ale nie wiem skąd wziąć HINSTANCE injectora, więc dla pewności mam je dwie), to czy wtedy taki śmieszny twór ma prawo działać?

Stworzyłem sobie taki testowy projekt, zrobiłem dwie dll'ki. Lecz jakoś dziwnie to wszystko współpracowało... W procedurze owego hooka znajdował się MessageBox i return CallNextHook. Owy MessageBox pojawia się tylko i wyłącznie wtedy, kiedy w aplikacji C# wywołuję funkcję UnHook z pierwszej biblioteki (injectora).

Byłbym wdzięczny, jak ktoś pochwaliłby się swoimi doświadczeniami z hookami i C#. Jak nie znajdę rozwiązania, to będę musiał jakoś przeżyć z C++...

Pozdrawiam, Wronq!

0

Napisano wyraźnie - kod zarządzany nie może zostać użyty do implementacji globalnego hooka. Nie ma prawa działać poprawnie.

0

No tak, ale ja nie implementuję hooka bezpośrednio z .NET, tylko przez pośredniczącą bibliotekę DLL.

0

Biblioteka jest w kodzie zarządzanym?

0

Obie biblioteki są napisane w C++.

0

Będzie działać bez problemów. Nawet w C# czystym by działało wstrzykiwanie, jeżeli by użyc [DllImport] do importu odpowiednich API. Musisz mieć tylko pewnosc ze Dll ktora bedziesz wstrzykiwał jest napisana w czystym c++ (umnagaed).

Jest jeszcze opcja wstrzykniecia czystej c++ dllki ktora uzywa hosting api aby uruchomić managed dll, ale to już troche trudniejsza sprawa.

0

Mam wrażenie, że pan wyżej mówi o DLL injecting, a nie o hookach... W czystym C# (oczywiście importując kilka funkcji WinAPI) mogę jedynie założyć hooka lokalnego, jak podpowiada support. Jeżeli się mylę, to przepraszam.
Ale nadal zastanawia mnie sprawa, dlaczego hook nie chce współpracować. Podam odpowiednie kody. Klasa z funkcjami:

 class WinAPI
{
         [DllImport("dll.dll", CharSet = CharSet.Auto,
         CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookM(int idHook); //Funkcja z dll'ki (injectora)

        [DllImport("dll.dll", CharSet = CharSet.Auto,
         CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookM(int hhk);
}

Jej użycie:

            int hhook = 0;
            hhook = WinAPI.SetWindowsHookM(13);//WH_KEYBOARD_LL
            Console.WriteLine(hhook);
            Console.ReadKey();
            Console.CursorLeft = 0;
            Console.WriteLine(WinAPI.UnhookWindowsHookM(hhook));
            Console.ReadKey();

Funkcje biblioteki, która zakłada hook:

HHOOK SetWindowsHookM(int idHook)
{
     HINSTANCE hinstDLL;
     HHOOK hhook;
     HOOKPROC hkprc;
     
     hinstDLL = LoadLibrary("Hook.dll");
     
     switch(idHook)
     {
          case WH_KEYBOARD_LL:
               MessageBox(0, "Zakladam hooka", ".", MB_ICONINFORMATION);
               hkprc = (HOOKPROC)GetProcAddress(hinstDLL, KEYBOARD_LL_N); //#define KEYBOARD_LL_N	"KeyboardLLHook"
               return SetWindowsHookEx(WH_KEYBOARD_LL, hkprc, hinstDLL, 0); 
               break;
     }
}

BOOL UnhookWindowsHookM(HHOOK hhk)
{
     MessageBox(0, "OdHookam", ".", MB_ICONINFORMATION);
     return UnhookWindowsHookEx(hhk);     
}

I na koniec funkcja samego Hooka:

LRESULT CALLBACK KeyboardLLHook (int code, WPARAM wParam, LPARAM lParam)
{   
        MessageBox(0, "Witaj z Hooka", "Elo", MB_ICONINFORMATION);
	if (code < 0) return CallNextHookEx (0, code, wParam, lParam);        
	if (code == HC_ACTION)    
	{        
		////////
	}
	return CallNextHookEx (0, code, wParam, lParam);
}

Przypomnę, że MsgBox z KeyboardLLHook pojawia się tylko wtedy kiedy wyłączam hooka (czyli dostaję wiadomość "OdHookam" i "Witaj z Hooka" na raz).

Pozdrawiam, Wronq!

0

Sorka, wczoraj późno było jak to pisałem i troche mnie przymuliło.

Z tego co wiem to WM_KEYBOARD_LL i WM_MOUSE_LL można ustawić jako global hooki z managed code. To co tam wypisują na msdn to ich nie dotyczy.

Kod wygląda w porządku, nie widze czemu miał by nie działać jak należy. Możliwe, że problemem jest UAC jeżeli używasz visty lub xp.

Jeżeli nie, popatrz tutaj http://www.codeproject.com/KB/cs/globalhook.aspx. Na samym dole opisują problemy z Garbage Collectorem i rozwiązanie, więc może masz jakiś dziwny przypadek tego ;).

0

Korzystam z Win XP. O UAC nic mi nie wiadomo, ale jeżeli aplikacja, która zakłada hooka jest w C++ wszystko działa bez zarzutu.
Jeżeli dobrze rozumiem działanie GC, to wartość hhook powinna gdzieś wynosić 0, mam rację? Sprawdzałem, nigdzie nie wynosi 0, więc raczej to nie problem z GC...
Dzięki za zainteresowanie.

Pozdrawiam, Wronq

1 użytkowników online, w tym zalogowanych: 0, gości: 1