-
По какой причине ZwQuerySystemInformation выводит не верную (на мой взгляд) информацию о потоках? Так вот описываю структуры :
PClientID = ^TClientID;
TClientID = packed record
UniqueProcess:cardinal;
UniqueThread:cardinal;
end;
PSYSTEM_THREADS = ^SYSTEM_THREADS;
SYSTEM_THREADS = packed record
KernelTime,
UserTime,
CreateTime: LARGE_INTEGER;
WaitTime: dword;
StartAddress: pointer;
ClientId: TClientId;
Priority,
BasePriority,
ContextSwitchCount: dword;
State: dword;
WaitReason: dword;
end;
-
Всмысле возвращает, а не выводит. Речь идет, напрмер, о идентификаторе.
-
> не верную (на мой взгляд) информацию
Полагаешь, что о твоём взгляде мы должны догадаться ?
-
Я имею ввиду, что получаю не верные данные, потому что, наверное, не правильно их обрабатываю. В таком случае подскажите пожалуйста как вывести все ИД потоков процесса, например. Мой код - for i:=1 to Data^.ThreadCount do
ShowMessage(IntToStr(Data^.Threads[i].ClientId.UniqueThread));
-
У тебя тут Data неверная, да к тому-же непонятно как полученная. Можно что-то более понятное посмотреть?
-
begin
DSize := $4000;
repeat
DPtr := VirtualAlloc(nil, DSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
if DPtr = nil then
Exit;
DStat := ZwQuerySystemInformation(5, DPtr, DSize, nil);
if DStat = STATUS_INFO_LENGTH_MISMATCH then
begin
VirtualFree(DPtr, 0, MEM_RELEASE);
DSize := DSize * 2;
end;
until DStat <> STATUS_INFO_LENGTH_MISMATCH;
if DStat = STATUS_SUCCESS then begin
Data := DPtr;
repeat
if PChar(WideCharToString(Data^.ProcessName.Buffer))='procexp.exe' then
for i := 1 to Data^.ThreadCount do
Writeln(IntToStr(Data^.Threads[i].ClientId.UniqueThread));
Data := Pointer(DWord(Data) + Data^.NextEntryDelta);
until Data^.NextEntryDelta = 0;
end;
VirtualFree(DPtr, 0, MEM_RELEASE);
end;
-
На SystemProcessInformation динамический релок памяти избыточен. При коде STATUS_INFO_LENGTH_MISMATCH она сама вернет нужный размер необходимой памяти. Посмотри вот этот пример, он достаточно хорошо показывает работу с потоками приложения: http://rouse.drkb.ru/winapi.php#pmm
-
Как можно идентифицировать статические потоки в процессе?
-
> Как можно идентифицировать статические потоки в процессе?
Ну я же тебе код дал, смотри процедуру FillThreadsInfo
-
> статические потоки
Эт что еще за зверь ?
-
Я имею ввиду, например, StartAddress. Он статический для каждого потока (я ошибаюсь?). В твоем коде я не увидел получения этой информации о потоке.
-
> Я имею ввиду, например, StartAddress
Он просто не выводится, но доступен в FillProcessList. на тебе демокод, раз уж настолько лениво самому разбираться. program ThreadList2;
uses
Windows,
SysUtils;
type
PSYSTEM_THREADS = ^SYSTEM_THREADS;
SYSTEM_THREADS = record
KernelTime: LARGE_INTEGER;
UserTime: LARGE_INTEGER;
CreateTime: LARGE_INTEGER;
WaitTime: ULONG;
StartAddress: Pointer;
UniqueProcess: DWORD;
UniqueThread: DWORD;
Priority: Integer;
BasePriority: Integer;
ContextSwitchCount: ULONG;
State: Longint;
WaitReason: Longint;
end;
PSYSTEM_PROCESS_INFORMATION = ^SYSTEM_PROCESS_INFORMATION;
SYSTEM_PROCESS_INFORMATION = packed record
NextOffset: ULONG;
ThreadCount: ULONG;
Reserved1: array [0..5] of ULONG;
CreateTime: FILETIME;
UserTime: FILETIME;
KernelTime: FILETIME;
ModuleNameLength: WORD;
ModuleNameMaxLength: WORD;
ModuleName: PWideChar;
BasePriority: ULONG;
ProcessID: ULONG;
InheritedFromUniqueProcessID: ULONG;
HandleCount: ULONG;
Reserved2 : array[0..1] of ULONG;
PeakVirtualSize : ULONG;
VirtualSize : ULONG;
PageFaultCount : ULONG;
PeakWorkingSetSize : ULONG;
WorkingSetSize : ULONG;
QuotaPeakPagedPoolUsage : ULONG;
QuotaPagedPoolUsage : ULONG;
QuotaPeakNonPagedPoolUsage : ULONG;
QuotaNonPagedPoolUsage : ULONG;
PageFileUsage : ULONG;
PeakPageFileUsage : ULONG;
PrivatePageCount : ULONG;
ReadOperationCount : LARGE_INTEGER;
WriteOperationCount : LARGE_INTEGER;
OtherOperationCount : LARGE_INTEGER;
ReadTransferCount : LARGE_INTEGER;
WriteTransferCount : LARGE_INTEGER;
OtherTransferCount : LARGE_INTEGER;
ThreadInfo: array [0..0] of SYSTEM_THREADS;
end;
function NtQuerySystemInformation(
SystemInformationClass: DWORD;
SystemInformation : Pointer;
SystemInformationLength : DWORD;
var ReturnLength: DWORD
): DWORD; stdcall; external 'ntdll.dll';
const
SystemProcessesAndThreadsInformation = 5;
STATUS_INFO_LENGTH_MISMATCH = $C0000004;
var
SystemInformation, Temp: PSYSTEM_PROCESS_INFORMATION;
ReturnLength: DWORD;
I: Integer;
begin
ReturnLength := SizeOf(SYSTEM_THREADS);
if NtQuerySystemInformation(
SystemProcessesAndThreadsInformation,
nil, 0, ReturnLength) <> STATUS_INFO_LENGTH_MISMATCH then Exit;
if ReturnLength > 0 then
begin
GetMem(SystemInformation, ReturnLength);
try
if NtQuerySystemInformation(SystemProcessesAndThreadsInformation,
SystemInformation, ReturnLength, ReturnLength) = 0 then
begin
Temp := SystemInformation;
repeat
if Temp^.ModuleName = nil then
writeln('System Idle Process, PID = 0')
else
writeln(String(Temp^.ModuleName), ', PID = ', Temp^.ProcessID);
writeln('TheadIDs | StartAddr');
writeln('=========|==========');
for I := 0 to Temp^.ThreadCount - 1 do
writeln(IntToHex(Temp^.ThreadInfo[I].UniqueThread, 8), ' | ',
IntToHex(Integer(Temp^.ThreadInfo[I].StartAddress), 8));
writeln;
writeln;
Temp := Pointer(DWORD(Temp) + Temp^.NextOffset);
until Temp^.NextOffset = 0;
end;
finally
FreeMem(SystemInformation);
end;
end;
readln;
end.
-
Благодарю!
-
Почему при получении списка процессов через native api (NtQuerySystemInformation(); ZwQuerySystemInformation() ) не отображается последний запущенный процесс. Т.е. Temp^.NextOffset = 0, список запонен, а последнего поцесса в нем нет. Читал на каком-то форуме, что это баг и его легко обойти. Но я не могу догнать как Подскажите, умные головы ))
-
Просто в этом примере не выводится самый последний. Т.е. когда Temp^.NextOffset = 0 это означает что сейчас получена самая последняя запись и ее тоже нужно вывести на экран, но происходит выход по условию. Перепиши вот так: Temp := SystemInformation;
while True do
begin
if Temp^.ModuleName = nil then
writeln('System Idle Process, PID = 0')
else
writeln(String(Temp^.ModuleName), ', PID = ', Temp^.ProcessID);
writeln('TheadIDs | StartAddr');
writeln('=========|==========');
for I := 0 to Temp^.ThreadCount - 1 do
writeln(IntToHex(Temp^.ThreadInfo[I].UniqueThread, 8), ' | ',
IntToHex(Integer(Temp^.ThreadInfo[I].StartAddress), 8));
writeln;
writeln;
if Temp^.NextOffset = 0 then Break;
Temp := Pointer(DWORD(Temp) + Temp^.NextOffset);
end;
-
> Почему при получении списка процессов через native api > (NtQuerySystemInformation(); ZwQuerySystemInformation() > ) не отображается последний запущенный процесс.
отображается
-
Rouse_ Спасибо, все получилось ))
|