IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Hook souris et Windows 7 64 bits


Sujet :

Windows

  1. #1
    Membre du Club
    Profil pro
    Développeur mobile
    Inscrit en
    Novembre 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Novembre 2007
    Messages : 107
    Points : 58
    Points
    58
    Par défaut Hook souris et Windows 7 64 bits
    Bonjour,

    Je cherche désespérément à faire fonctionner un hook souris basique réalisé en C++. Le hook doit fonctionner sous Windows 7 64 bits, où on peut donc y rencontrer des applications 32 et 64 bits.

    Après plusieurs recherches, il me faut donc en gros réaliser 2 hooks, un compilé en 32 bits pour les applications 32 bits, un autre compilé en 64 bits pour les applications 64 bits.

    J'ai trouvé un bout de code me permettant de faire la distinction entre les applications 32 et 64 bits, mais mon problème est que je ne sais pas comment le mettre en place ...

    Le code faisant cette distinction d'applis est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    HWND hwnd;
    DWORD ProcID;
    HANDLE hProc;
    BOOL bWOW64Proc = FALSE;
    
    GetWindowThreadProcessId(hwnd, &ProcID);
    hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);
    IsWow64Process(hProc, &bWOW64Proc);
    CloseHandle(hProc);
    Le code de ma DLL où est codé mon hook, tout ce qu'il y a de plus classique (il ne fait rien, c'est juste pour l'exemple) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <windows.h>
    #include <stdio.h>
    
    HANDLE MemPartagee;
    HINSTANCE thismod;
    HHOOK hhk;
    
    /**
     * Init DLL.
     */
    extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID Reserved)
    {
        if(dwReason == DLL_PROCESS_ATTACH)
        {
            thismod = hDll;
        }
        return 1;
    }
    
    /**
     * Fonction hook.
     */
    LRESULT CALLBACK wndProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode >= 0)
        {
            if (wParam == WM_LBUTTONDOWN)
            {
                // Traitements du hook ...
            }
        }
        
        return CallNextHookEx(hhk, nCode, wParam, lParam);
    }
    
    /**
     * Démarrage du hook.
     */
    extern "C" __declspec(dllexport) int __stdcall Intercepte()
    {
        if(!hhk)
        {
            hhk  = SetWindowsHookEx(WH_MOUSE, wndProc, thismod, 0);
        }
        
        return (int) hhk;
    }
    
    /**
     * Arrêt du hook.
     */
    extern "C" __declspec(dllexport) void __stdcall Relache()
    {
        if(hhk)
        {
            UnhookWindowsHookEx(hhk);
            hhk = 0;
        }
    }
    Quelqu'un saurait-il comment faire, ou plus généralement, comment réaliser un (ou 2) hook(s) souris fonctionnant sous Windows 7 64 bits ?

    Merci par avance pour votre aide

  2. #2
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Salut.

    Je déterre ce topic pour savoir où tu en es ?
    Est-ce que tu as résolu ton problème ?

    J'ai en fait le même genre de soucis.
    Je suis développeur pour cette application.
    Actuellement, seule une version 32 bits existe.
    L'une de ses fonctionnalités (nommée Drag'n'Go) permet de déplacer une fenêtre vers une zone spécifique de l'écran en adaptant sa taille au passage (il y a une petite vidéo dans la partie "Screenshots / Demos).
    Cela se fait à l'aide de plusieurs hooks installés au démarrage de l'application.
    Tout fonctionne correctement, sauf sur une version 64bits de Windows.
    En fait, les fenêtres des processus 32bits sont bien prises en compte, mais pas les fenêtres des processus 64 bits.
    J'ai fait le test en compilant l'application en 64 bits, et là, c'est l'inverse qui se produit (seules les fenêtres des processus 64 bits sont prises en compte).

    D'après tout ce que j'ai pu lire sur le net à ce sujet, il va falloir mettre en place deux dll différentes (une pour chaque architecture).
    Le plus gros problème est en fait l'intégration de ces deux dll au sein de la même application :
    • Tout d'abord, comment lancer la dll 32bits depuis un exécutable 64bits
    • Comment faire "communiquer" la dll 32 bits avec l'exécutable (il faut que la dll puisse connaitre les différents réglages effectués au sein de l'application, et ce sans redémarrage de cette dernière)


    Merci d'avance pour toute piste qui pourrait être évoquée.

    @+
    Xav'

  3. #3
    Membre du Club
    Profil pro
    Développeur mobile
    Inscrit en
    Novembre 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Novembre 2007
    Messages : 107
    Points : 58
    Points
    58
    Par défaut
    Salut,

    Hélas je n'ai pas plus d'infos à ce sujet pour le moment.
    Si qqn sait, je suis toujours preneur.

  4. #4
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    Citation Envoyé par wxXav Voir le message
    Le plus gros problème est en fait l'intégration de ces deux dll au sein de la même application :
    • Tout d'abord, comment lancer la dll 32bits depuis un exécutable 64bits
    • Comment faire "communiquer" la dll 32 bits avec l'exécutable (il faut que la dll puisse connaitre les différents réglages effectués au sein de l'application, et ce sans redémarrage de cette dernière)
    Il n'est pas possible d'avoir un programme 32 bits avec une DLL 64 bits (et vice-versa).

    Pour la question des hooks, la DLL est injectée dans les processus, donc un programme 32 bits ne peut injecter que des programmes 32 bits (même combat pour le 64 bits). Il faut donc créer deux applications.

    Je cite: SetWindowHookEx() [MSDN] (section "Remarks")

    Citation Envoyé par MSDN
    A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.
    Deux exceptions toutefois: WH_MOUSE_LL et WH_KEYBOARD_LL puisque la DLL n'est pas injectée.

    Je cite: LowLevelMouseProc Callback Function [MSDN] (section "Remarks")

    However, the WH_MOUSE_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.

  5. #5
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Salut, et merci pour la réponse.

    Citation Envoyé par Neitsa Voir le message
    Il n'est pas possible d'avoir un programme 32 bits avec une DLL 64 bits (et vice-versa).

    Pour la question des hooks, la DLL est injectée dans les processus, donc un programme 32 bits ne peut injecter que des programmes 32 bits (même combat pour le 64 bits). Il faut donc créer deux applications.
    Ça, je suis bien d'accord.
    Il faut donc que je fasse :
    • un petit exécutable et sa dll associée pour installer un hook 32bits
    • la même chose pour le 64 bits

    Le problème est de pouvoir faire communiquer ces deux dll avec une seule et même application (et de plus, la communication devrait pouvoir se faire dans les deux sens).

    Ou alors (c'est juste une idée, au passage), une dll "maître" ayant la même architecture que l'application, et une seconde dll pour l'autre architecture qui arriverait à communiquer avec la première.

    Je me dis que ça ne doit pas être impossible à faire (d'ailleurs, il y en a qui y sont apparemment arrivés : EasyHook mais il s'agit d'API Hooking, et le code source est en CSharp)

    Donc, ma question est maintenant : comment arriver à faire communiquer les deux dlls entre elles, ou comment les faire communiquer avec l'application principale ?

    Merci encore.
    @+
    Xav'

  6. #6
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Hello tout le monde.

    Je pense avoir trouvé une solution acceptable, et surtout assez simple à mettre en oeuvre.

    Comme il a été dit dans les posts précédents, il faut à tout prix avoir deux dll.
    Et comme une application ne peut pas à la fois charger une dll 32 bits et une dll 64 bits, il faudra que ces deux dll aient leur propre "lanceur" (une simple application qui chargera la dll et appellera la fonction d'installation des hook).

    Ces fameux lanceurs seront constitués d'une petite fenêtre (qui ne sera pas visible par l'utilisateur final).
    Il suffit donc de connaître la classe de la fenêtre, ainsi qu'éventuellement son titre pour pouvoir la retrouver avec un simple "FindWindow" depuis l'application principale.

    A partir du moment où l'application principale possède le handle (HWND) de chaque fenêtre cachée, elle va pouvoir lui envoyer des messages de la façon la plus classique qui soit : avec SendMessage.

    Et j'ai découvert un message spécialement dédié à l'échange de données entre deux processus : WM_COPYDATA.

    L'application n'aura donc qu'à envoyer les données au lanceur qui les transmettra à la dll.
    Pour la communication de données dans l'autre sens, cela peut se faire de la même manière, que ce soit depuis la dll ou depuis le lanceur.

    Il ne reste plus qu'à mettre tout ça en pratique.

    @thenaoh : J'espère que cette solution pourra t'aider.
    Sinon, il y a apparement d'autres solutions pour la communication entre deux processus, mais je pense que tu ne pourras pas non plus échapper à la méthode des "exécutables multiples".

    @+
    Xav'

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par wxXav Voir le message
    A partir du moment où l'application principale possède le handle (HWND) de chaque fenêtre cachée, elle va pouvoir lui envoyer des messages de la façon la plus classique qui soit : avec SendMessage.
    Depuis Vista et dû à l'UIPI, SendMessage va échoué lamentablement dans certains contextes si le message est supérieur à WM_USER. Il faudra prendre soin d'accepter chacun de ces messages avec ChangeWindowMessageFilter

  8. #8
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut Ça ne veut pas marcher...
    Hello.

    Je rencontre quelques soucis avec mon système de hooks 32/64 bits.

    Afin de peaufiner le truc, voici ce que j'ai fait :
    • Une application principale (32 ou 64 bits)
    • Un exécutable lié à une dll 32 bits
    • Un exécutable lié à une dll 64 bits


    L'application principale est une simple fenêtre avec 3 boutons :
    • Un pour démarrer le lanceur 32 bits
    • Un pour démarrer le lanceur 64 bits
    • Un pour effectuer une série de tests


    Les lanceurs sont de simples fenêtres (avec une zone de texte pour les logs)

    L'application principale démarre bien chaque lanceur quand on le lui demande.
    Ensuite, lors d'un premier clic sur le bouton "Test", elle demande à chaque lanceur de mettre en place les hooks
    Lors d'un deuxième clic, on demande l'arrêt des hooks, et un troisième demande la fermeture des fenêtres "lanceurs" (et donc de l'application associée).
    Les deux premières demandes se font vie des messages Windows "personnalisés" (créés avec RegisterWindowMessage).

    Jusque là, tout fonctionne bien : les hooks sont biens démarrés sans code d'erreur en retour.

    Le problème, c'est que suivant le type de hook, il ne semble pas fonctionner correctement.
    Par exemple, pour un hook souris "classique" (WH_MOUSE), seuls les événements effectués sur la fenêtre du lanceur sont interceptés. J'ai pourtant bien spécifié "0" comme dernier paramètre de la fonction "SetwindowsHookEx".
    J'ai le même comportement avec un hook de type WH_CBT.

    Par contre, autre comportement étrange : si au lieu de créer un hook de type "WH_MOUSE", j'en crée un de type "WH_MOUSE_LL", ça marche nickel. Et surtout, chaque hook (32 et 64 bits) intercepte les messages pour tous les événements, qu'ils soient destinés à une fenêtre 32 ou 64 bits.

    Je ne pense pas que le problème vienne du point soulevé par Andnotor dans le post précédent, car j'ai un comportement identique sun un Windows XP 32bits (avec un seul lanceur et une seule dll, bien entendu).

    Si quelqu'un a des idées sur l'éventuelle provenance de ce problème, je suis preneur.

    Merci d'avance, et @+
    Xav'

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par wxXav Voir le message
    j'ai un comportement identique sun un Windows XP 32bits
    Si ça ne marche pas sous XP, il n'y a qu'une seule explication : Tu initialises une variable dans la DLL en espérant qu'elle soit partagée entre processus. Ce qui ne fonctionne évidemment pas ! (Le handle de la fenêtre à qui tu destines les messages par exemple )

  10. #10
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Le handle de la fenêtre à qui tu destines les messages par exemple )
    Donc, en fait, le hook marche bien, mais je n'ai pas le retour dans les "pseudos-logs" ?

    Et je suppose que le problème est le même avec la variable contenant le handle du hook mis en place, ainsi que celles contenant les IDs des événements personnalisés
    Existe t'il une méthode pour que ces variables soient partagées ?

    Est-ce que ce bout de code pourrait résoudre le problème ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HWND g_hMainWnd __attribute__((section("hwnd_mainframe"), shared)) = NULL;
    Et comment expliquer que pour un hook de type "WH_MOUSE_LL" ça marche ?

    Merci d'avance pour les éclaircissements.

    @+
    Xav'

  11. #11
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut Ça marche !!!!!!
    J'aurais du faire l'essai et/ou rechercher la signification de ce fameux "__attribute__" avant de poser la question.

    Citation Envoyé par wxXav Voir le message
    Est-ce que ce bout de code pourrait résoudre le problème ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HWND g_hMainWnd __attribute__((section("hwnd_mainframe"), shared)) = NULL;
    Ça marche en plaçant un code similaire à celui-ci dans les dll (pour les handles de fenêtres/contrôles et les IDs des messages).

    Citation Envoyé par wxXav Voir le message
    Et comment expliquer que pour un hook de type "WH_MOUSE_LL" ça marche ?
    Par contre, cette question est toujours en suspend...

    @thenaoh : je confirme ce que j'ai mis plus haut : pour certains types de hook, il n'est apparemment pas nécessaire d'avoir les deux versions (32 et 64 bits).
    Je viens de refaire le test avec un hook WH_MOUSE, et que l'application principale soit en 32 ou 64 bits, je reçois deux fois le message WM_LBUTTONUP.

    Encore merci Andnotor de m'avoir mis sur la piste.
    @+
    Xav'

  12. #12
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par wxXav Voir le message
    Donc, en fait, le hook marche bien, mais je n'ai pas le retour dans les "pseudos-logs" ?
    C'est ça !

    Citation Envoyé par wxXav Voir le message
    Et je suppose que le problème est le même avec la variable contenant le handle du hook mis en place
    A partir du moment où CallNextHookEx n'a plus besoin de cette donnée depuis NT (!), tu peux purement et simplement la supprimer.

    Citation Envoyé par wxXav Voir le message
    ainsi que celles contenant les IDs des événements personnalisés
    Bien sûr, ce sont des variables comme les autres. Mais ça se résout facilement en appelant RegisterWindowMessage depuis le lanceur ET depuis la DLL.

    Citation Envoyé par wxXav Voir le message
    Et comment expliquer que pour un hook de type "WH_MOUSE_LL" ça marche ?
    Un hook de bas niveau est toujours exécuté dans le processus qui l'a installé

  13. #13
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    A partir du moment où CallNextHookEx n'a plus besoin de cette donnée depuis NT (!), tu peux purement et simplement la supprimer.
    Tiens, je n'avais pas remarqué que ce paramètre ne servait à rien.
    De toute façon, il me faut quand même une variable pour savoir si oui ou non le hook a bien été mis en place, donc, ça ou autre chose...

    Citation Envoyé par Andnotor Voir le message
    Bien sûr, ce sont des variables comme les autres. Mais ça se résout facilement en appelant RegisterWindowMessage depuis le lanceur ET depuis la DLL.
    Mais dans ce cas, ça implique d'appeler RegisterWindowMessage à chaque "rattachement" à un processus, donc dans DllMain.

    Encore merci pour toutes ces précisions.

    @+
    Xav'

  14. #14
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par wxXav Voir le message
    De toute façon, il me faut quand même une variable pour savoir si oui ou non le hook a bien été mis en place, donc, ça ou autre chose...
    Il faut juste se souvenir que si la variable est dans la DLL (SetWindowsHookEx est dans la DLL), elle n'est significative que dans le processus lanceur

    Citation Envoyé par wxXav Voir le message
    Mais dans ce cas, ça implique d'appeler RegisterWindowMessage à chaque "rattachement" à un processus, donc dans DllMain.
    Exactement, DLL_PROCESS_ATTACH.

Discussions similaires

  1. Réponses: 17
    Dernier message: 15/02/2015, 00h25
  2. Hook de messages windows (autres que souris/clavier)
    Par strayyy dans le forum Windows
    Réponses: 26
    Dernier message: 17/06/2009, 15h47
  3. Java natif & hook souris Windows
    Par ®om dans le forum Langage
    Réponses: 1
    Dernier message: 18/07/2006, 23h39
  4. Réponses: 5
    Dernier message: 14/10/2005, 21h44
  5. Probleme de Hook souris
    Par mandagor dans le forum MFC
    Réponses: 17
    Dernier message: 07/07/2005, 18h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo