Форум: "Система";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];
ВнизВопрос о процессах и не только... Найти похожие ветки
← →
Alexis © (2004-04-10 19:21) [0]При получении списка процессов(и полных путей к исполняемым файлам) в WinXP при помощи TLHelp32 и psAPI сталкиваюсь с такой проблемой : к некоторым процессам возвращаются такие пути :
?\SystemRoot\System32\smss.exe
\SystemRoot\System32\файл.exe
\??\D:\Windows\System32\winlogon.exe
К остальным процессам пути нормальные.Как из приведенного выше получить нормальные пути.
Подобное затрагивалось
http://delphimaster.net/view/4-1080837801/
но может есть еще варианты ?
И второй вопрос : как точно определить что процесс системный ?(со 100%-ной точностью)
Насколько знаю PID 0, 4 означают системный процесс, но многие другие процессы (например winlogon.exe, smss.exe) работают с другим PID-ом.
Process Explorer(на SysInternals.com) как-то определяет, кто разработчик программы (к процессам из директории Windows прописывает Microsoft Corporation.)
С помощью каких ф-ций это узнается? Нужны ли Debug привилегии?
← →
BiN © (2004-04-10 19:37) [1]как точно определить что процесс системный
- по имени пользователя процесса
см. http://delphimaster.net/view/4-1080837801/
Process Explorer(на SysInternals.com) как-то определяет, кто разработчик программы (к процессам из директории Windows прописывает Microsoft Corporation.)
С помощью каких ф-ций это узнается?
GetFileVersionInfo и иже с ним.
Нужны ли Debug привилегии?
нет
← →
Cobalt © (2004-04-10 19:40) [2]Имя разработчика берётся из ресурсов.
Признак системности - по-моему - по id пользователя (Видели, наверное - User Name = "NT AUTHORITY/SYSTEM")
← →
Alexis © (2004-04-10 19:49) [3]
> Признак системности - по-моему - по id пользователя (Видели,
> наверное - User Name = "NT AUTHORITY/SYSTEM")
Не видел. Можно поподробнее?
← →
Игорь Шевченко © (2004-04-10 21:12) [4]
> Признак системности - по-моему - по id пользователя
OpenProcessToken + GetTokenInformation
← →
Alexis © (2004-04-13 13:48) [5]2 Игорь Шевченко-спасибо, я узнал из ссылки [1].
Попытался написать код с использованием этих ф-ций:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
TLHelp32,
psAPI;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
ListBox3: TListBox;
Button3: TButton;
ListBox4: TListBox;
procedure Button3Click(Sender: TObject);
private
public
{ Public declarations }
end;
type SID_AND_ATTRIBUTES = record
Sid: Pointer;
Attributes:DWORD ;
end;
type TOKEN_USER = record
SID_AND_ATTRIBUTES: DWORD;
end;
var
Form1: TForm1;
activePIDS : TList;
TU: TOKEN_USER;
implementation
{$R *.dfm}
procedure TForm1.Button3Click(Sender: TObject);
var
snapshot : Cardinal;
procInfo : PROCESSENTRY32;
procInfoW : PROCESSENTRY32W;
procHandle, hMod : THandle;
BytesReturned : Cardinal;
pathsize : Cardinal;
j,k : integer;
pathname : array [0..1000] of char;
buff, buff2:string;
cp:Cardinal;
PID, size : DWORD;
TokenHandle : THandle;
begin
ListBox1.Clear;
ListBox2.Clear;
ListBox4.Clear;
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
procInfo.dwSize := sizeof(procInfo);
if Process32First(snapshot, procInfo) then
repeat
ListBox1.Items.Add(strpas(procInfo.szExeFile) + " ID: " + inttostr(procInfo.th32ProcessID));
procHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, procInfo.th32ProcessID);
if procHandle<>0 then
begin
OpenProcessToken(procHandle, TOKEN_QUERY, TokenHandle);
size := sizeof(TOKEN_USER);
if GetTokenInformation(TokenHandle, TokenUser,@TU,SizeOf(TOKEN_USER),Size) then
ListBox4.Items.Add("information was successfully retrieved")
else
ListBox4.Items.Add("Error:"+IntToStr(GetLastError));
EnumProcessModules(procHandle, @hmod, sizeof(THandle), BytesReturned);
GetModuleFileNameEx(procHandle, hmod, pathname, sizeof(pathname));
ListBox2.Items.Add( strpas(pathname) );
end
else
ListBox2.Items.Add("-system process-");
closeHandle(procHandle);
until not Process32Next(snapshot, procInfo);
end;
end.
На что мне в ListBox4 ко всем процессам, к которым удалось получить handle прописывается Error 122.
Что не так я делаю?
Кстати, есть ли какая-нибудь предопределенная константа, идентифицирующая системный процесс, типа SYSTEM_PROCESS ?
← →
VMcL © (2004-04-13 14:06) [6]{ The data area passed to a system call is too small. }
ERROR_INSUFFICIENT_BUFFER = 122; { dderror }
← →
Alexis © (2004-04-13 14:09) [7]Ага, вот оно что.
Ну а что насчет предопределенной константы?
← →
VMcL © (2004-04-13 14:37) [8]>>Alexis © (13.04.04 13:48) [5]
Используй лучше RaiseLastOSError, а не просто отображение номера ошибки.
← →
Игорь Шевченко © (2004-04-13 14:46) [9]
type
ZString = array[0..1024] of char;
function SIDToName (const SID: PSID): string;
var
Use : SID_NAME_USE;
DomainName : ZString;
DomainNameLength : DWORD;
Name : ZString;
NameLength : DWORD;
begin
if not LookupAccountSid(nil, SID, Name, NameLength, DomainName,
DomainNameLength, Use) then
RaiseLastWin32Error;
Result := Name;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
AccessToken : THandle;
Info : PSIDANDATTRIBUTES;
ReturnLength : DWORD;
begin
Win32Check(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, AccessToken));
GetMem (Info, 1024);
try
Win32Check(GetTokenInformation(AccessToken, TokenUser, Info, 1024,
ReturnLength));
ShowMessage(SidToName(Info^.Sid));
finally
FreeMem(Info);
end;
end;
end.
Может, поможет...
← →
AndersoNRules © (2004-04-14 16:13) [10]Otkuda vi vseo ato znayete?
← →
Alexis © (2004-04-18 11:49) [11]2 Игорь Шевченко - спасибо, это работает, но ко всем процессам возвращается имя залогиневшегося на данный момент пользователя.
Я попробовал изменить
GetTokenInformation(AccessToken, TokenUser, Info, 1024, ResultLength)
на
GetTokenInformation(AccessToken, TokenOwner, Info, 1024, ResultLength)
но это к нужному мне результату не привело.
Есть ли какой-то предопределенный макрос типа OWNER_SYSTEM?
Как же все таки определить кому принадлежит процесс?
С какими параметрами вызывать GetTokenInformation?
← →
Игорь Шевченко © (2004-04-19 11:13) [12]
> но ко всем процессам возвращается имя залогиневшегося на
> данный момент пользователя.
Не ко всем...
← →
Alexis © (2004-04-19 11:59) [13]Eto jasno, cto ne ko vsem, a tolko k tem, k kotorym udalos polucit Handle.
No mne na vopros kto nibud mozet otvetit ili nikto ne znaet?
← →
Игорь Шевченко © (2004-04-19 12:28) [14]
> a tolko k tem, k kotorym udalos polucit Handle.
Для того, чтобы можно было открыть другие процессы, необходимо разрешить привилегию SeDebugName
← →
Alexis © (2004-04-19 14:12) [15]2 Игорь Шевченко-ведь я спрашиваю не о том, как открыть все процессы, а то как определить системность процесса.
Т.е. как определить системность процесса, к которому удалось получить Handle ?
(см. оригинальный вопрос)
← →
Игорь Шевченко © (2004-04-19 15:35) [16]
> как точно определить что процесс системный ?(
OpenProcess + OpenProcessToken + GetTokenInformation
← →
Игорь Шевченко © (2004-04-19 15:37) [17]Небольшой пример:
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
NtProcessInfo, ComCtrls;
type
TfMain = class(TForm)
ListView: TListView;
procedure FormCreate(Sender: TObject);
private
FProcessList: THSNtProcessInfoList;
procedure RefreshProcessList;
procedure LookupProcessOwner(AProcess: THSNtProcessInfo);
procedure DisplayProcess(AProcess: THSNtProcessInfo;
const UserName: string);
end;
var
fMain: TfMain;
implementation
uses
NtDll, HsNtDef, HsWinUtils;
{$R *.DFM}
type
ZString = array[0..1024] of char;
function SIDToName (const SID: PSID): string;
var
Use : SID_NAME_USE;
DomainName : ZString;
DomainNameLength : DWORD;
Name : ZString;
NameLength : DWORD;
begin
if not LookupAccountSid(nil, SID, Name, NameLength, DomainName,
DomainNameLength, Use) then
Result := "***"
else
Result := Name;
end;
procedure TfMain.RefreshProcessList;
var
Processes : Pointer;
rc : NTSTATUS;
Dummy: ULONG;
I: Integer;
begin
FProcessList.Free;
Processes := QueryListInformation(SystemProcessesAndThreadsInformation, rc,
Dummy);
if NT_SUCCESS(rc) then begin
FProcessList := THSNtProcessInfoList.Create(Processes);
for I:=0 to Pred(FProcessList.Count) do
if FProcessList[I].Info.ProcessId <> 0 then
LookupProcessOwner(FProcessList[I]);
end;
end;
procedure TfMain.FormCreate(Sender: TObject);
begin
if not HSEnablePrivilege(SE_DEBUG_NAME) then
raise Exception.CreateFmt("Can""t set debug privilege due to %s",
[SysErrorMessage(GetLastError)]);
RefreshProcessList;
end;
procedure TfMain.LookupProcessOwner(AProcess: THSNtProcessInfo);
var
AccessToken : THandle;
Info : PSIDANDATTRIBUTES;
ReturnLength : DWORD;
ProcessHandle: THandle;
UserName: string;
begin
ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, false,
AProcess.Info.ProcessId);
if ProcessHandle = 0 then
Exit;
try
if not OpenProcessToken(ProcessHandle, TOKEN_QUERY, AccessToken) then
Exit;
GetMem (Info, 4096);
try
Win32Check(GetTokenInformation(AccessToken, TokenUser, Info, 1024,
ReturnLength));
UserName := SidToName(Info^.Sid);
finally
FreeMem(Info);
end;
finally
CloseHandle(ProcessHandle);
end;
DisplayProcess(AProcess, UserName);
end;
procedure TfMain.DisplayProcess(AProcess: THSNtProcessInfo;
const UserName: string);
begin
with ListView.Items.Add do begin
Caption := AProcess.ProcessName;
SubItems.Add(UserName);
end;
end;
end.
← →
Игорь Шевченко © (2004-04-19 15:46) [18]Небольшое исправление:
try
Win32Check(GetTokenInformation(AccessToken, TokenUser, Info, 4096,
ReturnLength));
UserName := SidToName(Info^.Sid);
finally
FreeMem(Info);
CloseHandle(AccessToken);
end;
Недостающие unit"ы можно взять с
http://www.schevchenko.net.ru/SRC/Common_60.zip
и
http://www.schevchenko.net.ru/SRC/QuerySystemInformation_60.zip
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.035 c