![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Параметры коммандной строки чужего процесса [D2, D3, D4, D5, D6, NT4, Win2k, WinXP]
iptower © (2002-08-30 12:47:00)Как узнать параметры коммандной строки чужего процесса под WIN NT
Игорь Шевченко (2002-09-02 18:11:00) [1]paul_shmakov © (02.09.02 17:29)
Большое спасибо!
> const
> PEBAddress = $7FFDF000;
>
> эта константа на всех операционках равна $7FFDF000?
Да. Программа проверялась на WinNT 4.0 (SP6), Win2000 и WinXP
По-хорошему для будущих версий можно использовать функцию
RtlGetCurrentPeb, но я не знаю, на всех ли она NT-платформах поддерживается. В NTDLL.DLL от WinXP - есть.
Кстати, купил книжку Гари Неббета по Native API в Библио-глобусе :-)
С уважением,
paul_shmakov (2002-09-02 17:29:00) [2]
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.
paul_shmakov (2002-09-02 17:28:00) [3]не нашел я у себя системного процесса с окном. но программа работает. мне вот только интересно:
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;
Игорь Шевченко (2002-09-02 15:38:00) [4]paul_shmakov © (02.09.02 15:28)
Если под рукой имеется системный процесс с окном, не очень трудно будет мой способ проверить ? Мне самому интересно :-)
paul_shmakov (2002-09-02 15:28:00) [5]2 Игорь Шевченко:
в моем примере debug привилегии требуются только для получения командной строки системных процессов, о чем я честно написал:
...
// Needed only to obtain command line of system processes
AdjustDebugPriviliges();
...
Игорь Шевченко (2002-09-02 14:51:00) [6]Ученик © (02.09.02 13:53)
Спасибо. У меня в списке окон показываются только те, которые появляются на taskbar. Последняя буква - это я спешил и не проверяю, чем строка заканчивается.
Значит, метод не требует DebugPrivilege :-)
P.S. Со мной можно на "ты"
Ученик (2002-09-02 13:53:00) [7]Игорь Шевченко © (02.09.02 13:27)
С обычной формой в сервисе все работает только последняя буква почему то обрезана
Ученик (2002-09-02 13:37:00) [8]>Игорь Шевченко © (02.09.02 13:27)
Да, я проверил, окно в списке не показывается, думал Вы сами хотите, правда окно ToolWindow
Игорь Шевченко (2002-09-02 13:27:00) [9]Ученик © (02.09.02 13:20)
> Значит, не судьба :-)
А тебе очень трудно проверить ? :-)
Ученик (2002-09-02 13:20:00) [10]>Игорь Шевченко © (02.09.02 13:01)
Значит, не судьба :-)
Игорь Шевченко (2002-09-02 13:01:00) [11]Ученик © (02.09.02 12:28)
Увы, не моя область знаний :-(
Ученик (2002-09-02 12:28:00) [12]File-New-Other-Service Application, Interactive=True, и показ какой-нибудь формы на OnStart
Игорь Шевченко (2002-09-02 12:11:00) [13]Ученик © (02.09.02 11:25)
Вот если у тебя есть пример такого сервиса и тебе не затруднительно проверить мой метод, я был бы очень признателен.
С уважением,
Ученик (2002-09-02 11:25:00) [14]>Игорь Шевченко © (02.09.02 11:10)
Сервисы, они ведь разные :-)
Игорь Шевченко (2002-09-02 11:10:00) [15]Ученик © (02.09.02 11:09)
Они тоже, вроде, окон не создают :-)
Ученик (2002-09-02 11:09:00) [16]>Игорь Шевченко © (02.09.02 11:05)
Имелись ввиду процессы, которые запущены под Local System Account
Игорь Шевченко (2002-09-02 11:05:00) [17]Ученик © (02.09.02 10:48)
Мне надо было определить командную строка для окна. Системные процессы окон, вроде, не создают
Ученик (2002-09-02 10:48:00) [18]>Игорь Шевченко © (02.09.02 10:42)
По-моему беда с системными процессами, в этом случае как раз и требуется DebugPrivilege.
Игорь Шевченко (2002-09-02 10:42:00) [19]В кладовке лежит программа EnumFunctions - там в unit"e main есть функция HSGetWindowCommandLine - несколько другой принцип, не требующий DebugPrivilege. На Delphi :-)
paul_shmakov (2002-09-01 01:58:00) [20]2 Ученик:
спасибо за порт :)