Плагин ProcCmdLine.spf (командная строка процесса)

Обсуждение программ nnCron и nnCron LITE

Плагин ProcCmdLine.spf (командная строка процесса)

Postby dothen » Fri, 14 Apr 2017, 00:12

Продолжение этой темы Логирование запуска с полным путем да с аргументами...

Получает командную строку, или полный путь процесса. Работает для 32-битных и 64-битных процессов.

Штатные слова FOR-PROCS FOR-PROCS: KILL KILL: PROC-EXIST? PROC-EXIST: PROC-NAME PROC-FULLNAME PROC-CLOSE PROC-CLOSE:
стали работать с 64-битными процессами.

WatchProc: и WatchProcStop: стали работать с 64-битными процессами.

В nnCron уже давно есть слова которые могут работать с 64-битными процессами.

WTS-FOR-PROCS ( "proc_pattern" sessionid -- )
<...>
;WTS-FOR-PROCS

WTS-FOUND-SESSIONID
WTS-FOUND-PROCESSID
WTS-FOUND-PROCESSNAME
WTS-FOUND-USERSID

WTS-GET-USERNAME
.WTS-PROCESSES

Code: Select all
\ Файл:       proccmdline.spf
\ Автор:      dothen
\ Дата:       01.05.2017
\ Версия:     1.02
\ Описание:
\ Получает командную строку, или полный путь процесса x32/x64.

\ Штатные слова стали работать с 64-битными процессами.
\ FOR-PROCS FOR-PROCS: KILL KILL: PROC-EXIST? PROC-EXIST: PROC-NAME PROC-FULLNAME PROC-CLOSE PROC-CLOSE:
\ WatchProc: и WatchProcStop: стали работать с x64 процессами.

\ ------------------------------------------------------
\ Права доступа и существование процесса не проверяются.
\ ------------------------------------------------------

\ Слова:
\ OSx32? ( -- ? )   Разрядность операционной системы.
\ OSx64? ( -- ? )
\ Proc32? ( pid -- ? )    Разрядность процесса.
\ Proc64? ( pid -- ? )

\ PROC-CMDLINE ( pid -- a u )    Получает командную строку процесса.
\ PROC-FULLNAME ( pid -- a u )   Переопределяется для 64-битной ОС.

\ ProcID     Тут содержится PID после выполнении PROC-CMDLINE и PROC-FULLNAME.
\ ProcBIT    Тут содержится строка "(32)" или "(64)" после выполнении PROC-CMDLINE и PROC-FULLNAME в 64-битной ОС. Удобно при выводе в лог или консоль (ProcBIT ASCIIZ> TYPE).


WINAPI: GetNativeSystemInfo Kernel32.dll
WINAPI: IsWow64Process Kernel32.dll

\ Разрядность операционной системы.
\ : OSx32? ( -- ? ) PAD GetNativeSystemInfo DROP PAD W@ 0 = ;
\ : OSx64? ( -- ? ) PAD GetNativeSystemInfo DROP PAD W@ 9 = ;
PAD GetNativeSystemInfo DROP PAD W@ 0 = VALUE OSx32?
PAD GetNativeSystemInfo DROP PAD W@ 9 = VALUE OSx64?

\ Разрядность процесса.
: Proc64? ( pid -- ? )
    0 0x400 OpenProcess >R 0 SP@ R@ IsWow64Process DROP R> CloseHandle DROP
    0= OSx64? AND
;

: Proc32? ( pid -- ? ) Proc64? 0= ;


\ -----------------------------------------
\ Взятие командной строки или полного пути.
\ -----------------------------------------
\ USER-VALUE ProcID
\ USER-CREATE ProcBIT 2 CELLS USER-ALLOT
\ USER-CREATE retLength 2 CELLS USER-ALLOT
\ USER-VALUE bufMem
\ USER-VALUE hProc

0 VALUE ProcID
2VARIABLE ProcBIT
2VARIABLE retLength
0 VALUE bufMem
0 VALUE hProc

: getline ( -- a u )
    0 bufMem retLength @ + W!
    bufMem retLength @ 2 / UNICODE>S OVER >R S>TEMP R> FREE DROP
;

: close-free ( -- ) hProc CloseHandle DROP bufMem FREE DROP ;

\ ------------------------------------
\ Для 64-битной ОС.
\ ------------------------------------
OSx64? [IF]
\ Эти функции недокументированные.
WINAPI: NtWow64QueryInformationProcess64 ntdll.dll
WINAPI: NtWow64ReadVirtualMemory64 ntdll.dll

: ReadProcMemory64 { size offset -- }
    retLength                \ Сколько прочитано байт (32-битный адрес 64-битной ячейки).
    0 size                   \ Сколько надо прочитать байт (64-битное число).
    bufMem                   \ Приемный буфер (32-битный адрес).
    bufMem offset + CELL + @ \ Вторая половина 64-битного адреса
    bufMem offset + @        \ Первая половина 64-битного адреса из которого читать.
    hProc                    \ Дескриптор процесса (32-битный).
    NtWow64ReadVirtualMemory64 DUP IF ." Error: NtWow64ReadVirtualMemory64" CR THEN
;

: PROC-CMDLINE ( pid -- a u )
    TO ProcID
    ProcID 9 < IF S" (64)" ProcBIT ZPLACE S" " EXIT THEN   \ Не открывать роцесс бездействия системы и процесс System т.к система безопасности ограничивает доступ к ним.
    ProcID FALSE 0x410 OpenProcess TO hProc
    S" "
    hProc 0= IF ." Error: OpenProcess" CR EXIT THEN

    4096 ALLOCATE THROW TO bufMem

    0 SP@ hProc IsWow64Process DROP IF S" (32)" ELSE S" (64)" THEN ProcBIT ZPLACE \ строка "(32)" или "(64)"

    retLength 48 bufMem 0 hProc NtWow64QueryInformationProcess64 \ Читать PROCESS_BASIC_INFORMATION64
    IF close-free ." Error: NtWow64QueryInformationProcess64" CR EXIT THEN

    40  8  ReadProcMemory64 IF close-free EXIT THEN  \ Читать PEB64
    128 32 ReadProcMemory64 IF close-free EXIT THEN  \ Читать RTL_USER_PROCESS_PARAMETERS64
    PROC-FULLPATH? @
    IF
      bufMem 96  + W@ 104 ReadProcMemory64 IF close-free EXIT THEN \ Читать ImagePathName
    ELSE
      bufMem 112 + W@ 120 ReadProcMemory64 IF close-free EXIT THEN \ Читать CommandLine
    THEN
    2DROP getline
    close-free
;

\ -----------------------------------------
\ Встраивание (делается если ОС 64-битная).
\ -----------------------------------------

: (WalkProc) ( -- )
    S" *" -1 WTS-FOR-PROCS
      PROC-FULLPATH? @
      IF
        WTS-FOUND-PROCESSID PROC-CMDLINE
      ELSE
        WTS-FOUND-PROCESSNAME
      THEN
      WTS-FOUND-PROCESSID xtWalkProc @ EXECUTE 0= WTS-FP-CUT? !
    ;WTS-FOR-PROCS
;

\ Хак: В скомпилированное слово WalkProcNT (spf4-20.rar\devel\~nn\lib\proc.f) вставляется переход на новое слово.
:NONAME ( xt -- ) xtWalkProc ! GetDebugPriv (WalkProc) ;
' WalkProcNT JMP

\ Переопределяем слово PROC-FULLNAME
: PROC-FULLNAME ( pid -- a u)
    PROC-FULLPATH? ON
    PROC-CMDLINE
    PROC-FULLPATH? OFF
;
[THEN]

\ ------------------------------------
\ Для 32-битной ОС.
\ ------------------------------------
OSx32? [IF]
WINAPI: ReadProcessMemory Kernel32.dll

: ReadProcMemory32 { size offset -- }
    retLength         \ Сколько прочитано байт.
    size              \ Сколько надо прочитать байт.
    bufMem            \ Приемный буфер.
    bufMem offset + @ \ Адрес из которого читать.
    hProc             \ Дескриптор процесса.
    ReadProcessMemory 0= DUP IF ." Error: ReadProcessMemory" CR THEN
;

\ Слово может работать и в 64-битной ОС но только для 32-битных процессов.
: PROC-CMDLINE ( pid -- a u )
    TO ProcID  0. ProcBIT 2!
    ProcID 9 < IF S" " EXIT THEN   \ Не открывать роцесс бездействия системы и процесс System т.к система безопасности ограничивает доступ к ним.
    ProcID FALSE 0x410 OpenProcess TO hProc
    S" "
    hProc 0= IF ." Error: OpenProcess" CR EXIT THEN

    4096 ALLOCATE THROW TO bufMem

    0 SP@ hProc IsWow64Process DROP 0= OSx64? AND \ Проверка на случай выполнения слова в 64-битной ОС. 64-битные процесы не читаем.
    IF close-free ." Error: Process x64" CR EXIT THEN

    retLength 24 bufMem 0 hProc NtQueryInformationProcess   \ Читать PROCESS_BASIC_INFORMATION
    IF close-free ." Error: NtQueryInformationProcess" CR EXIT THEN

    20 4  ReadProcMemory32 IF close-free EXIT THEN  \ Читать PEB (вся PEB=472)
    72 16 ReadProcMemory32 IF close-free EXIT THEN  \ Читать RTL_USER_PROCESS_PARAMETERS
    PROC-FULLPATH? @
    IF
      bufMem 56 + W@ 60 ReadProcMemory32 IF close-free EXIT THEN \ Читать ImagePathName
    ELSE
      bufMem 64 + W@ 68 ReadProcMemory32 IF close-free EXIT THEN \ Читать CommandLine
    THEN
    2DROP getline
    close-free
;
[THEN]




\EOF




\ Примеры
#( task_test_proccmdline
\ NoActive
Action:
    FOR-PROCS: "*"
      FOUND-PROC TYPE
      FOUND-PID PROC-FULLNAME ProcBIT ASCIIZ> TYPE SPACE
      FOUND-PID . CR TYPE CR
      FOUND-PID PROC-CMDLINE TYPE CR CR
    ;FOR-PROCS

    0 PROC-NAME TYPE CR
    S" ex*er.exe" PROC-EXIST? PROC-CMDLINE TYPE CR
\    KILL: "hh.exe"
)#

#( task_test_WatchProc
\ NoActive
 WatchProc: "*"
Action:
   WATCH-PROC-ID PROC-NAME TYPE SPACE
   WATCH-PROC-ID Proc64? IF ." (x64)" ELSE ." (x32)" THEN CR
   WATCH-PROC-ID PROC-CMDLINE TYPE CR CR
)#





\ Архив.
\ Первоначальный вариант встраивания.
\ -----------------------------------
OSx64? [IF]
\ ForEachProcess   отсюда: spf4-20.rar\devel\~ac\lib\win\process\enumproc.f
\ Константы объявлены тут: spf4-20.rar\devel\~nn\lib\proc95.f
\ Если есть задачи с WatchProc:, WatchProcStop: т.е. если функция CreateToolhelp32Snapshot выполняется в цикле, то ошибки страниц не прекращаются.
: ForEachProcess2  { xt \ hSnap pe -- }
    0 TH32CS_SNAPPROCESS CreateToolhelp32Snapshot TO hSnap
    hSnap INVALID_HANDLE_VALUE = IF GetLastError THROW THEN
    /PROCESSENTRY32 ALLOCATE THROW TO pe
    /PROCESSENTRY32 pe pe.th32dwSize !
    pe hSnap Process32First 1 =
    IF
      BEGIN
        pe xt EXECUTE 0=
        pe hSnap Process32Next 0= OR
      UNTIL
    THEN
    pe FREE THROW
    hSnap CLOSE-FILE THROW
;

: (WalkProc_) ( addr-PROCESSENTRY32 -- )
    >R
    PROC-FULLPATH? @
    IF
      R@ pe.th32ProcessID @ PROC-CMDLINE
    ELSE
      R@ pe.szExeFile ASCIIZ>
    THEN
    R> pe.th32ProcessID @ xtWalkProc @ EXECUTE
;

\ Хак: В скомпилированное слово WalkProcNT (spf4-20.rar\devel\~nn\lib\proc.f) вставляется переход на новое слово.
:NONAME ( xt -- ) xtWalkProc ! GetDebugPriv ['] (WalkProc_) ForEachProcess2 ;
' WalkProcNT JMP
[THEN]


Last edited by dothen on Mon, 01 May 2017, 05:27, edited 3 times in total.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Плагин ProcCmdLine.spf (командная строка процесса)

Postby dothen » Fri, 14 Apr 2017, 00:15

Кронтаб nncron_process.tab

По хоткею завершает или перезапускает процесс создавший окно которое активно в данный момент.

Code: Select all
# Файл:       nncron_process.tab
# Автор:      dothen
# Дата:       30.04.2017
# Версия:     1.01
# Описание:
# По хоткею завершает или перезапускает процесс создавший окно которое активно в данный момент.

# Подключить плагины proccmdline.spf extwords.spf
# Подключить кронтаб nncron_extwords2.tab (http://www.nncron.ru/forums/viewtopic.php?f=5&t=13361#p35725)

# Горячие клавиши:
# Ctrl+Alt+Shift+Num-   Завершить.
# Ctrl+Alt+Shift+Num/   Перезапустить.

# В слове KILL-RESTART можно добавлять исключения.

# Пишет лог: log\process.log
#---------------------------
# Слова:

# ACTIVE-WIN-PROC-RESTART ( -- )    Перезапускает процесс создавший окно которое активно в данный момент.
# ACTIVE-WIN-PROC-KILL    ( -- )    Завершает процесс создавший окно которое активно в данный момент.
# KILL-RESTART { tree? restart? pid \ a u -- }    Завершает или перезапускает процесс


<%

\ Завершает или перезапускает процесс
: KILL-RESTART { tree? restart? pid \ a1 u1 a2 u2 a3 u3 -- }
    S" Error: PID " >ZPAD pid N>S +ZPAD
    pid PROC-NAME  TO u1 TO a1
    pid PROC-CMDLINE TO u2 TO a2
    pid PROC-FULLNAME  TO u3 TO a3
    u2 0>
    IF
      S" Process: " >ZPAD a1 u1 +ZPAD ProcBIT 4 +ZPAD
      a1 u1
      SCASE
        S" explorer.exe"   ISOF FALSE ENDSOF \ Не убиваем Проводник, Рабочий стол, Панель задач.
        S" nncron.exe"     ISOF FALSE ENDSOF \ ISOF  - Игнорирует регистр.
        S" TOTALCMD*.EXE" WCSOF FALSE ENDSOF \ WCSOF - Поддерживает работу с масками используя символы * и ?
        S" *"             WCSOF TRUE  ENDSOF
      ENDSCASE
      IF
        tree?
        IF SWHide
          S" taskkill.exe /t /f /pid " pid N>S S+ START-APP \ Завершить процесс и его дочерние процесы (дерево процессов).
        ELSE
          pid kill
        THEN
        restart?
        IF
          500 PAUSE
          a3 u3 ONLYDIR START-IN
          0 a2 u2 StartApp DROP
          S"  RESTART"
        ELSE S"  KILL" THEN +ZPAD
        S"    CMDLINE: "    +ZPAD
        a2 u2               +ZPAD
        S"    FULLPATH: "   +ZPAD
        a3 u3               +ZPAD
        TRAY-REFRESH
      THEN
    THEN
    ZPAD> S" log\process.log" LOG
;

: ACTIVE-WIN-PROC-KILL     ( -- ) FALSE FALSE ACTIVE-PROC-PID KILL-RESTART ;
: ACTIVE-WIN-PROC-RESTART  ( -- ) FALSE TRUE  ACTIVE-PROC-PID KILL-RESTART ;
\ : ACTIVE-WIN-PROCTREE-KILL ( -- ) TRUE  FALSE ACTIVE-PROC-PID KILL-RESTART ;


[UNDEFINED] KEY~PRESSED? [IF]
WINAPI: GetAsyncKeyState USER32.DLL

: KEY~PRESSED? ( vk -- ? ) GetAsyncKeyState 0x8000 AND? ;

\ Ждать поднятия кнопки с кодом VK если она нажата.
: WAIT~KUP ( vk -- )
    BEGIN DUP KEY~PRESSED? WHILE
      50 PAUSE
    REPEAT DROP
;
[THEN]


%>


#( CLASSIC-TASK-#-Restart-Process
\ Перезапускает процесс создавший окно которое активно в данный момент.
SingleInstance \ NoActive
WatchHotKey: "^@+{DIVIDE}" \ Ctrl+Alt+Shift+Num/
Action:
    ACTIVE-WIN-PROC-RESTART
    VK_DIVIDE WAIT~KUP
)#

#( CLASSIC-TASK-#-Terminate-Process
\ Завершает процесс создавший окно которое активно в данный момент.
SingleInstance \ NoActive
WatchHotKey: "^@+{SUBTRACT}" \ Ctrl+Alt+Shift+Num-
Action:
    ACTIVE-WIN-PROC-KILL
    VK_SUBTRACT WAIT~KUP
)#


Last edited by dothen on Mon, 01 May 2017, 01:32, edited 2 times in total.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Плагин ProcCmdLine.spf (командная строка процесса)

Postby dothen » Tue, 18 Apr 2017, 19:38

Сделал встраивание с использованием WTS-FOR-PROCS.
Проверял только на Win7 x64.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Плагин ProcCmdLine.spf (командная строка процесса)

Postby dothen » Sun, 30 Apr 2017, 22:06

В кронтабе добавил слово WAIT~KUP т.к. WAIT-KUP не ждет VK_DIVIDE и VK_SUBTRACT, а SingleInstance не действует для сложных хоткеев.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Плагин ProcCmdLine.spf (командная строка процесса)

Postby dothen » Mon, 01 May 2017, 05:20

В плагине увеличил размер буфера bufMem, было 1024 теперь 4096.
nnCron падал когда читал память процесса WUDFHost.exe (в Win7 запускается при подключении USB-устройства).
У этого процесса длина командной строки 530 символов, в юникоде получается больше килобайта.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58


Return to nnCron forum (Russian)

Who is online

Users browsing this forum: Bing [Bot] and 3 guests

cron