Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2002.10.17;
Скачать: [xml.tar.bz2];

Вниз

Параметры коммандной строки чужего процесса   Найти похожие ветки 

 
iptower   (2002-08-30 12:47) [0]

Как узнать параметры коммандной строки чужего процесса под WIN NT


 
Игорь Шевченко   (2002-08-30 14:05) [1]

It"s top secret :-)

www.sysinternals.com - Process Explorer


 
paul_shmakov   (2002-08-30 18:56) [2]

а если самостоятельно программно, то вот я набросал пример (сорри, что на C):

//
// rcmdline.cpp
// Get process command line NT/W2K/XP
// Paul Shmakov
//
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

BOOL GetProcessCommandLine(DWORD dwProcessID, LPTSTR szBuffer, DWORD cbBuffer)
{
BOOL bRes = FALSE;

HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_READ | PROCESS_VM_OPERATION,
/*PROCESS_ALL_ACCESS,*/ FALSE, dwProcessID);

if(hProcess)
{
#ifndef UNICODE
#define GETCOMMANDLINE "GetCommandLineA"
#else
#define GETCOMMANDLINE "GetCommandLineW"
#endif // UNICODE

LPVOID pGetCommandLine = GetProcAddress(GetModuleHandle(_T("kernel32.dll")),
GETCOMMANDLINE);

if(pGetCommandLine)
{
DWORD dwTID;

HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pGetCommandLine, 0, 0, &dwTID);

if(hThread)
{
if(WAIT_OBJECT_0 == WaitForSingleObject(hThread, 10000))
{
LPCSTR pCommandLine = 0;
if(GetExitCodeThread(hThread, (LPDWORD)&pCommandLine))
{
DWORD dwRead;
if(ReadProcessMemory(hProcess, pCommandLine, szBuffer,
cbBuffer, &dwRead))
{
szBuffer[dwRead] = 0;
bRes = TRUE;
}
}
}

CloseHandle(hThread);
}
}

CloseHandle(hProcess);
}

return bRes;
}

BOOL AdjustDebugPriviliges(void)
{
BOOL bRes = FALSE;

HANDLE hTok;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hTok))
{
LUID luid;
TOKEN_PRIVILEGES tp;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bRes = AdjustTokenPrivileges(hTok, FALSE, &tp, NULL, NULL, NULL);

CloseHandle(hTok);
}

return bRes;
}

int _tmain(int argc, char* argv[])
{
if(argc > 1)
{
DWORD dwPID = atoi(argv[1]);
char szCmdLine[1000];

// Needed only to obtain command line of system processes
AdjustDebugPriviliges();

if(GetProcessCommandLine(dwPID, szCmdLine, sizeof(szCmdLine) / sizeof(szCmdLine[0])))
{
printf("Process %d command line: %s\n", dwPID, szCmdLine);
}
else
printf("Failed to obtain command line of process %d\n", dwPID);
}
else
printf("Usage: rcmdline <pid>\n");

return 0;
}

работать будет только под nt/2k/xp, т.к. использует CreateRemoteThread. если нужно решение для всех версий, то без dll дополнительной не обойтись.
пишите dll, которая во время своей инициализации вызывает GetCommandLine и выводит его куда-нибудь или в вызывающий процесс передает.
из своего процесса внедряете эту dll в чужой процесс тем или иным способом.


 
Ученик   (2002-08-30 19:31) [3]

Вариант в Delphi

function AdjustDebugPriviliges : Bool;
var
hTok : THandle;
tp : TTokenPrivileges;
begin
Result := False;
if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hTok) then try
if LookupPrivilegeValue(nil, "SeDebugPrivilege", tp.Privileges[0].Luid) then begin
tp.PrivilegeCount := 1;
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
Result := AdjustTokenPrivileges(hTok, False, tp, 0, PTokenPrivileges(nil)^, PDWord(nil)^)
end
finally
CloseHandle(hTok)
end
end;

function GetProcessCommandLine(dwProcessID : DWord; szBuffer : PChar; cbBuffer : DWORD) : Bool;
var
hProcess, hThread : THandle;
pGetCommandLine : Pointer;
pCommandLine : PChar;
dwRead, dwTID : DWord;
begin
Result := FALSE;
hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_READ or PROCESS_VM_OPERATION,
FALSE, dwProcessID);
if (hProcess <> 0) then try
pGetCommandLine := GetProcAddress(GetModuleHandle("kernel32.dll"), "GetCommandLineA");
if (pGetCommandLine <> nil) then begin
hThread := CreateRemoteThread(hProcess, NIL, 0, pGetCommandLine, nil, 0, dwTID);
if (hThread <> 0) then try
if WAIT_OBJECT_0 = WaitForSingleObject(hThread, 10000) then begin
if GetExitCodeThread(hThread, PDWord(@pCommandLine)^) then begin
if ReadProcessMemory(hProcess, pCommandLine, szBuffer, cbBuffer, dwRead) then begin
szBuffer[dwRead] := #0;
Result := TRUE
end
end
end
finally
CloseHandle(hThread)
end
end
finally
CloseHandle(hProcess)
end
end;

procedure TForm1.Button1Click(Sender: TObject);
var
szBuffer : array[0..255] of Char;
begin
AdjustDebugPriviliges;
if GetProcessCommandLine(StrToInt(Edit1.Text), szBuffer, 255) then
ShowMessage(szBuffer)
end;


 
paul_shmakov   (2002-09-01 01:58) [4]

2 Ученик:
спасибо за порт :)


 
Игорь Шевченко   (2002-09-02 10:42) [5]

В кладовке лежит программа EnumFunctions - там в unit"e main есть функция HSGetWindowCommandLine - несколько другой принцип, не требующий DebugPrivilege. На Delphi :-)


 
Ученик   (2002-09-02 10:48) [6]

>Игорь Шевченко © (02.09.02 10:42)
По-моему беда с системными процессами, в этом случае как раз и требуется DebugPrivilege.


 
Игорь Шевченко   (2002-09-02 11:05) [7]

Ученик © (02.09.02 10:48)

Мне надо было определить командную строка для окна. Системные процессы окон, вроде, не создают


 
Ученик   (2002-09-02 11:09) [8]

>Игорь Шевченко © (02.09.02 11:05)
Имелись ввиду процессы, которые запущены под Local System Account


 
Игорь Шевченко   (2002-09-02 11:10) [9]

Ученик © (02.09.02 11:09)

Они тоже, вроде, окон не создают :-)


 
Ученик   (2002-09-02 11:25) [10]

>Игорь Шевченко © (02.09.02 11:10)
Сервисы, они ведь разные :-)


 
Игорь Шевченко   (2002-09-02 12:11) [11]

Ученик © (02.09.02 11:25)

Вот если у тебя есть пример такого сервиса и тебе не затруднительно проверить мой метод, я был бы очень признателен.

С уважением,


 
Ученик   (2002-09-02 12:28) [12]

File-New-Other-Service Application, Interactive=True, и показ какой-нибудь формы на OnStart


 
Игорь Шевченко   (2002-09-02 13:01) [13]

Ученик © (02.09.02 12:28)

Увы, не моя область знаний :-(


 
Ученик   (2002-09-02 13:20) [14]

>Игорь Шевченко © (02.09.02 13:01)
Значит, не судьба :-)


 
Игорь Шевченко   (2002-09-02 13:27) [15]

Ученик © (02.09.02 13:20)

> Значит, не судьба :-)


А тебе очень трудно проверить ? :-)


 
Ученик   (2002-09-02 13:37) [16]

>Игорь Шевченко © (02.09.02 13:27)
Да, я проверил, окно в списке не показывается, думал Вы сами хотите, правда окно ToolWindow


 
Ученик   (2002-09-02 13:53) [17]

Игорь Шевченко © (02.09.02 13:27)
С обычной формой в сервисе все работает только последняя буква почему то обрезана


 
Игорь Шевченко   (2002-09-02 14:51) [18]

Ученик © (02.09.02 13:53)

Спасибо. У меня в списке окон показываются только те, которые появляются на taskbar. Последняя буква - это я спешил и не проверяю, чем строка заканчивается.
Значит, метод не требует DebugPrivilege :-)

P.S. Со мной можно на "ты"


 
paul_shmakov   (2002-09-02 15:28) [19]

2 Игорь Шевченко:
в моем примере debug привилегии требуются только для получения командной строки системных процессов, о чем я честно написал:

...
// Needed only to obtain command line of system processes
AdjustDebugPriviliges();
...


 
Игорь Шевченко   (2002-09-02 15:38) [20]

paul_shmakov © (02.09.02 15:28)

Если под рукой имеется системный процесс с окном, не очень трудно будет мой способ проверить ? Мне самому интересно :-)


 
paul_shmakov   (2002-09-02 17:28) [21]

не нашел я у себя системного процесса с окном. но программа работает. мне вот только интересно:

const
PEBAddress = $7FFDF000;

эта константа на всех операционках равна $7FFDF000?

я достал эту функцию из примера, сунул ее в тестовое консольное приложение. работает! этот способ действительно лучше, т.к. требует меньше привилегий - в OpenProcess требуется только PROCESS_VM_READ, а у меня еще и PROCESS_CREATE_THREAD, PROCESS_VM_OPERATION.
хотя для процесса csrss.exe все равно потребовались debug priviliges.

вот этот тестовый пример (test.dpr):

// (c) Игорь Шевченко
program test;

{$APPTYPE CONSOLE}

uses
Windows, Messages, SysUtils;

type
{ Структура UNICODE_STRING - Передача строковых параметров для Native API и
хранение строк во внутренних структурах Windows }
TUNICODE_STRING = packed record
Length : WORD;
MaximumLength : WORD;
Buffer : PWideChar;
end;

{ Переопределение типов }
UChar = Byte;
Ptr32 = Pointer;
Uint4B = Cardinal;
{ Текущий каталог }
type
TCURDIR = packed record
DosPath : TUNICODE_STRING;
Handle : Ptr32;
end;
{ User Process Parameters - пользовательские параметры процесса }
type
TRTL_USER_PROCESS_PARAMETERS = packed record
MaximumLength : Uint4B;
Length : Uint4B;
Flags : Uint4B;
DebugFlags : Uint4B;
ConsoleHandle : Ptr32;
ConsoleFlags : Uint4B;
StandardInput : Ptr32;
StandardOutput : Ptr32;
StandardError : Ptr32;
CurrentDirectory : TCURDIR;
DllPath : TUNICODE_STRING;
ImagePathName : TUNICODE_STRING;
CommandLine : TUNICODE_STRING;
Environment : Ptr32;
StartingX : Uint4B;
StartingY : Uint4B;
CountX : Uint4B;
CountY : Uint4B;
CountCharsX : Uint4B;
CountCharsY : Uint4B;
FillAttribute : Uint4B;
WindowFlags : Uint4B;
ShowWindowFlags : Uint4B;
WindowTitle : TUNICODE_STRING;
DesktopInfo : TUNICODE_STRING;
ShellInfo : TUNICODE_STRING;
RuntimeData : TUNICODE_STRING;
// +0x090 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR
end;

PRTL_USER_PROCESS_PARAMETERS = ^TRTL_USER_PROCESS_PARAMETERS;

{ Process Environment Block - блок окружения процесса }
type
TPEB = packed record
InheritedAddressSpace : UChar;
ReadImageFileExecOptions : UChar;
BeingDebugged : UChar;
SpareBool : UChar;
Mutant : Ptr32;
ImageBaseAddress : Ptr32;
Ldr : Ptr32; { _PEB_LDR_DATA }
ProcessParameters : PRTL_USER_PROCESS_PARAMETERS { _RTL_USER_PROCESS_PARAMETERS };
SubSystemData : Ptr32;
ProcessHeap : Ptr32;
{ Остальные данные опущены }
end;

PPEB = ^TPEB;



 
paul_shmakov   (2002-09-02 17:29) [22]


function HSGetWindowCommandLine (AProcessID : DWORD) : String;
const
PEBAddress = $7FFDF000;
var
AProcessHandle : THandle;
ATargetProcessParametersPointer : Ptr32;
ATargetProcessParameters : TRTL_USER_PROCESS_PARAMETERS;
ATargetCommandLine : array[0..MAX_PATH] of WideChar;
AReturned : DWORD;
APathBytes : WORD;
begin
Result := "";
{ Алгоритм пригоден только для NT-платформ }
if true {HSQuerySystemInfo(hsiNTPlatform)} then begin
{ handle этого процесса }
AProcessHandle := OpenProcess(PROCESS_VM_READ, false, AProcessID);
if AProcessHandle = 0 then
RaiseLastWin32Error();
try
{ Получение адреса структуры параметров процесса }
if NOT ReadProcessMemory(AProcessHandle,
{ Этот оператор нужен для подсчета смещения в блоке
PEB на указатель на параметры процесса }
@PPEB(PEBAddress)^.ProcessParameters,
@ATargetProcessParametersPointer, SizeOf(Ptr32),
AReturned) then
RaiseLastWin32Error();
{ Проверка избыточна, но вставлена для пущей надежности. }
if AReturned <> SizeOf(Pointer) then
raise Exception.CreateFmt(
"ReadProcessMemory прочитала неверное количество данных, ожидалось %d, получено %d",
[SizeOf(Ptr32), AReturned]);
{ Получение структуры параметров процесса }
if NOT ReadProcessMemory(AProcessHandle, ATargetProcessParametersPointer,
@ATargetProcessParameters,
SizeOf(ATargetProcessParameters),
AReturned) then
RaiseLastWin32Error();
{ Проверка избыточна, но вставлена для пущей надежности. }
if AReturned <> SizeOf(ATargetProcessParameters) then
raise Exception.CreateFmt(
"ReadProcessMemory прочитала неверное количество данных, ожидалось %d, получено %d",
[SizeOf(ATargetProcessParameters), AReturned]);
{ размер командной строки в байтах }
APathBytes := ATargetProcessParameters.CommandLine.Length;
if APathBytes > MAX_PATH * SizeOf(WideChar) then
APathBytes := MAX_PATH * SizeOf(WideChar);
{ Получение командной строки для указанного процесса }
if NOT ReadProcessMemory(AProcessHandle,
ATargetProcessParameters.CommandLine.Buffer,
@ATargetCommandLine,
APathBytes,
AReturned) then
RaiseLastWin32Error();
{ Для преобразования в Ansi подсчитывается число символов Unicode без
завершающего нуля. lstrlenW почему-то дала неверный результат. Странно.}
Result := WideCharLenToString(ATargetCommandLine,
Pred(AReturned DIV SizeOf(WideChar)));
finally
CloseHandle(AProcessHandle);
end;
end;
end;

function SetDebugPriv: Boolean;
var
Token: THandle;
tkp: TTokenPrivileges;
begin
Result := false;
if OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
begin
if LookupPrivilegeValue(nil, PChar("SeDebugPrivilege"), tkp.Privileges[0].Luid) then
begin
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
Result := AdjustTokenPrivileges(Token, false, tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);
end;
end;
end;

var
ProcessID: DWORD;
begin
// Убирите комментарий для процесса crcss.exe
// SetDebugPriv;
// Введите id процесса
ProcessID := ????;
WriteLn(HSGetWindowCommandLine(ProcessID));
end.


 
Игорь Шевченко   (2002-09-02 18:11) [23]

paul_shmakov © (02.09.02 17:29)

Большое спасибо!



> const
> PEBAddress = $7FFDF000;
>
> эта константа на всех операционках равна $7FFDF000?


Да. Программа проверялась на WinNT 4.0 (SP6), Win2000 и WinXP
По-хорошему для будущих версий можно использовать функцию
RtlGetCurrentPeb, но я не знаю, на всех ли она NT-платформах поддерживается. В NTDLL.DLL от WinXP - есть.

Кстати, купил книжку Гари Неббета по Native API в Библио-глобусе :-)

С уважением,



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2002.10.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.008 c
6-56252
karbo
2002-08-13 23:29
2002.10.17
Где хранится Hardware Address ?


1-56031
Эльф
2002-10-08 08:44
2002.10.17
Меню в стиле OfficeXP


3-55991
zks
2002-09-23 12:52
2002.10.17
ADO + MSSQL + D6


1-56100
Gregory
2002-10-08 20:14
2002.10.17
Как в WebBrowser открыть HTML документ из памяти (переменной)


3-55979
ec
2002-09-23 15:19
2002.10.17
Как убрать окошко с паролем в Table ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский