Gibt es bei einer X11-Fenster-ID eine Möglichkeit, die ID des Prozesses zu ermitteln, der sie erstellt hat?
Dies ist natürlich nicht immer möglich, zum Beispiel wenn das Fenster über eine TCP-Verbindung kam. Für diesen Fall möchte ich die IP und den Port, die mit dem entfernten Ende verbunden sind.
Die Frage wurde zuvor zu Stack Overflow gestellt , und es wurde vorgeschlagen, die _NET_WM_PID
Eigenschaft zu verwenden. Aber das wird von der Anwendung festgelegt. Gibt es eine Möglichkeit, dies zu tun, wenn die Anwendung nicht gut abgespielt wird?
Antworten:
Es sei denn , Ihr X-Server unterstützt
XResQueryClientIds
von v1.2 Erweiterung X-Ressource weiß , dass ich keine einfache Art und Weise zu zuverlässig Prozess - ID anfordern. Es gibt jedoch auch andere Möglichkeiten.Wenn Sie nur ein Fenster vor sich haben und dessen ID noch nicht kennen, können Sie es leicht herausfinden. Öffnen Sie einfach ein Terminal neben dem betreffenden Fenster, führen Sie
xwininfo
es aus und klicken Sie auf dieses Fenster.xwininfo
zeigt Ihnen die Fenster-ID.Nehmen wir also an, Sie kennen eine Fenster-ID, z. B. 0x1600045, und möchten herausfinden, in welchem Prozess sie sich befindet.
Am einfachsten können Sie überprüfen, wem dieses Fenster gehört, indem Sie XKillClient für dieses Fenster ausführen.
und sehen, welcher Prozess gerade gestorben ist. Aber nur, wenn Sie nichts dagegen haben, es natürlich zu töten!
Eine weitere einfache aber unzuverlässig Art und Weise ist die zu überprüfen
_NET_WM_PID
undWM_CLIENT_MACHINE
Eigenschaften:Das ist, was Werkzeuge mögen
xlsclients
undxrestop
tun.Leider können diese Informationen nicht nur falsch sein, weil der Prozess schlecht war und diese geändert hat, sondern auch, weil er fehlerhaft war. Zum Beispiel habe ich nach einem Firefox-Absturz / Neustart verwaiste Fenster (vom Flash-Plugin, denke ich) mit einem
_NET_WM_PID
Hinweis auf einen Prozess gesehen, der vor langer Zeit gestorben ist.Alternative Weg ist zu laufen
und überprüfen Sie die Eigenschaften der Eltern des betreffenden Fensters. Das kann Ihnen auch Hinweise auf die Fensterherkunft geben.
Aber! Sie können möglicherweise nicht feststellen, von welchem Prozess dieses Fenster erstellt wurde, aber es gibt immer noch eine Möglichkeit, festzustellen, von wo aus dieser Prozess eine Verbindung zum X-Server hergestellt hat. Und so ist es für echte Hacker. :)
Die Windows-ID 0x1600045, die Sie kennen, wenn niedrigere Bits auf Null gesetzt sind (dh 0x1600000), ist eine "Client-Basis". Alle für diesen Client zugewiesenen Ressourcen-IDs basieren darauf (0x1600001, 0x1600002, 0x1600003 usw.). X-Server speichert Informationen zu seinen Clients im clients [] -Array und für jeden Client wird seine "Basis" in der clientAsMask-Variablen [i] -> gespeichert. Um den X-Socket zu finden, der diesem Client entspricht, müssen Sie eine Verbindung zum X-Server mit dem
gdb
Array clients [] herstellen, den Client damit suchenclientAsMask
und dessen Socket-Deskriptor ausgeben, der in ((OsCommPtr) (clients [i] - > osPrivate)) -> fd.Möglicherweise sind viele X-Clients verbunden. Um sie also nicht alle manuell zu überprüfen, verwenden wir eine GDB-Funktion:
Wenn Sie den Socket gefunden haben, können Sie überprüfen, wer mit ihm verbunden ist, und schließlich den Prozess finden.
WARNUNG : Schließen Sie KEINE GDB von INNERHALB des X-Servers an den X-Server an. gdb unterbricht den Prozess, mit dem es verbunden ist. Wenn Sie also innerhalb von X-session eine Verbindung herstellen, frieren Sie Ihren X-Server ein und können nicht mehr mit gdb interagieren. Sie müssen entweder zum Textterminal (
Ctrl+Alt+F2
) wechseln oder über ssh eine Verbindung zu Ihrem Computer herstellen.Beispiel:
Finden Sie die PID Ihres X-Servers:
Die Fenster-ID lautet 0x1600045, die Client-Basis also 0x1600000. Stellen Sie eine Verbindung zum X-Server her und suchen Sie den Client-Socket-Deskriptor für diese Client-Basis. Sie müssen Debug-Informationen für X-Server installiert haben (-debuginfo-Paket für rpm-Distributionen oder -dbg-Paket für debs).
Jetzt wissen Sie, dass der Client mit einem Server-Socket 31 verbunden
lsof
ist.(hier ist "X" der Prozessname, "1237" die PID, "root" der Benutzer, von dem aus er ausgeführt wird, "31u" ist ein Socket-Deskriptor)
Dort sehen Sie möglicherweise, dass der Client über TCP verbunden ist, und können dann zu dem Computer gehen, von dem aus die Verbindung hergestellt wurde, und
netstat -nap
dort nach dem Prozess suchen. Aber höchstwahrscheinlich sehen Sie dort einen Unix-Socket, wie oben gezeigt, was bedeutet, dass es sich um einen lokalen Client handelt.Um ein Paar für diesen Unix-Socket zu finden, können Sie die MvG-Technik verwenden (Sie benötigen auch Debug-Informationen für Ihren installierten Kernel):
Nun, da Sie den Client-Socket kennen, können
lsof
Sie die PID ermitteln, in der sich der Socket befindet :Das ist es. Der Prozess, der dieses Fenster beibehält, ist "Firefox" mit der Prozess-ID 7725
2017 Edit : Es gibt jetzt mehr Optionen, wie unter Wer hat das andere Ende dieses Unix-Socketpaars? . Ab Linux 3.3 und
lsof
4.89 können Sie die obigen Punkte 3 bis 5 ersetzen durch:um herauszufinden, wer sich am anderen Ende des Sockets auf fd 31 des X-Server-Prozesses mit der ID 1237 befindet.
quelle
xdotool hat bei mir nicht funktioniert. Dies tat:
Lauf
xprop _NET_WM_PID
und klicke auf das Fenster.
Dies basiert auf der Antwort unter http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/
quelle
kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Wenn Sie xdotool installiert haben, dann
xdotool selectwindow getwindowpid
gefolgt von einem Klick auf das betreffende Fenster wird die PID zurückgegeben.
(Sie können das betreffende Fenster auch auf andere Weise auswählen, z. B. wenn Sie über die entsprechende Fenster-ID verfügen
xdotool getwindowpid <number>
. Sie können die Auswahl auch nach Name oder Klasse usw. vornehmen.)Ich denke, das erfordert ein nettes Spiel im Namen der WM. Ich habe nicht viel experimentiert oder musste.
quelle
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)
⇒ Es ist nur ein Shell-Wrapper zum Lesen_NET_WM_PID
(nützlich, aber nicht das, wonach ich gefragt habe).Das
_NET_WM_PID
wird nicht vom Fenstermanager festgelegt (wie nur ein anderer X11-Client, wie würde es wissen?).Stattdessen müssen kompatible X11-Clients (Anwendungen)
_NET_WM_PID
undWM_CLIENT_MACHINE
in ihren eigenen Fenstern eingerichtet werden. Vorausgesetzt, dass sich eine Anwendung gut verhält, ist dies der Fall, unabhängig davon, ob ein Fenstermanager ausgeführt wird oder nicht.Wenn
WM_CLIENT_MACHINE
es sich um Ihren eigenen Hostnamen handelt, sollte die PID aussagekräftig sein.Andernfalls "Ich möchte die IP und den Port, die mit dem Remote-Ende verknüpft sind" - ich bin mir nicht sicher, was das bedeutet. Wenn Sie beispielsweise eine SSH-Sitzung mit aktivierter X-Weiterleitung geöffnet haben, werden Fenster, die von weitergeleiteten Apps geöffnet werden, mit der Remote-PID und dem Hostnamen gekennzeichnet. Sie haben jedoch nicht unbedingt die Möglichkeit, eine Verbindung zu diesem Remote-Host herzustellen.
quelle
_NET_WM_PID
wird von der anwendung gesetzt: richtig, das macht mehr sinn! Es ist jedoch nicht das X11-Protokoll, sondern die relativ aktuelle FreeDesktop- Spezifikation._NET_WM_PID
auf die Remote-PID undWM_CLIENT_MACHINE
auf die Remote-Verbindung eingestellt zu sein (getestet mit xterm).Ich konnte das
xdotool
unter Ubuntu 11.04 Beta benutzen , war aberselectwindow
kein gültiger Befehl, ich musste ein Skript hacken mit:Beobachten Sie dann, wie die Fenster-ID vergeht, während ich das gewünschte Fenster auswählte, und decodieren Sie dann die verantwortliche PID mit:
quelle