Чтение аргументов командной строки другого процесса (код Win32 C)

Мне нужно иметь возможность перечислить аргументы командной строки (если есть), переданные другим запущенным процессам. У меня уже есть PID запущенных процессов в системе, поэтому в основном мне нужно определить аргументы, переданные процессу с заданным PID XXX.

Я работаю над основной частью Модуль Python для управления процессами. Код написан как расширение Python на C и будет обернут библиотекой Python более высокого уровня. Цель этого проекта - избежать зависимости от сторонних библиотек, таких как расширения pywin32, или от уродливых хаков, таких как вызов «ps» или taskkill в командной строке, поэтому я ищу способ сделать это в коде C.

Я погуглил это и нашел несколько кратких предложений по использованию CreateRemoteThread (), чтобы внедрить себя в другой процесс, а затем запустить GetCommandLine (), но я надеялся, что у кого-то могут быть некоторые рабочие образцы кода и / или лучшие предложения.

ОБНОВИТЬ: Я нашел полный рабочий демонстрационный код и решение, использующее NtQueryProcessInformation в CodeProject: http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx - Это не идеально, поскольку «не поддерживается» для отбраковки информации непосредственно из структур NTDLL, но я буду жить с этим. Спасибо всем за предложения.

ОБНОВЛЕНИЕ 2: Мне удалось через больше поисков в Google найти версию C, которая не использует код C++ и немного более прямо / лаконично указывает на эту проблему. Подробнее см. http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/.

Спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
9
0
13 489
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Если вы не являетесь родителем этих процессов, то это невозможно с использованием документированных функций :( Теперь, если вы родитель, вы можете выполнить свой трюк CreateRemoteThread, но в противном случае вы почти наверняка получите отказ в доступе, если ваше приложение не имеет права администратора.

Теперь у меня есть код в модуле, который получит права SeDebug, если это возможно, поэтому, если они являются пользователем Admin, у нас должны быть необходимые привилегии, верно?

Jay 14.01.2009 00:56

Кешированное решение: http://74.125.45.132/search?q=cache:-wPkE2PbsGwJ:windowsxp.mvps.org/listproc.htm+running+process+command+line&hl=es&ct=clnk&cd=1&gl=ar&client=firefox-a

in CMD
WMIC /OUTPUT:C:\ProcessList.txt PROCESS get Caption,Commandline,Processid

or

WMIC /OUTPUT:C:\ProcessList.txt path win32_process get Caption,Processid,Commandline

Также: http://mail.python.org/pipermail/python-win32/2007-De December/006498.html

http://tgolden.sc.sabren.com/python/wmi_cookbook.html#running_processes 
seems to do the trick:

import wmi
c = wmi.WMI ()
for process in c.Win32_Process ():
  print process.CommandLine

Спасибо за предложения, однако я бы предпочел не вызывать внешние процессы. Упомянутый модуль wmi также требует другого стороннего модуля поверх расширений pywin32, которые мы также не хотим требовать от пользователя.

Jay 14.01.2009 00:58

Вы можете вызвать WMI из C через его COM-интерфейс, хотя это не самый элегантный код.

Rob Walker 14.01.2009 01:00

@Rob - это правда ... это было бы серьезными накладными расходами для этой, казалось бы, простой задачи, но похоже, что у меня не так много вариантов.

Jay 14.01.2009 01:10

Подход WMI, упомянутый в другом ответе, вероятно, является наиболее подходящим способом надежный для этого. Просматривая MSDN, я обнаружил, что похоже на другой возможный подход; он задокументирован, но неясно, полностью ли он поддерживается. На языке MSDN это -

may be altered or unavailable in future versions of Windows...

В любом случае, при условии, что у вашего процесса есть необходимые разрешения, вы должны иметь возможность вызывать NtQueryProcessInformation с ProcessInformationClass из ProcessBasicInformation. В возвращенной структуре PROCESS_BASIC_INFORMATION вы должны получить обратно указатель на блок выполнения процесса целевого процесса (как поле PebBaseAddress). Поле ProcessParameters PEB даст вам указатель на структуру RTL_USER_PROCESS_PARAMETERS. Поле CommandLine этой структуры будет структурой UNICODE_STRING. (Будьте осторожны, не делайте слишком много предположений о строке; нет никаких гарантий, что она будет завершена NULL, и неясно, нужно ли вам удалять имя исполняемого приложения с начала командная строка.)

Я не пробовал этот подход - и, как я уже упоминал выше, он кажется немного ... сомнительным (читай: непереносимым) - но, возможно, стоит попробовать. Удачи...

Я видел это и чувствовал то же самое, что и вы - это казалось шатким, но демонстрация CodeProject, которую я обнаружил, отлично работает даже в Vista, поэтому я все равно буду использовать это. См. Ссылку CodeProject для рабочего кода.

Jay 15.01.2009 21:35
Ответ принят как подходящий

Чтобы ответить на свой вопрос, я наконец нашел решение CodeProject, которое делает именно то, что я ищу:

http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx

Как уже указывал @Reuben, вы можете использовать NtQueryProcessInformation для получения этой информации. К сожалению, это не рекомендуемый подход, но, учитывая, что единственное другое решение, похоже, связано с накладными расходами на запрос WMI, я думаю, что мы сейчас воспользуемся этим подходом.

Обратите внимание, что это, похоже, не работает при использовании кода, скомпилированного из 32-битной Windows на 64-битной ОС Windows, но поскольку наши модули скомпилированы из источника на целевой машине, это должно быть в порядке для наших целей. Я бы предпочел использовать этот существующий код, и если он выйдет из строя в Windows 7 или более поздних версиях, мы можем снова взглянуть на использование WMI. Спасибо за ответы!

ОБНОВИТЬ: Здесь проиллюстрирована более краткая и только C (в отличие от C++) версия той же техники:

http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/

Используя psutil (https://github.com/giampaolo/psutil):

>>> import psutil, os
>>> psutil.Process(os.getpid()).cmdline()
['C:\\Python26\\python.exe', '-O']
>>> 

Другие вопросы по теме