Biorąc pod uwagę identyfikator okna X11, czy istnieje sposób na znalezienie identyfikatora procesu, który go utworzył?
Oczywiście nie zawsze jest to możliwe, na przykład, jeśli okno przeszło połączenie TCP. W takim przypadku chciałbym, aby adres IP i port były powiązane ze zdalnym końcem.
Pytanie zostało zadane wcześniej na przepełnieniu stosu , a proponowaną metodą było użycie tej _NET_WM_PID
właściwości. Ale to ustawia aplikacja. Czy można to zrobić, jeśli aplikacja nie działa dobrze?
Odpowiedzi:
Chyba, że X-serwer obsługuje
XResQueryClientIds
od X-Zasobami przedłużenie v1.2 nie znam łatwy sposób, aby niezawodnie żądania identyfikator procesu. Istnieją jednak inne sposoby.Jeśli masz przed sobą okno i nie znasz jeszcze jego identyfikatora - łatwo je znaleźć. Po prostu otwórz terminal obok danego okna, uruchom
xwininfo
tam i kliknij to okno.xwininfo
pokaże ci identyfikator okna.Załóżmy więc, że znasz identyfikator okna, np. 0x1600045, i chcesz dowiedzieć się, jaki proces jest jego właścicielem.
Najłatwiejszym sposobem sprawdzenia, do kogo należy to okno, jest uruchomienie XKillClient dla niego, tj .:
i zobacz, który proces właśnie umarł. Ale tylko jeśli oczywiście nie masz nic przeciwko zabiciu go!
Innym łatwym, ale zawodnym sposobem jest sprawdzenie jego
_NET_WM_PID
iWM_CLIENT_MACHINE
właściwości:Właśnie takie narzędzia lubią
xlsclients
ixrestop
robią.Niestety te informacje mogą być niepoprawne nie tylko dlatego, że proces był zły i zmienił je, ale także dlatego, że był błędny. Na przykład po awarii / ponownym uruchomieniu Firefoksa widziałem osierocone okna (jak sądzę z wtyczki flash) ze
_NET_WM_PID
wskazaniem na proces, który zmarł dawno temu.Alternatywnym sposobem jest uruchomienie
i sprawdź właściwości rodziców danego okna. To może dać ci kilka wskazówek na temat pochodzenia okna.
Ale! Chociaż możesz nie znaleźć procesu, który utworzył to okno, wciąż istnieje sposób, aby dowiedzieć się, skąd ten proces połączył się z serwerem X. I tak jest dla prawdziwych hakerów. :)
Identyfikator okna 0x1600045, który znasz z zerowanymi niższymi bitami (tj. 0x1600000), jest „bazą klienta”. Wszystkie identyfikatory zasobów przydzielone temu klientowi są „oparte” na nim (0x1600001, 0x1600002, 0x1600003 itp.). Serwer X przechowuje informacje o swoich klientach w tablicy klientów [], a dla każdego klienta jego „baza” jest przechowywana w klientach [i] -> zmienna clientAsMask. Aby znaleźć gniazdo X odpowiadające temu klientowi, musisz podłączyć się do serwera X za pomocą
gdb
, przejść przez tablicę klientów [], znaleźć klienta z tymclientAsMask
i wydrukować jego deskryptor gniazda, zapisany w ((OsCommPtr) (klienci [i] - > osPrivate)) -> fd.Może być podłączonych wiele klientów X, więc aby nie sprawdzać ich wszystkich ręcznie, użyjmy funkcji gdb:
Po znalezieniu gniazda możesz sprawdzić, kto jest z nim połączony, a na końcu znaleźć proces.
OSTRZEŻENIE : NIE podłączaj gdb do X-serwera od WEWNĄTRZ X-serwera. gdb zawiesza proces, do którego się dołącza, więc jeśli podłączysz się do niego z poziomu sesji X, zamrozisz swój serwer X i nie będziesz mógł wchodzić w interakcje z gdb. Musisz albo przełączyć się na terminal tekstowy (
Ctrl+Alt+F2
), albo połączyć się z komputerem przez ssh.Przykład:
Znajdź PID swojego X-serwera:
Identyfikator okna to 0x1600045, więc podstawa klienta to 0x1600000. Podłącz do serwera X i znajdź deskryptor gniazda klienta dla tej bazy klientów. Musisz zainstalować informacje debugowania dla X-serwera (pakiet -debuginfo dla dystrybucji rpm-lub pakiet -dbg dla deba).
Teraz wiesz, że klient jest podłączony do gniazda 31 serwera. Użyj,
lsof
aby znaleźć to, co to gniazdo:(tutaj „X” to nazwa procesu, „1237” to jego pid, „root” to użytkownik, z którego działa, „31u” to deskryptor gniazda)
Tam możesz zobaczyć, że klient jest połączony przez TCP, następnie możesz przejść do komputera, z którego jest podłączony i sprawdzić
netstat -nap
tam, aby znaleźć proces. Ale najprawdopodobniej zobaczysz tam gniazdo unix, jak pokazano powyżej, co oznacza, że jest to klient lokalny.Aby znaleźć parę dla tego gniazda uniksowego, możesz użyć techniki MvG (będziesz również potrzebować informacji o debugowaniu dla zainstalowanego jądra):
Teraz, gdy znasz już gniazdo klienta, użyj
lsof
PID , aby je zatrzymać:Otóż to. Proces utrzymywania tego okna to „firefox” o identyfikatorze procesu 7725
Edycja 2017 : Teraz jest więcej opcji, jak widać na Kto ma drugi koniec tej pary gniazd unixowych? . W Linuksie 3.3 lub nowszym oraz w wersji
lsof
4.89 lub nowszej możesz zastąpić punkty 3 do 5 powyżej:aby dowiedzieć się, kto jest na drugim końcu gniazda na fd 31 procesu X-server o identyfikatorze 1237.
źródło
xdotool nie działał dla mnie. To spowodowało:
Biegać
xprop _NET_WM_PID
i kliknij okno.
Jest to oparte na odpowiedzi na stronie http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/
źródło
kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Jeśli masz zainstalowany xdotool , to
xdotool selectwindow getwindowpid
następnie kliknięcie danego okna spowoduje zwrócenie PID.
(Istnieją inne sposoby wyboru danego okna, np. Jeśli masz jego identyfikator, możesz to zrobić
xdotool getwindowpid <number>
. Możesz także wybrać według nazwy lub klasy itp.)Myślę, że wymaga to trochę dobrej gry w imieniu WM. Nie eksperymentowałem dużo ani nie musiałem.
źródło
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)
⇒ to tylko opakowanie powłoki do przeczytania_NET_WM_PID
(przydatne, ale nie to, o co prosiłem).Nie
_NET_WM_PID
jest ustawione przez menedżera okien (jako kolejny klient X11, skąd miałby wiedzieć?).Zamiast tego oczekuje się, że klienty (aplikacje) X11 zgodne ze standardem
_NET_WM_PID
iWM_CLIENT_MACHINE
we własnych oknach. Zakładając, że dobrze się zachowuje aplikacja, będzie to prawdą niezależnie od tego, czy menedżer okien jest uruchomiony, czy nie.Jeśli
WM_CLIENT_MACHINE
jest to twoja nazwa hosta, PID powinien mieć znaczenie.W przeciwnym razie „Chciałbym, aby adres IP i port były powiązane ze zdalnym końcem” - nie jestem pewien, co to oznacza. Na przykład, jeśli masz otwartą sesję ssh z włączonym przekazywaniem X, okna otwierane przez przekazywane aplikacje będą oznaczone zdalnym PID i nazwą hosta, ale niekoniecznie masz jakiś sposób, aby połączyć się z tym zdalnym hostem.
źródło
_NET_WM_PID
jest ustawiony przez aplikację: tak, to ma większy sens! Ale to nie jest protokół X11, to stosunkowo nowa specyfikacja FreeDesktop ._NET_WM_PID
wydaje się być ustawiony na zdalny PID iWM_CLIENT_MACHINE
zdalne połączenie (testowane z xterm).Byłem w stanie korzystać z
xdotool
wersji Ubuntu 11.04 beta, aleselectwindow
nie byłem prawidłowym poleceniem, musiałem zhakować skrypt za pomocą:następnie obserwuj id okna, gdy wybrałem okno, które chciałem, a następnie dekodowałem odpowiedzialny PID za pomocą:
źródło