Avec un identifiant de fenêtre X11, existe-t-il un moyen de trouver l'identifiant du processus qui l'a créé?
Bien sûr, cela n’est pas toujours possible, par exemple si la fenêtre est passée par une connexion TCP. Dans ce cas, j'aimerais connaître l'adresse IP et le port associés à l'extrémité distante.
La question avait déjà été posée sur le dépassement de pile et une méthode proposée consistait à utiliser la _NET_WM_PID
propriété. Mais c'est défini par l'application. Y at-il un moyen de le faire si l'application ne joue pas bien?
Réponses:
À moins que votre serveur X prend en charge
XResQueryClientIds
de l' extension v1.2 X-ressources Je ne connais pas facile moyen de manière fiable demander l' ID de processus. Il y a d'autres façons cependant.Si vous avez juste une fenêtre devant vous et que vous ne connaissez pas encore son identifiant, il est facile de le trouver. Ouvrez simplement un terminal à côté de la fenêtre en question, exécutez
xwininfo
-le et cliquez sur cette fenêtre.xwininfo
va vous montrer l'id de la fenêtre.Supposons donc que vous connaissez un identifiant de fenêtre, par exemple 0x1600045, et que vous souhaitiez savoir quel est le processus le possédant.
Le moyen le plus simple de vérifier à qui appartient cette fenêtre est d’exécuter XKillClient, c’est-à-dire:
et voir quel processus vient de mourir. Mais seulement si ça ne vous dérange pas de le tuer bien sûr!
Une autre façon facile , mais peu fiable est de vérifier ses
_NET_WM_PID
etWM_CLIENT_MACHINE
propriétés:C'est ce que les outils aiment
xlsclients
etxrestop
font.Malheureusement, ces informations peuvent être incorrectes, non seulement parce que le processus était pervers et les a modifiées, mais également parce qu’il était bogué. Par exemple, après un crash / redémarrage de Firefox, j'ai vu des fenêtres orphelines (provenant du plug-in flash, je suppose)
_NET_WM_PID
pointant vers un processus qui s'est éteint depuis longtemps.Une autre façon est de courir
et vérifiez les propriétés des parents de la fenêtre en question. Cela peut aussi vous donner des indices sur l’origine des fenêtres.
Mais! Bien que vous ne trouviez peut-être pas quel processus a créé cette fenêtre, il existe toujours un moyen de savoir où ce processus s'est connecté au serveur X. Et cette façon est pour les vrais hackers. :)
L'identificateur de fenêtre 0x1600045 que vous connaissez avec les bits inférieurs mis à zéro (c.-à-d. 0x1600000) est une "base client". Et tous les ID de ressources alloués à ce client sont "basés" sur celui-ci (0x1600001, 0x1600002, 0x1600003, etc.). X-server stocke des informations sur ses clients dans le groupe de clients [] et, pour chaque client, sa "base" est stockée dans la variable de clients [i] -> clientAsMask. Pour trouver X-socket correspondant à ce client, vous devez vous connecter au serveur X avec
gdb
, parcourir le tableau clients [], trouver le client avec celaclientAsMask
et imprimer son descripteur de socket, stocké dans ((OsCommPtr) (clients [i] - > osPrivate)) -> fd.Il peut y avoir beaucoup de clients X connectés, donc pour ne pas les vérifier tous manuellement, utilisons une fonction gdb:
Lorsque vous trouvez le socket, vous pouvez vérifier qui est connecté et enfin trouver le processus.
AVERTISSEMENT : N'attachez PAS gdb au serveur X depuis INSIDE. gdb suspend le processus auquel il est attaché; ainsi, si vous vous y attachez depuis X-session, vous figez votre serveur X et vous ne pourrez plus interagir avec gdb. Vous devez soit basculer sur text terminal (
Ctrl+Alt+F2
), soit vous connecter à votre machine via ssh.Exemple:
Trouvez le PID de votre serveur X:
L'identifiant de la fenêtre est 0x1600045, la base du client est donc 0x1600000. Attachez au serveur X et recherchez le descripteur de socket client pour cette base de clients. Vous aurez besoin des informations de débogage installées pour le serveur X (paquetage -debuginfo pour les distributions rpm ou paquetage -dbg pour les deb).
Vous savez maintenant que le client est connecté à un socket de serveur 31. Utilisez
lsof
pour trouver ce qu'est ce socket:(ici "X" est le nom du processus, "1237" est son pid, "root" est l'utilisateur depuis lequel il est en cours d'exécution, "31u" est un descripteur de socket)
Là, vous pouvez voir que le client est connecté via TCP, alors vous pouvez aller sur la machine à partir de laquelle il est connecté et vérifier
netstat -nap
le processus. Mais très probablement, vous verrez une prise Unix ici, comme indiqué ci-dessus, ce qui signifie qu'il s'agit d'un client local.Pour trouver une paire pour ce socket Unix, vous pouvez utiliser la technique de MvG (vous aurez également besoin d'informations de débogage pour votre noyau installé):
Maintenant que vous connaissez le socket client, utilisez
lsof
pour rechercher le PID le tenant:C'est ça. Le processus maintenant cette fenêtre est "firefox" avec l'identifiant de processus 7725
Édition 2017 : Il y a maintenant plus d'options comme on peut le voir sur Qui a l'autre extrémité de cette socket unix? . Avec Linux 3.3 ou supérieur et avec
lsof
4.89 ou supérieur, vous pouvez remplacer les points 3 à 5 ci-dessus par:pour savoir qui se trouve à l’autre extrémité du socket sur le disque 31 du processus du serveur X avec l’ID 1237.
la source
xdotool n'a pas fonctionné pour moi. Cela a:
Courir
xprop _NET_WM_PID
et cliquez sur la fenêtre.
Ceci est basé sur la réponse à http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/
la source
kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Si vous avez installé xdotool , alors
xdotool selectwindow getwindowpid
suivi en cliquant sur la fenêtre en question retournera le PID.
(Il existe d'autres moyens de sélectionner la fenêtre en question, par exemple, si vous avez son identifiant de fenêtre, vous pouvez simplement le faire
xdotool getwindowpid <number>
. Vous pouvez également sélectionner par nom ou par classe, etc.)Je pense que cela nécessite de jouer gentil de la part du WM. Je n'ai pas beaucoup expérimenté ni eu besoin de le faire.
la source
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)
⇒ c’est juste un wrapper de shell à lire_NET_WM_PID
(utile, mais pas ce que j’ai demandé).Le
_NET_WM_PID
gestionnaire de fenêtres ne le définit pas (comme un autre client X11, comment le saurait-il?).Au lieu de cela, les clients X11 conformes (applications) doivent être définis
_NET_WM_PID
etWM_CLIENT_MACHINE
sur leurs propres fenêtres. En supposant une application bien conçue, cela sera vrai qu'un gestionnaire de fenêtres soit en cours d'exécution ou non.Si
WM_CLIENT_MACHINE
est votre propre nom d'hôte, alors le PID devrait être significatif.Sinon, "je voudrais l'adresse IP et le port associés à l'extrémité distante" - je ne suis pas sûr de ce que cela signifie. Par exemple, si une session ssh est ouverte et que le transfert X est activé, les fenêtres ouvertes par les applications transférées seront marquées avec le PID et le nom d'hôte distants, mais vous n'avez pas nécessairement de moyen de vous reconnecter à cet hôte distant.
la source
_NET_WM_PID
est défini par l'application: oui, cela a plus de sens! Mais ce n'est pas le protocole X11, c'est la spécification FreeDesktop relativement récente ._NET_WM_PID
semble être défini sur le PID distant etWM_CLIENT_MACHINE
sur la connexion à distance (testé avec xterm).J'ai pu utiliser la
xdotool
version bêta sous Ubuntu 11.04, mais ceselectwindow
n'était pas une commande valide, j'ai dû pirater un script avec:puis regardez l’identifiant de la fenêtre défiler pendant que je sélectionnais la fenêtre que je voulais, puis décodait le PID responsable avec:
la source